/*******************************************************************************
 * Copyright (c) 2000, 2021 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Chris.Dennis@invidi.com - http://bugs.eclipse.org/bugs/show_bug.cgi?id=29027
 *     Michel Ishizuka (cqw10305@nifty.com) - http://bugs.eclipse.org/bugs/show_bug.cgi?id=68963
 *     Genady Beryozkin, me@genady.org - https://bugs.eclipse.org/bugs/show_bug.cgi?id=11668
 *     Benjamin Muskalla <b.muskalla@gmx.net> - https://bugs.eclipse.org/bugs/show_bug.cgi?id=41573
 *     Stephan Wahlbrink <stephan.wahlbrink@walware.de> - Wrong operations mode/feedback for text drag over/drop in text editors - https://bugs.eclipse.org/bugs/show_bug.cgi?id=206043
 *     Tom Eicher (Avaloq Evolution AG) - block selection mode
 *     Nick Sandonato <nsandona@us.ibm.com> - [implementation] AbstractTextEditor does not prompt when out of sync in MultiPageEditorPart - http://bugs.eclipse.org/337719
 *     Holger Voormann - Word Wrap - https://bugs.eclipse.org/bugs/show_bug.cgi?id=35779
 *     Florian Weßling <flo@cdhq.de> - Word Wrap - https://bugs.eclipse.org/bugs/show_bug.cgi?id=35779
 *     Andrey Loskutov <loskutov@gmx.de> - Word Wrap - https://bugs.eclipse.org/bugs/show_bug.cgi?id=35779
 *     Angelo Zerr <angelo.zerr@gmail.com> - [CodeMining] Provide extension point for CodeMining - Bug 528419
 *******************************************************************************/
package org.eclipse.ui.texteditor;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.IntStream;
import java.util.stream.Stream;

import org.osgi.framework.Bundle;

import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.custom.ST;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.custom.VerifyKeyListener;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.DragSource;
import org.eclipse.swt.dnd.DragSourceAdapter;
import org.eclipse.swt.dnd.DragSourceEvent;
import org.eclipse.swt.dnd.DropTargetAdapter;
import org.eclipse.swt.dnd.DropTargetEvent;
import org.eclipse.swt.dnd.DropTargetListener;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.events.GestureEvent;
import org.eclipse.swt.events.GestureListener;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.VerifyEvent;
import org.eclipse.swt.events.VerifyListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.PaletteData;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.widgets.Caret;
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.Menu;
import org.eclipse.swt.widgets.Shell;

import org.eclipse.core.commands.operations.IOperationApprover;
import org.eclipse.core.commands.operations.IOperationHistory;
import org.eclipse.core.commands.operations.IUndoContext;
import org.eclipse.core.commands.operations.OperationHistoryFactory;

import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.ILog;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.SafeRunner;
import org.eclipse.core.runtime.Status;

import org.eclipse.text.undo.DocumentUndoManagerRegistry;
import org.eclipse.text.undo.IDocumentUndoManager;

import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.GroupMarker;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IStatusLineManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.preference.PreferenceConverter;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.util.SafeRunnable;
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.StructuredSelection;

import org.eclipse.jface.text.AbstractInformationControlManager;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.BlockTextSelection;
import org.eclipse.jface.text.DefaultLineTracker;
import org.eclipse.jface.text.DocumentEvent;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IDocumentListener;
import org.eclipse.jface.text.IFindReplaceTarget;
import org.eclipse.jface.text.IFindReplaceTargetExtension;
import org.eclipse.jface.text.IInformationControlCreator;
import org.eclipse.jface.text.IMarkRegionTarget;
import org.eclipse.jface.text.IMultiTextSelection;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.IRewriteTarget;
import org.eclipse.jface.text.ISelectionValidator;
import org.eclipse.jface.text.ITextHover;
import org.eclipse.jface.text.ITextInputListener;
import org.eclipse.jface.text.ITextListener;
import org.eclipse.jface.text.ITextOperationTarget;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.ITextViewerExtension;
import org.eclipse.jface.text.ITextViewerExtension2;
import org.eclipse.jface.text.ITextViewerExtension4;
import org.eclipse.jface.text.ITextViewerExtension5;
import org.eclipse.jface.text.ITextViewerExtension6;
import org.eclipse.jface.text.ITextViewerExtension7;
import org.eclipse.jface.text.ITextViewerExtension8;
import org.eclipse.jface.text.ITextViewerExtension8.EnrichMode;
import org.eclipse.jface.text.IUndoManager;
import org.eclipse.jface.text.IUndoManagerExtension;
import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.Region;
import org.eclipse.jface.text.TabsToSpacesConverter;
import org.eclipse.jface.text.TextEvent;
import org.eclipse.jface.text.TextSelection;
import org.eclipse.jface.text.TextUtilities;
import org.eclipse.jface.text.codemining.ICodeMiningProvider;
import org.eclipse.jface.text.hyperlink.HyperlinkManager;
import org.eclipse.jface.text.hyperlink.IHyperlinkDetector;
import org.eclipse.jface.text.information.IInformationProvider;
import org.eclipse.jface.text.information.IInformationProviderExtension2;
import org.eclipse.jface.text.link.LinkedModeModel;
import org.eclipse.jface.text.link.LinkedPosition;
import org.eclipse.jface.text.quickassist.IQuickAssistAssistant;
import org.eclipse.jface.text.revisions.RevisionInformation;
import org.eclipse.jface.text.source.Annotation;
import org.eclipse.jface.text.source.CompositeRuler;
import org.eclipse.jface.text.source.IAnnotationHover;
import org.eclipse.jface.text.source.IAnnotationModel;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.jface.text.source.ISourceViewerExtension3;
import org.eclipse.jface.text.source.ISourceViewerExtension4;
import org.eclipse.jface.text.source.ISourceViewerExtension5;
import org.eclipse.jface.text.source.IVerticalRuler;
import org.eclipse.jface.text.source.IVerticalRulerColumn;
import org.eclipse.jface.text.source.IVerticalRulerExtension;
import org.eclipse.jface.text.source.IVerticalRulerInfo;
import org.eclipse.jface.text.source.SourceViewer;
import org.eclipse.jface.text.source.SourceViewerConfiguration;
import org.eclipse.jface.text.source.VerticalRuler;

import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IEditorDescriptor;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorRegistry;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.IKeyBindingService;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.INavigationLocation;
import org.eclipse.ui.INavigationLocationProvider;
import org.eclipse.ui.IPartListener;
import org.eclipse.ui.IPartService;
import org.eclipse.ui.IPersistableEditor;
import org.eclipse.ui.IReusableEditor;
import org.eclipse.ui.ISaveablesLifecycleListener;
import org.eclipse.ui.ISaveablesSource;
import org.eclipse.ui.IWindowListener;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.IWorkbenchCommandConstants;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchPartSite;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.Saveable;
import org.eclipse.ui.SaveablesLifecycleEvent;
import org.eclipse.ui.actions.ActionFactory;
import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction;
import org.eclipse.ui.actions.CommandNotMappedException;
import org.eclipse.ui.actions.ContributedAction;
import org.eclipse.ui.commands.ICommandImageService;
import org.eclipse.ui.dialogs.PropertyDialogAction;
import org.eclipse.ui.dnd.IDragAndDropService;
import org.eclipse.ui.internal.texteditor.EditPosition;
import org.eclipse.ui.internal.texteditor.FocusedInformationPresenter;
import org.eclipse.ui.internal.texteditor.HistoryTracker;
import org.eclipse.ui.internal.texteditor.NLSUtility;
import org.eclipse.ui.internal.texteditor.TextEditorPlugin;
import org.eclipse.ui.internal.texteditor.rulers.StringSetSerializer;
import org.eclipse.ui.operations.LinearUndoViolationUserApprover;
import org.eclipse.ui.operations.NonLocalUndoUserApprover;
import org.eclipse.ui.operations.OperationHistoryActionHandler;
import org.eclipse.ui.operations.RedoActionHandler;
import org.eclipse.ui.operations.UndoActionHandler;
import org.eclipse.ui.part.EditorPart;
import org.eclipse.ui.part.MultiPageEditorSite;

import org.eclipse.ui.texteditor.rulers.IColumnSupport;
import org.eclipse.ui.texteditor.rulers.IContributedRulerColumn;
import org.eclipse.ui.texteditor.rulers.RulerColumnDescriptor;
import org.eclipse.ui.texteditor.rulers.RulerColumnPreferenceAdapter;
import org.eclipse.ui.texteditor.rulers.RulerColumnRegistry;


/**
 * Abstract base implementation of a text editor.
 * <p>
 * Subclasses are responsible for configuring the editor appropriately. The standard text editor,
 * <code>TextEditor</code>, is one such example.
 * </p>
 * <p>
 * If a subclass calls {@linkplain #setEditorContextMenuId(String) setEditorContextMenuId} the
 * argument is used as the id under which the editor's context menu is registered for extensions. If
 * no id is set, the context menu is registered under <b>[editor_id].EditorContext</b> whereby
 * [editor_id] is replaced with the editor's part id. If the editor is instructed to run in version
 * 1.0 context menu registration compatibility mode, the latter form of the registration even
 * happens if a context menu id has been set via {@linkplain #setEditorContextMenuId(String)
 * setEditorContextMenuId}. If no id is set while in compatibility mode, the menu is registered
 * under {@link #DEFAULT_EDITOR_CONTEXT_MENU_ID}.
 * </p>
 * <p>
 * If a subclass calls {@linkplain #setRulerContextMenuId(String) setRulerContextMenuId} the
 * argument is used as the id under which the ruler's context menu is registered for extensions. If
 * no id is set, the context menu is registered under <b>[editor_id].RulerContext</b> whereby
 * [editor_id] is replaced with the editor's part id. If the editor is instructed to run in version
 * 1.0 context menu registration compatibility mode, the latter form of the registration even
 * happens if a context menu id has been set via {@linkplain #setRulerContextMenuId(String)
 * setRulerContextMenuId}. If no id is set while in compatibility mode, the menu is registered under
 * {@link #DEFAULT_RULER_CONTEXT_MENU_ID}.
 * </p>
 * <p>
 * As of 3.5, contributers can contribute editor and ruler context menu actions to all subclasses of
 * this class by using {@link #COMMON_EDITOR_CONTEXT_MENU_ID} and
 * {@link #COMMON_RULER_CONTEXT_MENU_ID}.
 * </p>
 */
public abstract class AbstractTextEditor extends EditorPart implements ITextEditor, IReusableEditor, ITextEditorExtension, ITextEditorExtension2, ITextEditorExtension3, ITextEditorExtension4, ITextEditorExtension5, ITextEditorExtension6, INavigationLocationProvider, ISaveablesSource, IPersistableEditor {

	/**
	 * Tag used in xml configuration files to specify editor action contributions.
	 * Current value: <code>editorContribution</code>
	 * @since 2.0
	 */
	private static final String TAG_CONTRIBUTION_TYPE= "editorContribution"; //$NON-NLS-1$

	/**
	 * Tag used in the {@link IMemento} when saving and restoring the editor's selection offset.
	 *
	 * @see #saveState(IMemento)
	 * @see #restoreState(IMemento)
	 * @see #doRestoreState(IMemento)
	 * @since 3.3
	 */
	protected static final String TAG_SELECTION_OFFSET= "selectionOffset"; //$NON-NLS-1$

	/**
	 * Tag used in the {@link IMemento} when saving and restoring the editor's selection length.
	 *
	 * @see #saveState(IMemento)
	 * @see #restoreState(IMemento)
	 * @see #doRestoreState(IMemento)
	 * @since 3.3
	 */
	protected static final String TAG_SELECTION_LENGTH= "selectionLength"; //$NON-NLS-1$

	/**
	 * Tag used in the {@link IMemento} when saving and restoring the editor's top pixel value.
	 *
	 * @see #saveState(IMemento)
	 * @see #restoreState(IMemento)
	 * @see #doRestoreState(IMemento)
	 * @since 3.6
	 */
	protected static final String TAG_SELECTION_TOP_PIXEL= "selectionTopPixel"; //$NON-NLS-1$

	/**
	 * Tag used in the {@link IMemento} when saving and restoring the editor's horizontal pixel
	 * value.
	 *
	 * @see #saveState(IMemento)
	 * @see #restoreState(IMemento)
	 * @see #doRestoreState(IMemento)
	 * @since 3.6
	 */
	protected static final String TAG_SELECTION_HORIZONTAL_PIXEL= "selectionHorizontalPixel"; //$NON-NLS-1$


	/**
	 * The caret width for the wide (double) caret.
	 * See https://bugs.eclipse.org/bugs/show_bug.cgi?id=21715.
	 * Value: {@value}
	 * @since 3.0
	 */
	private static final int WIDE_CARET_WIDTH= 2;

	/**
	 * The caret width for the narrow (single) caret.
	 * See https://bugs.eclipse.org/bugs/show_bug.cgi?id=21715.
	 * Value: {@value}
	 * @since 3.0
	 */
	private static final int SINGLE_CARET_WIDTH= 1;

	/**
	 * The symbolic name of the block selection mode font.
	 *
	 * @since 3.5
	 */
	private static final String BLOCK_SELECTION_MODE_FONT= "org.eclipse.ui.workbench.texteditor.blockSelectionModeFont"; //$NON-NLS-1$

	/**
	 * The text input listener.
	 *
	 * @see ITextInputListener
	 * @since 2.1
	 */
	private static class TextInputListener implements ITextInputListener {
		/** Indicates whether the editor input changed during the process of state validation. */
		public boolean inputChanged;

		/* Detectors for editor input changes during the process of state validation. */
		@Override
		public void inputDocumentAboutToBeChanged(IDocument oldInput, IDocument newInput) {}
		@Override
		public void inputDocumentChanged(IDocument oldInput, IDocument newInput) { inputChanged= true; }
	}

	/**
	 * Internal element state listener.
	 */
	class ElementStateListener implements IElementStateListener, IElementStateListenerExtension {

			/**
			 * Internal <code>VerifyListener</code> for performing the state validation of the
			 * editor input in case of the first attempted manipulation via typing on the keyboard.
			 * @since 2.0
			 */
			class Validator implements VerifyListener {
				@Override
				public void verifyText(VerifyEvent e) {
					IDocument document= getDocumentProvider().getDocument(getEditorInput());
					final boolean[] documentChanged= new boolean[1];
					IDocumentListener listener= new IDocumentListener() {
						@Override
						public void documentAboutToBeChanged(DocumentEvent event) {
						}
						@Override
						public void documentChanged(DocumentEvent event) {
							documentChanged[0]= true;
						}
					};
					try {
						if (document != null)
							document.addDocumentListener(listener);
						if (! validateEditorInputState() || documentChanged[0])
							e.doit= false;
					} finally {
						if (document != null)
							document.removeDocumentListener(listener);
					}
				}
			}

		/**
		 * The listener's validator.
		 * @since 2.0
		 */
		private Validator fValidator;
		/**
		 * The display used for posting runnable into the UI thread.
		 * @since 3.0
		 */
		private Display fDisplay;

		@Override
		public void elementStateValidationChanged(final Object element, final boolean isStateValidated) {
			if (element != null && element.equals(getEditorInput())) {
				Runnable r = () -> {
					enableSanityChecking(true);
					if (isStateValidated) {
						if (fValidator != null) {
							ISourceViewer viewer1 = fSourceViewer;
							if (viewer1 != null) {
								StyledText textWidget1 = viewer1.getTextWidget();
								if (textWidget1 != null && !textWidget1.isDisposed())
									textWidget1.removeVerifyListener(fValidator);
								fValidator = null;
							}
						}
						enableStateValidation(false);
					} else if (!isStateValidated && fValidator == null) {
						ISourceViewer viewer2 = fSourceViewer;
						if (viewer2 != null) {
							StyledText textWidget2 = viewer2.getTextWidget();
							if (textWidget2 != null && !textWidget2.isDisposed()) {
								fValidator = new Validator();
								enableStateValidation(true);
								textWidget2.addVerifyListener(fValidator);
							}
						}
					}
				};
				execute(r, false);
			}
		}


		@Override
		public void elementDirtyStateChanged(Object element, boolean isDirty) {
			if (element != null && element.equals(getEditorInput())) {
				Runnable r = () -> {
					enableSanityChecking(true);
					firePropertyChange(PROP_DIRTY);
				};
				execute(r, false);
			}
		}

		@Override
		public void elementContentAboutToBeReplaced(Object element) {
			if (element != null && element.equals(getEditorInput())) {
				Runnable r = () -> {
					enableSanityChecking(true);
					rememberSelection();
					resetHighlightRange();
				};
				execute(r, false);
			}
		}

		@Override
		public void elementContentReplaced(Object element) {
			if (element != null && element.equals(getEditorInput())) {
				Runnable r = () -> {
					enableSanityChecking(true);
					firePropertyChange(PROP_DIRTY);
					restoreSelection();
					handleElementContentReplaced();
				};
				execute(r, false);
			}
		}

		@Override
		public void elementDeleted(Object deletedElement) {
			if (deletedElement != null && deletedElement.equals(getEditorInput())) {
				Runnable r = () -> {
					enableSanityChecking(true);
					close(false);
				};
				execute(r, false);
			}
		}

		@Override
		public void elementMoved(final Object originalElement, final Object movedElement) {
			if (originalElement != null && originalElement.equals(getEditorInput())) {
				final boolean doValidationAsync= Display.getCurrent() != null;
				Runnable r= new Runnable() {
					@Override
					public void run() {
						enableSanityChecking(true);

						if (fSourceViewer == null)
							return;

						if (!canHandleMove((IEditorInput) originalElement, (IEditorInput) movedElement)) {
							close(true);
							return;
						}

						if (movedElement == null || movedElement instanceof IEditorInput) {
							rememberSelection();

							final IDocumentProvider d= getDocumentProvider();
							final String previousContent;
							IDocumentUndoManager previousUndoManager=null;
							IDocument changed= null;
							boolean wasDirty= isDirty();
							changed= d.getDocument(getEditorInput());
							if (changed != null) {
								if (wasDirty)
									previousContent= changed.get();
								else
									previousContent= null;

								previousUndoManager= DocumentUndoManagerRegistry.getDocumentUndoManager(changed);
								if (previousUndoManager != null)
									previousUndoManager.connect(this);
							}
							else
								previousContent= null;

							setInput((IEditorInput) movedElement);

							// The undo manager needs to be replaced with one for the new document.
							// Transfer the undo history and then disconnect from the old undo manager.
							if (previousUndoManager != null) {
								IDocument newDocument= getDocumentProvider().getDocument(movedElement);
								if (newDocument != null) {
									IDocumentUndoManager newUndoManager= DocumentUndoManagerRegistry.getDocumentUndoManager(newDocument);
									if (newUndoManager != null)
										newUndoManager.transferUndoHistory(previousUndoManager);
								}
								previousUndoManager.disconnect(this);
							}

							if (wasDirty && changed != null) {
								Runnable r2 = () -> {
									validateState(getEditorInput());
									d.getDocument(getEditorInput()).set(previousContent);
									updateStatusField(ITextEditorActionConstants.STATUS_CATEGORY_ELEMENT_STATE);
									restoreSelection();
								};
								execute(r2, doValidationAsync);
							} else
								restoreSelection();

						}
					}
				};
				execute(r, false);
			}
		}

		@Override
		public void elementStateChanging(Object element) {
			if (element != null && element.equals(getEditorInput()))
				enableSanityChecking(false);
		}

		@Override
		public void elementStateChangeFailed(Object element) {
			if (element != null && element.equals(getEditorInput()))
				enableSanityChecking(true);
		}

		/**
		 * Executes the given runnable in the UI thread.
		 * <p>
		 * See https://bugs.eclipse.org/bugs/show_bug.cgi?id=76765 for details
		 * about why the parameter <code>postAsync</code> has been
		 * introduced in the course of 3.1.
		 *
		 * @param runnable runnable to be executed
		 * @param postAsync <code>true</code> if the runnable must be posted asynchronous, <code>false</code> otherwise
		 * @since 3.0
		 */
		private void execute(Runnable runnable, boolean postAsync) {
			if (postAsync || Display.getCurrent() == null) {
				if (fDisplay == null)
					fDisplay= getSite().getShell().getDisplay();
				fDisplay.asyncExec(runnable);
			} else
				runnable.run();
		}
	}

	/**
	 * Internal text listener for updating all content dependent
	 * actions. The updating is done asynchronously.
	 */
	class TextListener implements ITextListener, ITextInputListener {

		/**
		 * Should the last edit position be updated?
		 *
		 * @since 3.0
		 */
		private boolean fUpdateLastEditPosition = false;

		/**
		 * The editor's last edit position
		 *
		 * @since 3.0
		 */

		/** The posted updater code. */
		private Runnable fRunnable = () -> {
			fIsRunnablePosted = false;

			if (fSourceViewer != null) {
				updateContentDependentActions();

				// remember the last edit position
				if (isDirty() && fUpdateLastEditPosition) {
					HistoryTracker<EditPosition> positionHistory = TextEditorPlugin.getDefault()
							.getEditPositionHistory();
					fUpdateLastEditPosition = false;
					ISelection sel = getSelectionProvider().getSelection();
					IEditorInput input = getEditorInput();
					IDocument document = getDocumentProvider().getDocument(input);
					IEditorSite editorSite = getEditorSite();
					if (editorSite instanceof MultiPageEditorSite)
						editorSite = ((MultiPageEditorSite) editorSite).getMultiPageEditor().getEditorSite();

					if (sel instanceof ITextSelection && !sel.isEmpty()) {
						ITextSelection s = (ITextSelection) sel;
						Position newPosition = new Position(s.getOffset(), s.getLength());
						EditPosition newEditPosition = new EditPosition(input, editorSite.getId(), newPosition);
						EditPosition replaced = positionHistory.addOrReplace(newEditPosition);
						if (document != null) {
							if (replaced != null) {
								document.removePosition(replaced.getPosition());
							}
							try {
								if (positionHistory.getSize() > 0) {
									document.addPosition(positionHistory.getCurrentBrowsePoint().getPosition());
								}
							} catch (BadLocationException ex) {
								positionHistory.deleteLast();
							}
						}
					}

					TextEditorPlugin.getDefault().enableLastEditPositionDependentActions();
				}
			}
		};

		/** Display used for posting the updater code. */
		private Display fDisplay;

		/**
		 * Has the runnable been posted?
		 * @since 3.0
		 */
		private boolean fIsRunnablePosted= false;

		@Override
		public void textChanged(TextEvent event) {

			/*
			 * Also works for text events which do not base on a DocumentEvent.
			 * This way, if the visible document of the viewer changes, all content
			 * dependent actions are updated as well.
			 */

			if (fDisplay == null)
				fDisplay= getSite().getShell().getDisplay();

			if (event.getDocumentEvent() != null)
				fUpdateLastEditPosition= true;

			if (!fIsRunnablePosted) {
				fIsRunnablePosted= true;
				fDisplay.asyncExec(fRunnable);
			}
		}

		@Override
		public void inputDocumentAboutToBeChanged(IDocument oldInput, IDocument newInput) {
			discardHistoryFor(oldInput, newInput);
		}

		@Override
		public void inputDocumentChanged(IDocument oldInput, IDocument newInput) {
			discardHistoryFor(oldInput, newInput);
		}

		private void discardHistoryFor(IDocument oldInput, IDocument newInput) {
			// Only discard history from document if it is replaced by other real document,
			// don't care otherwise
			if (oldInput == null || newInput == null) {
				return;
			}
			HistoryTracker<EditPosition> positionHistory = TextEditorPlugin.getDefault().getEditPositionHistory();
			if (!positionHistory.isEmpty()) {
				Stream<EditPosition> rawHistory = positionHistory.rawHistory();
				rawHistory.forEach(p -> oldInput.removePosition(p.getPosition()));
			}
		}
	}

	/**
	 * Internal property change listener for handling changes in the editor's preferences.
	 */
	class PropertyChangeListener implements IPropertyChangeListener {
		@Override
		public void propertyChange(PropertyChangeEvent event) {
			handlePreferenceStoreChanged(event);
		}
	}

	/**
	 * Internal property change listener for handling workbench font changes.
	 * @since 2.1
	 */
	class FontPropertyChangeListener implements IPropertyChangeListener {
		@Override
		public void propertyChange(PropertyChangeEvent event) {
			if (fSourceViewer == null)
				return;

			String property= event.getProperty();

			// IMPORTANT: Do not call isBlockSelectionModeEnabled() before checking the property!

			if (BLOCK_SELECTION_MODE_FONT.equals(property) && isBlockSelectionModeEnabled()) {
				Font blockFont= JFaceResources.getFont(BLOCK_SELECTION_MODE_FONT);
				setFont(fSourceViewer, blockFont);
				disposeFont();
				updateCaret();
				return;
			}
			if (getFontPropertyPreferenceKey().equals(property) && !isBlockSelectionModeEnabled()) {
				initializeViewerFont(fSourceViewer);
				updateCaret();
				return;
			}
		}
	}

	/**
	 * Internal key verify listener for triggering action activation codes.
	 */
	class ActivationCodeTrigger implements VerifyKeyListener {

		/** Indicates whether this trigger has been installed. */
		private boolean fIsInstalled= false;
		/**
		 * The key binding service to use.
		 * @since 2.0
		 */
		private IKeyBindingService fKeyBindingService;

		@Override
		public void verifyKey(VerifyEvent event) {

			ActionActivationCode code= null;
			int size= fActivationCodes.size();
			for (int i= 0; i < size; i++) {
				code= fActivationCodes.get(i);
				if (code.matches(event)) {
					IAction action= getAction(code.fActionId);
					if (action != null) {

						if (action instanceof IUpdate)
							((IUpdate) action).update();

						if (!action.isEnabled() && action instanceof IReadOnlyDependent) {
							IReadOnlyDependent dependent= (IReadOnlyDependent) action;
							boolean writable= dependent.isEnabled(true);
							if (writable) {
								event.doit= false;
								return;
							}
						} else if (action.isEnabled()) {
							event.doit= false;
							action.run();
							return;
						}
					}
				}
			}
		}

		/**
		 * Installs this trigger on the editor's text widget.
		 * @since 2.0
		 */
		public void install() {
			if (!fIsInstalled) {

				if (fSourceViewer instanceof ITextViewerExtension) {
					ITextViewerExtension e= (ITextViewerExtension) fSourceViewer;
					e.prependVerifyKeyListener(this);
				} else {
					StyledText text= fSourceViewer.getTextWidget();
					text.addVerifyKeyListener(this);
				}

				fKeyBindingService= getEditorSite().getKeyBindingService();
				fIsInstalled= true;
			}
		}

		/**
		 * Uninstalls this trigger from the editor's text widget.
		 * @since 2.0
		 */
		public void uninstall() {
			if (fIsInstalled) {

				if (fSourceViewer instanceof ITextViewerExtension) {
					ITextViewerExtension e= (ITextViewerExtension) fSourceViewer;
					e.removeVerifyKeyListener(this);
				} else if (fSourceViewer != null) {
					StyledText text= fSourceViewer.getTextWidget();
					if (text != null && !text.isDisposed())
						text.removeVerifyKeyListener(fActivationCodeTrigger);
				}

				fIsInstalled= false;
				fKeyBindingService= null;
			}
		}

		/**
		 * Registers the given action for key activation.
		 * @param action the action to be registered
		 * @since 2.0
		 */
		public void registerActionForKeyActivation(IAction action) {
			if (fIsInstalled && action.getActionDefinitionId() != null)
				fKeyBindingService.registerAction(action);
		}

		/**
		 * The given action is no longer available for key activation
		 * @param action the action to be unregistered
		 * @since 2.0
		 */
		public void unregisterActionFromKeyActivation(IAction action) {
			if (fIsInstalled && action.getActionDefinitionId() != null)
				fKeyBindingService.unregisterAction(action);
		}

		/**
		 * Sets the key binding scopes for this editor.
		 * @param keyBindingScopes the key binding scopes
		 * @since 2.1
		 */
		public void setScopes(String[] keyBindingScopes) {
			if (keyBindingScopes != null && keyBindingScopes.length > 0)
				fKeyBindingService.setScopes(keyBindingScopes);
		}
	}

	/**
	 * Representation of action activation codes.
	 */
	static class ActionActivationCode {

		/** The action id. */
		public String fActionId;
		/** The character. */
		public char fCharacter;
		/** The key code. */
		public int fKeyCode= -1;
		/** The state mask. */
		public int fStateMask= SWT.DEFAULT;

		/**
		 * Creates a new action activation code for the given action id.
		 * @param actionId the action id
		 */
		public ActionActivationCode(String actionId) {
			fActionId= actionId;
		}

		/**
		 * Returns <code>true</code> if this activation code matches the given verify event.
		 * @param event the event to test for matching
		 * @return whether this activation code matches <code>event</code>
		 */
		public boolean matches(VerifyEvent event) {
			return (event.character == fCharacter &&
						(fKeyCode == -1 || event.keyCode == fKeyCode) &&
						(fStateMask == SWT.DEFAULT || event.stateMask == fStateMask));
		}
	}

	/**
	 * Internal part and shell activation listener for triggering state validation.
	 * @since 2.0
	 */
	class ActivationListener implements IPartListener, IWindowListener {

		/** Cache of the active workbench part. */
		private IWorkbenchPart fActivePart;
		/**
		 * The part service.
		 * @since 3.1
		 */
		private IPartService fPartService;

		/**
		 * Creates this activation listener.
		 *
		 * @param partService the part service on which to add the part listener
		 * @since 3.1
		 */
		public ActivationListener(IPartService partService) {
			fPartService= partService;
			fPartService.addPartListener(this);
			PlatformUI.getWorkbench().addWindowListener(this);
		}

		/**
		 * Disposes this activation listener.
		 *
		 * @since 3.1
		 */
		public void dispose() {
			fPartService.removePartListener(this);
			PlatformUI.getWorkbench().removeWindowListener(this);
			fPartService= null;
		}

		@Override
		public void partActivated(IWorkbenchPart part) {
			fActivePart= part;
			handleActivation();
		}

		@Override
		public void partBroughtToTop(IWorkbenchPart part) {
		}

		@Override
		public void partClosed(IWorkbenchPart part) {
		}

		@Override
		public void partDeactivated(IWorkbenchPart part) {
			fActivePart= null;
		}

		@Override
		public void partOpened(IWorkbenchPart part) {
			// Restore the saved state if any
			if ((part == AbstractTextEditor.this || part.getAdapter(AbstractTextEditor.class) == AbstractTextEditor.this) && fMementoToRestore != null && containsSavedState(fMementoToRestore)) {
				doRestoreState(fMementoToRestore);
				fMementoToRestore= null;
			}
		}

		/**
		 * Handles the activation triggering a element state check in the editor.
		 */
		private void handleActivation() {
			if (!fHandleActivation)
				return;

			if (fActivePart == AbstractTextEditor.this || fActivePart != null && fActivePart.getAdapter(AbstractTextEditor.class) == AbstractTextEditor.this) {
				fHandleActivation= false;
				try {
					safelySanityCheckState(getEditorInput());
				} finally {
					fHandleActivation= true;
					fHasBeenActivated= true;
				}
			}
		}

		@Override
		public void windowActivated(IWorkbenchWindow window) {
			if (fHandleActivation && window == getEditorSite().getWorkbenchWindow()) {
				/*
				 * Workaround for problem described in
				 * http://dev.eclipse.org/bugs/show_bug.cgi?id=11731
				 * Will be removed when SWT has solved the problem.
				 */
				window.getShell().getDisplay().asyncExec(this::handleActivation);
			}
		}

		@Override
		public void windowDeactivated(IWorkbenchWindow window) {
		}

		@Override
		public void windowClosed(IWorkbenchWindow window) {
		}

		@Override
		public void windowOpened(IWorkbenchWindow window) {
		}
	}

	/**
	 * Internal interface for a cursor listener. I.e. aggregation
	 * of mouse and key listener.
	 * @since 2.0
	 */
	interface ICursorListener extends MouseListener, KeyListener {
	}

	/**
	 * Maps an action definition id to an StyledText action.
	 * @since 2.0
	 */
	protected static final class IdMapEntry {

		/** The action id. */
		private String fActionId;
		/** The StyledText action. */
		private int fAction;

		/**
		 * Creates a new mapping.
		 * @param actionId the action id
		 * @param action the StyledText action
		 */
		public IdMapEntry(String actionId, int action) {
			fActionId= actionId;
			fAction= action;
		}

		/**
		 * Returns the action id.
		 * @return the action id
		 */
		public String getActionId() {
			return fActionId;
		}

		/**
		 * Returns the action.
		 * @return the action
		 */
		public int getAction() {
			return fAction;
		}
	}

	/**
	 * Internal action to scroll the editor's viewer by a specified number of lines.
	 * @since 2.0
	 */
	class ScrollLinesAction extends Action {

		/** Number of lines to scroll. */
		private int fScrollIncrement;

		/**
		 * Creates a new scroll action that scroll the given number of lines. If the
		 * increment is &lt; 0, it's scrolling up, if &gt; 0 it's scrolling down.
		 * @param scrollIncrement the number of lines to scroll
		 */
		public ScrollLinesAction(int scrollIncrement) {
			fScrollIncrement= scrollIncrement;
		}

		@Override
		public void run() {
			if (fSourceViewer instanceof ITextViewerExtension5) {
				ITextViewerExtension5 extension= (ITextViewerExtension5) fSourceViewer;
				StyledText textWidget= fSourceViewer.getTextWidget();
				int topIndex= textWidget.getTopIndex();
				int newTopIndex= Math.max(0, topIndex + fScrollIncrement);
				fSourceViewer.setTopIndex(extension.widgetLine2ModelLine(newTopIndex));
			} else {
				int topIndex= fSourceViewer.getTopIndex();
				int newTopIndex= Math.max(0, topIndex + fScrollIncrement);
				fSourceViewer.setTopIndex(newTopIndex);
			}
		}
	}

	/**
	 * Action to toggle the insert mode. The action is checked if smart mode is
	 * turned on.
	 *
	 * @since 2.1
	 */
	class ToggleInsertModeAction extends ResourceAction {

		public ToggleInsertModeAction(ResourceBundle bundle, String prefix) {
			super(bundle, prefix, IAction.AS_CHECK_BOX);
		}

		@Override
		public void run() {
			switchToNextInsertMode();
		}

		@Override
		public boolean isChecked() {
			return fInsertMode == SMART_INSERT;
		}
	}

	/**
	 * Action to toggle the overwrite mode.
	 *
	 * @since 3.0
	 */
	class ToggleOverwriteModeAction extends ResourceAction {

		public ToggleOverwriteModeAction(ResourceBundle bundle, String prefix) {
			super(bundle, prefix);
		}

		@Override
		public void run() {
			toggleOverwriteMode();
		}
	}

	/**
	 * This action implements smart end.
	 * Instead of going to the end of a line it does the following:
	 * - if smart home/end is enabled and the caret is before the line's last non-whitespace and then the caret is moved directly after it
	 * - if the caret is after last non-whitespace the caret is moved at the end of the line
	 * - if the caret is at the end of the line the caret is moved directly after the line's last non-whitespace character
	 * @since 2.1 (in 3.3 the access modifier changed from package visibility to protected)
	 */
	protected class LineEndAction extends TextNavigationAction {

		/** boolean flag which tells if the text up to the line end should be selected. */
		private boolean fDoSelect;

		/**
		 * Create a new line end action.
		 *
		 * @param textWidget the styled text widget
		 * @param doSelect a boolean flag which tells if the text up to the line end should be selected
		 */
		public LineEndAction(StyledText textWidget, boolean doSelect) {
			super(textWidget, ST.LINE_END);
			fDoSelect= doSelect;
		}

		/**
		 * Computes the offset of the line end position.
		 *
		 * @param document the document where to compute the line end position
		 * @param line the line to determine the end position of
		 * @param length the length of the line
		 * @param offset the caret position in the document
		 * @return the offset of the line end
		 * @since 3.4 protected, was added in 3.3 as private method
		 */
		protected int getLineEndPosition(final IDocument document, final String line, final int length, final int offset) {
			int index= length - 1;
			while (index > -1 && Character.isWhitespace(line.charAt(index)))
				index--;
			index++;

			LinkedModeModel model= LinkedModeModel.getModel(document, offset);
			if (model != null) {
				LinkedPosition linkedPosition= model.findPosition(new LinkedPosition(document, offset, 0));
				if (linkedPosition != null) {
					int linkedPositionEnd= linkedPosition.getOffset() + linkedPosition.getLength();
					int lineOffset;
					try {
						lineOffset= document.getLineInformationOfOffset(offset).getOffset();
						if (offset != linkedPositionEnd && linkedPositionEnd - lineOffset < index)
							index= linkedPositionEnd - lineOffset;
					} catch (BadLocationException e) {
						//should not happen
					}
				}
			}
			return index;
		}

		@Override
		public void run() {
			boolean isSmartHomeEndEnabled= false;
			IPreferenceStore store= getPreferenceStore();
			if (store != null)
				isSmartHomeEndEnabled= store.getBoolean(AbstractTextEditor.PREFERENCE_NAVIGATION_SMART_HOME_END);

			StyledText st= fSourceViewer.getTextWidget();
			if (st == null || st.isDisposed())
				return;
			boolean caretAtBeginningOfSelection = st.getCaretOffset() == st.getSelection().x;
			Point firstSelection = st.getSelection();
			int[] ranges = st.getSelectionRanges();
			List<Point> newSelection = new ArrayList<>(ranges.length / 2);
			for (int j = 0; j < ranges.length; j += 2) {
				int offset = ranges[j];
				int length = ranges[j + 1];
				int caretOffset = caretAtBeginningOfSelection ? offset : offset + length;
				int lineNumber = st.getLineAtOffset(caretOffset);
				int lineOffset = st.getOffsetAtLine(lineNumber);
				int lineLength;
				int caretOffsetInDocument;
				final IDocument document = fSourceViewer.getDocument();

				try {
					caretOffsetInDocument = widgetOffset2ModelOffset(fSourceViewer, caretOffset);
					lineLength = document.getLineInformationOfOffset(caretOffsetInDocument).getLength();
				} catch (BadLocationException ex) {
					return;
				}
				int lineEndOffset = lineOffset + lineLength;

				int delta = lineEndOffset - st.getCharCount();
				if (delta > 0) {
					lineEndOffset -= delta;
					lineLength -= delta;
				}
				String line = ""; //$NON-NLS-1$
				if (lineLength > 0)
					line = st.getText(lineOffset, lineEndOffset - 1);

				// Remember current selection
				Point oldSelection = new Point(offset, offset + length);

				// The new caret position
				int newCaretOffset = -1;

				if (isSmartHomeEndEnabled) {
					// Compute the line end offset
					int i = getLineEndPosition(document, line, lineLength, caretOffsetInDocument);
					newCaretOffset = (caretOffset - lineOffset == i) ? lineEndOffset : lineOffset + i;
				} else if (caretOffset < lineEndOffset) {
						// to end of line
						newCaretOffset = lineEndOffset;
				}

				if (newCaretOffset == -1) {
					newCaretOffset = caretOffset;
				}

				newSelection.add(new Point(
						fDoSelect ? (caretOffset < oldSelection.y ? oldSelection.y : oldSelection.x) : newCaretOffset,
						newCaretOffset));

			}
			st.setSelectionRanges(newSelection.stream().flatMapToInt(
					p -> IntStream.of(Math.min(p.y, p.x), Math.abs(p.y - p.x)))
					.toArray());
			if (newSelection.size() == 1) {
				st.showSelection();
			}
			fireSelectionChanged(firstSelection);
		}
	}

	/**
	 * This action implements smart home.
	 * Instead of going to the start of a line it does the following:
	 * - if smart home/end is enabled and the caret is after the line's first non-whitespace then the caret is moved directly before it
	 * - if the caret is before the line's first non-whitespace the caret is moved to the beginning of the line
	 * - if the caret is at the beginning of the line the caret is moved directly before the line's first non-whitespace character
	 * @since 2.1
	 */
	protected class LineStartAction extends TextNavigationAction {

		/** boolean flag which tells if the text up to the beginning of the line should be selected. */
		private final boolean fDoSelect;

		/**
		 * Creates a new line start action.
		 *
		 * @param textWidget the styled text widget
		 * @param doSelect a boolean flag which tells if the text up to the beginning of the line should be selected
		 */
		public LineStartAction(final StyledText textWidget, final boolean doSelect) {
			super(textWidget, ST.LINE_START);
			fDoSelect= doSelect;
		}

		/**
		 * Computes the offset of the line start position.
		 *
		 * @param document the document where to compute the line start position
		 * @param line the line to determine the start position of
		 * @param length the length of the line
		 * @param offset the caret position in the document
		 * @return the offset of the line start
		 * @since 3.0
		 */
		protected int getLineStartPosition(final IDocument document, final String line, final int length, final int offset) {
			int index= 0;
			while (index < length && Character.isWhitespace(line.charAt(index)))
				index++;

			LinkedModeModel model= LinkedModeModel.getModel(document, offset);
			if (model != null) {
				LinkedPosition linkedPosition= model.findPosition(new LinkedPosition(document, offset, 0));
				if (linkedPosition != null) {
					int linkedPositionOffset= linkedPosition.getOffset();
					int lineOffset;
					try {
						lineOffset= document.getLineInformationOfOffset(offset).getOffset();
						if (offset != linkedPositionOffset && index < linkedPositionOffset - lineOffset)
							index= linkedPositionOffset - lineOffset;
					} catch (BadLocationException e) {
						//should not happen
					}
				}
			}
			return index;
		}

		@Override
		public void run() {
			boolean isSmartHomeEndEnabled= false;
			IPreferenceStore store= getPreferenceStore();
			if (store != null)
				isSmartHomeEndEnabled= store.getBoolean(AbstractTextEditor.PREFERENCE_NAVIGATION_SMART_HOME_END);

			StyledText st= fSourceViewer.getTextWidget();
			if (st == null || st.isDisposed())
				return;
			boolean caretAtBeginningOfSelection = st.getCaretOffset() == st.getSelection().x;
			Point firstSelection = st.getSelection();
			int[] ranges = st.getSelectionRanges();
			List<Point> newSelection = new ArrayList<>(ranges.length / 2);
			for (int j = 0; j < ranges.length; j += 2) {
				int offset = ranges[j];
				int length = ranges[j + 1];
				int caretOffset = caretAtBeginningOfSelection ? offset : offset + length;
				int lineNumber = st.getLineAtOffset(caretOffset);
				int lineOffset = st.getOffsetAtLine(lineNumber);
				int lineLength;
				int caretOffsetInDocument;
				final IDocument document = fSourceViewer.getDocument();

				try {
					caretOffsetInDocument = widgetOffset2ModelOffset(fSourceViewer, caretOffset);
					lineLength = document.getLineInformationOfOffset(caretOffsetInDocument).getLength();
				} catch (BadLocationException ex) {
					return;
				}

				String line = ""; //$NON-NLS-1$
				if (lineLength > 0) {
					int end = lineOffset + lineLength - 1;
					end = Math.min(end, st.getCharCount() - 1);
					line = st.getText(lineOffset, end);
				}

				// The new caret position
				int newCaretOffset = -1;

				if (isSmartHomeEndEnabled) {
					// Compute the line start offset
					int index = getLineStartPosition(document, line, lineLength, caretOffsetInDocument);
					newCaretOffset = (caretOffset - lineOffset == index) ? lineOffset : lineOffset + index;
				} else if (caretOffset >= lineOffset) {
					// to beginning of line
					newCaretOffset = lineOffset;
				}

				newSelection.add(
						new Point(fDoSelect ? (caretAtBeginningOfSelection ? offset + length : offset) : newCaretOffset,
								newCaretOffset));
			}
			st.setSelectionRanges(newSelection.stream().flatMapToInt(
					p -> IntStream.of(p.x, p.y - p.x))
					.toArray());
			if (newSelection.size() == 1) {
				st.showSelection();
			}
			fireSelectionChanged(firstSelection);
		}
	}

	/**
	 * Internal action to show the editor's ruler context menu (accessibility).
	 * @since 2.0
	 */
	class ShowRulerContextMenuAction extends Action {
		@Override
		public void run() {
			if (fSourceViewer == null)
				return;

			StyledText text= fSourceViewer.getTextWidget();
			if (text == null || text.isDisposed())
				return;

			Point location= text.getLocationAtOffset(text.getCaretOffset());
			location.x= 0;

			if (fVerticalRuler instanceof IVerticalRulerExtension)
				((IVerticalRulerExtension) fVerticalRuler).setLocationOfLastMouseButtonActivity(location.x, location.y);

			location= text.toDisplay(location);
			fRulerContextMenu.setLocation(location.x, location.y);
			fRulerContextMenu.setVisible(true);
		}
	}

	/**
	 * Editor specific selection provider which wraps the source viewer's selection provider.
	 *
	 * @since 3.4 protected, was added in 2.1 as private class
	 */
	protected class SelectionProvider implements IPostSelectionProvider, ISelectionValidator {

		@Override
		public void addSelectionChangedListener(ISelectionChangedListener listener) {
			if (fSourceViewer != null)
				fSourceViewer.getSelectionProvider().addSelectionChangedListener(listener);
		}

		@Override
		public ISelection getSelection() {
			return doGetSelection();
		}

		@Override
		public void removeSelectionChangedListener(ISelectionChangedListener listener) {
			if (fSourceViewer != null)
				fSourceViewer.getSelectionProvider().removeSelectionChangedListener(listener);
		}

		@Override
		public void setSelection(ISelection selection) {
			doSetSelection(selection);
		}

		@Override
		public void addPostSelectionChangedListener(ISelectionChangedListener listener) {
			if (fSourceViewer != null) {
				if (fSourceViewer.getSelectionProvider() instanceof IPostSelectionProvider)  {
					IPostSelectionProvider provider= (IPostSelectionProvider) fSourceViewer.getSelectionProvider();
					provider.addPostSelectionChangedListener(listener);
				}
			}
		}

		@Override
		public void removePostSelectionChangedListener(ISelectionChangedListener listener) {
			if (fSourceViewer != null)  {
				if (fSourceViewer.getSelectionProvider() instanceof IPostSelectionProvider)  {
					IPostSelectionProvider provider= (IPostSelectionProvider) fSourceViewer.getSelectionProvider();
					provider.removePostSelectionChangedListener(listener);
				}
			}
		}

		@Override
		public boolean isValid(ISelection postSelection) {
			return fSelectionListener != null && fSelectionListener.isValid(postSelection);
		}
	}

	/**
	 * Internal implementation class for a change listener.
	 * @since 3.0
	 */
	protected abstract class AbstractSelectionChangedListener implements ISelectionChangedListener  {

		/**
		 * Installs this selection changed listener with the given selection provider. If the
		 * selection provider is a post selection provider, post selection changed events are the
		 * preferred choice, otherwise normal selection changed events are requested.
		 *
		 * @param selectionProvider the selection provider
		 */
		public void install(ISelectionProvider selectionProvider) {
			if (selectionProvider == null)
				return;

			if (selectionProvider instanceof IPostSelectionProvider)  {
				IPostSelectionProvider provider= (IPostSelectionProvider) selectionProvider;
				provider.addPostSelectionChangedListener(this);
			} else  {
				selectionProvider.addSelectionChangedListener(this);
			}
		}

		/**
		 * Removes this selection changed listener from the given selection provider.
		 *
		 * @param selectionProvider the selection provider
		 */
		public void uninstall(ISelectionProvider selectionProvider) {
			if (selectionProvider == null)
				return;

			if (selectionProvider instanceof IPostSelectionProvider)  {
				IPostSelectionProvider provider= (IPostSelectionProvider) selectionProvider;
				provider.removePostSelectionChangedListener(this);
			} else  {
				selectionProvider.removeSelectionChangedListener(this);
			}
		}
	}

	/**
	 * This selection listener allows the SelectionProvider to implement {@link ISelectionValidator}.
	 *
	 * @since 3.0
	 */
	private class SelectionListener extends AbstractSelectionChangedListener implements IDocumentListener {

		private IDocument fDocument;
		private final Object INVALID_SELECTION= new Object();
		private Object fPostSelection= INVALID_SELECTION;

		@Override
		public synchronized void selectionChanged(SelectionChangedEvent event) {
			fPostSelection= event.getSelection();
		}

		@Override
		public synchronized void documentAboutToBeChanged(DocumentEvent event) {
			fPostSelection= INVALID_SELECTION;
		}

		@Override
		public void documentChanged(DocumentEvent event) {
		}

		public synchronized boolean isValid(ISelection selection) {
			return fPostSelection != INVALID_SELECTION && fPostSelection == selection;
		}

		public void setDocument(IDocument document) {
			if (fDocument != null)
				fDocument.removeDocumentListener(this);

			fDocument= document;
			if (fDocument != null)
				fDocument.addDocumentListener(this);
		}

		@Override
		public void install(ISelectionProvider selectionProvider) {
			super.install(selectionProvider);

			if (selectionProvider != null)
				selectionProvider.addSelectionChangedListener(this);
		}

		@Override
		public void uninstall(ISelectionProvider selectionProvider) {
			if (selectionProvider != null)
				selectionProvider.removeSelectionChangedListener(this);

			if (fDocument != null) {
				fDocument.removeDocumentListener(this);
				fDocument= null;
			}
			super.uninstall(selectionProvider);
		}
	}


	/**
	 * Implements the ruler column support of for the given editor.
	 * <p>
	 * This is currently only used to support vertical ruler columns.
	 * </p>
	 *
	 * @since 3.3
	 */
	protected static class ColumnSupport implements IColumnSupport {
		private final AbstractTextEditor fEditor;
		private final RulerColumnRegistry fRegistry;
		private final List<IContributedRulerColumn> fColumns;

		/**
		 * Creates a new column support for the given editor. Only the editor itself should normally
		 * create such an instance.
		 *
		 * @param editor the editor
		 * @param registry the contribution registry to refer to
		 */
		public ColumnSupport(AbstractTextEditor editor, RulerColumnRegistry registry) {
			Assert.isLegal(editor != null);
			Assert.isLegal(registry != null);
			fEditor= editor;
			fRegistry= registry;
			fColumns= new ArrayList<>();
		}

		@Override
		public final void setColumnVisible(RulerColumnDescriptor descriptor, boolean visible) {
			Assert.isLegal(descriptor != null);

			final CompositeRuler ruler= getRuler();
			if (ruler == null)
				return;

			if (!isColumnSupported(descriptor))
				visible= false;

			if (isColumnVisible(descriptor)) {
				if (!visible)
					removeColumn(ruler, descriptor);
			} else {
				if (visible)
					addColumn(ruler, descriptor);
			}
		}

		private void addColumn(final CompositeRuler ruler, final RulerColumnDescriptor descriptor) {

			final int idx= computeIndex(ruler, descriptor);

			SafeRunnable runnable= new SafeRunnable() {
				@Override
				public void run() throws Exception {
					IContributedRulerColumn column= descriptor.createColumn(fEditor);
					fColumns.add(column);
					initializeColumn(column);
					ruler.addDecorator(idx, column);
				}
			};
			SafeRunner.run(runnable);
		}

		/**
		 * Hook to let subclasses initialize a newly created column.
		 * <p>
		 * Subclasses may extend this method.</p>
		 *
		 * @param column the created column
		 */
		protected void initializeColumn(IContributedRulerColumn column) {
		}

		private void removeColumn(final CompositeRuler ruler, final RulerColumnDescriptor descriptor) {
			removeColumn(ruler, getVisibleColumn(ruler, descriptor));
		}

		private void removeColumn(final CompositeRuler ruler, final IContributedRulerColumn rulerColumn) {
			if (rulerColumn != null) {
				SafeRunnable runnable= new SafeRunnable() {
					@Override
					public void run() throws Exception {
						if (ruler != null)
							ruler.removeDecorator(rulerColumn);
						rulerColumn.columnRemoved();
					}
				};
				SafeRunner.run(runnable);
			}
		}

		/**
		 * Returns the currently visible column matching <code>id</code>, <code>null</code> if
		 * none.
		 *
		 * @param ruler the composite ruler to scan
		 * @param descriptor the descriptor of the column of interest
		 * @return the matching column or <code>null</code>
		 */
		private IContributedRulerColumn getVisibleColumn(CompositeRuler ruler, RulerColumnDescriptor descriptor) {
			for (Iterator<IVerticalRulerColumn> it= ruler.getDecoratorIterator(); it.hasNext();) {
				IVerticalRulerColumn column= it.next();
				if (column instanceof IContributedRulerColumn) {
					IContributedRulerColumn rulerColumn= (IContributedRulerColumn)column;
					RulerColumnDescriptor rcd= rulerColumn.getDescriptor();
					if (descriptor.equals(rcd))
						return rulerColumn;
				}
			}
			return null;
		}

		/**
		 * Computes the insertion index for a column contribution into the currently visible columns.
		 *
		 * @param ruler the composite ruler into which to insert the column
		 * @param descriptor the descriptor to compute the index for
		 * @return the insertion index for a new column
		 */
		private int computeIndex(CompositeRuler ruler, RulerColumnDescriptor descriptor) {
			int index= 0;
			List<RulerColumnDescriptor> all= fRegistry.getColumnDescriptors();
			int newPos= all.indexOf(descriptor);
			for (Iterator<IVerticalRulerColumn> it= ruler.getDecoratorIterator(); it.hasNext();) {
				IVerticalRulerColumn column= it.next();
				if (column instanceof IContributedRulerColumn) {
					RulerColumnDescriptor rcd= ((IContributedRulerColumn)column).getDescriptor();
					if (rcd != null && all.indexOf(rcd) > newPos)
						break;
				} else if ("org.eclipse.jface.text.source.projection.ProjectionRulerColumn".equals(column.getClass().getName())) { //$NON-NLS-1$
					// projection column is always the rightmost column
					break;
				}
				index++;
			}
			return index;
		}

		@Override
		public final boolean isColumnVisible(RulerColumnDescriptor descriptor) {
			Assert.isLegal(descriptor != null);
			CompositeRuler ruler= getRuler();
			return ruler != null && getVisibleColumn(ruler, descriptor) != null;
		}

		@Override
		public final boolean isColumnSupported(RulerColumnDescriptor descriptor) {
			Assert.isLegal(descriptor != null);
			if (getRuler() == null)
				return false;

			return descriptor.matchesEditor(fEditor);
		}

		/**
		 * Returns the editor's vertical ruler, if it is a {@link CompositeRuler}, <code>null</code>
		 * otherwise.
		 *
		 * @return the editor's {@link CompositeRuler} or <code>null</code>
		 */
		private CompositeRuler getRuler() {
			Object ruler= fEditor.getAdapter(IVerticalRulerInfo.class);
			if (ruler instanceof CompositeRuler)
				return (CompositeRuler) ruler;
			return null;
		}

		/**
		 * {@inheritDoc}
		 * <p>
		 * Subclasses may extend this method.</p>
		 *
		 */
		@Override
		public void dispose() {
			for (IContributedRulerColumn iContributedRulerColumn : new ArrayList<>(fColumns))
				removeColumn(getRuler(), iContributedRulerColumn);
			fColumns.clear();
		}
	}



	/**
	 * This action behaves in two different ways: If there is no current text
	 * hover, the javadoc is displayed using information presenter. If there is
	 * a current text hover, it is converted into a information presenter in
	 * order to make it sticky.
	 *
	 * @since 3.3
	 */
	private final class InformationDispatchAction extends TextEditorAction {

		/** The wrapped text operation action. */
		private final TextOperationAction fTextOperationAction;

		/**
		 * Creates a dispatch action.
		 *
		 * @param resourceBundle the resource bundle
		 * @param prefix the prefix
		 * @param textOperationAction the text operation action
		 */
		public InformationDispatchAction(ResourceBundle resourceBundle, String prefix, final TextOperationAction textOperationAction) {
			super(resourceBundle, prefix, AbstractTextEditor.this);
			if (textOperationAction == null)
				throw new IllegalArgumentException();
			fTextOperationAction= textOperationAction;
		}

		@Override
		public void run() {

			ISourceViewer sourceViewer= getSourceViewer();
			if (sourceViewer == null) {
				if (fTextOperationAction.isEnabled())
					fTextOperationAction.run();
				return;
			}

			if (sourceViewer instanceof ITextViewerExtension4)  {
				ITextViewerExtension4 extension4= (ITextViewerExtension4) sourceViewer;
				if (extension4.moveFocusToWidgetToken())
					return;
			}

			if (sourceViewer instanceof ITextViewerExtension2) {
				// does a text hover exist?
				ITextHover textHover= ((ITextViewerExtension2) sourceViewer).getCurrentTextHover();
				if (textHover != null && makeTextHoverFocusable(sourceViewer, textHover))
					return;
			}

			if (sourceViewer instanceof ISourceViewerExtension3) {
				// does an annotation hover exist?
				IAnnotationHover annotationHover= ((ISourceViewerExtension3) sourceViewer).getCurrentAnnotationHover();
				if (annotationHover != null && makeAnnotationHoverFocusable(annotationHover))
					return;
			}

			// otherwise, just run the action
			if (fTextOperationAction.isEnabled())
				fTextOperationAction.run();
		}

		/**
		 * Tries to make a text hover focusable (or "sticky").
		 *
		 * @param sourceViewer the source viewer to display the hover over
		 * @param textHover the hover to make focusable
		 * @return <code>true</code> if successful, <code>false</code> otherwise
		 */
		private boolean makeTextHoverFocusable(ISourceViewer sourceViewer, ITextHover textHover) {
			Point hoverEventLocation= ((ITextViewerExtension2) sourceViewer).getHoverEventLocation();
			int offset= computeOffsetAtLocation(sourceViewer, hoverEventLocation.x, hoverEventLocation.y);
			if (offset == -1)
				return false;

			try {
				IRegion hoverRegion= textHover.getHoverRegion(sourceViewer, offset);
				if (hoverRegion == null)
					return false;

				String hoverInfo= textHover.getHoverInfo(sourceViewer, hoverRegion);

				IInformationControlCreator controlCreator= null;
				if (textHover instanceof IInformationProviderExtension2) // this is conceptually wrong, but left here for backwards compatibility
					controlCreator= ((IInformationProviderExtension2)textHover).getInformationPresenterControlCreator();

				IInformationProvider informationProvider= new FocusedInformationPresenter.InformationProvider(hoverRegion, hoverInfo, controlCreator);

				FocusedInformationPresenter informationPresenter= getInformationPresenter();
				informationPresenter.setOffset(offset);
				informationPresenter.setAnchor(AbstractInformationControlManager.ANCHOR_BOTTOM);
				informationPresenter.setMargins(6, 6); // default values from AbstractInformationControlManager
				String contentType= TextUtilities.getContentType(sourceViewer.getDocument(), getSourceViewerConfiguration().getConfiguredDocumentPartitioning(getSourceViewer()), offset, true);
				informationPresenter.setInformationProvider(informationProvider, contentType);
				informationPresenter.showInformation();

				return true;

			} catch (BadLocationException e) {
				return false;
			}
		}

		/**
		 * Tries to make an annotation hover focusable (or "sticky").
		 *
		 * @param annotationHover the hover to make focusable
		 * @return <code>true</code> if successful, <code>false</code> otherwise
		 */
		private boolean makeAnnotationHoverFocusable(IAnnotationHover annotationHover) {
			IVerticalRulerInfo info= getVerticalRuler();
			int line= info.getLineOfLastMouseButtonActivity();
			if (line == -1)
				return false;

			return getInformationPresenter().openFocusedAnnotationHover(annotationHover, line);
		}

		/**
		 * Returns the information presenter (creates it if necessary).
		 *
		 * @return the information presenter
		 * @since 3.6
		 */
		private FocusedInformationPresenter getInformationPresenter() {
			if (fInformationPresenter == null) {
				fInformationPresenter= new FocusedInformationPresenter(getSourceViewer(), getSourceViewerConfiguration());
			}
			return fInformationPresenter;
		}

		// modified version from TextViewer
		private int computeOffsetAtLocation(ITextViewer textViewer, int x, int y) {

			StyledText styledText= textViewer.getTextWidget();
			IDocument document= textViewer.getDocument();

			int widgetOffset = styledText.getOffsetAtPoint(new Point(x, y));
			if (document == null || widgetOffset == -1) {
				return -1;
			}

			try {
				Point p= styledText.getLocationAtOffset(widgetOffset);
				if (p.x > x) {
					widgetOffset--;
				}

				if (textViewer instanceof ITextViewerExtension5) {
					ITextViewerExtension5 extension= (ITextViewerExtension5) textViewer;
					return extension.widgetOffset2ModelOffset(widgetOffset);
				}
				IRegion visibleRegion= textViewer.getVisibleRegion();
				return widgetOffset + visibleRegion.getOffset();
			} catch (IllegalArgumentException e) {
				return -1;
			}
		}
	}

	/**
	 * Key used to look up font preference.
	 * Value: <code>"org.eclipse.jface.textfont"</code>
	 *
	 * @deprecated As of 2.1, replaced by {@link JFaceResources#TEXT_FONT}
	 */
	@Deprecated
	public static final String PREFERENCE_FONT= JFaceResources.TEXT_FONT;
	/**
	 * Key used to look up foreground color preference.
	 * Value: <code>AbstractTextEditor.Color.Foreground</code>
	 * @since 2.0
	 */
	public static final String PREFERENCE_COLOR_FOREGROUND= "AbstractTextEditor.Color.Foreground"; //$NON-NLS-1$
	/**
	 * Key used to look up background color preference.
	 * Value: <code>AbstractTextEditor.Color.Background</code>
	 * @since 2.0
	 */
	public static final String PREFERENCE_COLOR_BACKGROUND= "AbstractTextEditor.Color.Background"; //$NON-NLS-1$
	/**
	 * Key used to look up foreground color system default preference.
	 * Value: <code>AbstractTextEditor.Color.Foreground.SystemDefault</code>
	 * @since 2.0
	 */
	public static final String PREFERENCE_COLOR_FOREGROUND_SYSTEM_DEFAULT= "AbstractTextEditor.Color.Foreground.SystemDefault"; //$NON-NLS-1$
	/**
	 * Key used to look up background color system default preference.
	 * Value: <code>AbstractTextEditor.Color.Background.SystemDefault</code>
	 * @since 2.0
	 */
	public static final String PREFERENCE_COLOR_BACKGROUND_SYSTEM_DEFAULT= "AbstractTextEditor.Color.Background.SystemDefault"; //$NON-NLS-1$
	/**
	 * Key used to look up selection foreground color preference.
	 * Value: <code>AbstractTextEditor.Color.SelectionForeground</code>
	 * @since 3.0
	 */
	public static final String PREFERENCE_COLOR_SELECTION_FOREGROUND= "AbstractTextEditor.Color.SelectionForeground"; //$NON-NLS-1$
	/**
	 * Key used to look up selection background color preference.
	 * Value: <code>AbstractTextEditor.Color.SelectionBackground</code>
	 * @since 3.0
	 */
	public static final String PREFERENCE_COLOR_SELECTION_BACKGROUND= "AbstractTextEditor.Color.SelectionBackground"; //$NON-NLS-1$
	/**
	 * Key used to look up selection foreground color system default preference.
	 * Value: <code>AbstractTextEditor.Color.SelectionForeground.SystemDefault</code>
	 * @since 3.0
	 */
	public static final String PREFERENCE_COLOR_SELECTION_FOREGROUND_SYSTEM_DEFAULT= "AbstractTextEditor.Color.SelectionForeground.SystemDefault"; //$NON-NLS-1$
	/**
	 * Key used to look up selection background color system default preference.
	 * Value: <code>AbstractTextEditor.Color.SelectionBackground.SystemDefault</code>
	 * @since 3.0
	 */
	public static final String PREFERENCE_COLOR_SELECTION_BACKGROUND_SYSTEM_DEFAULT= "AbstractTextEditor.Color.SelectionBackground.SystemDefault"; //$NON-NLS-1$
	/**
	 * Key used to look up find scope background color preference.
	 * Value: <code>AbstractTextEditor.Color.FindScope</code>
	 * @since 2.0
	 */
	public static final String PREFERENCE_COLOR_FIND_SCOPE= "AbstractTextEditor.Color.FindScope"; //$NON-NLS-1$
	/**
	 * Key used to look up smart home/end preference.
	 * Value: <code>AbstractTextEditor.Navigation.SmartHomeEnd</code>
	 * @since 2.1
	 */
	public static final String PREFERENCE_NAVIGATION_SMART_HOME_END= "AbstractTextEditor.Navigation.SmartHomeEnd"; //$NON-NLS-1$
	/**
	 * Key used to look up the custom caret preference.
	 * Value: {@value}
	 * @since 3.0
	 */
	public static final String PREFERENCE_USE_CUSTOM_CARETS= "AbstractTextEditor.Accessibility.UseCustomCarets"; //$NON-NLS-1$
	/**
	 * Key used to look up the caret width preference.
	 * Value: {@value}
	 * @since 3.0
	 */
	public static final String PREFERENCE_WIDE_CARET= "AbstractTextEditor.Accessibility.WideCaret"; //$NON-NLS-1$
	/**
	 * A named preference that controls if hyperlinks are turned on or off.
	 * <p>
	 * Value is of type <code>Boolean</code>.
	 * </p>
	 *
	 * @since 3.1
	 */
	public static final String PREFERENCE_HYPERLINKS_ENABLED= "hyperlinksEnabled"; //$NON-NLS-1$

	/**
	 * A named preference that controls the key modifier for hyperlinks.
	 * <p>
	 * Value is of type <code>String</code>.
	 * </p>
	 *
	 * @since 3.1
	 */
	public static final String PREFERENCE_HYPERLINK_KEY_MODIFIER= "hyperlinkKeyModifier"; //$NON-NLS-1$
	/**
	 * A named preference that controls the key modifier mask for hyperlinks.
	 * The value is only used if the value of <code>PREFERENCE_HYPERLINK_KEY_MODIFIER</code>
	 * cannot be resolved to valid SWT modifier bits.
	 * <p>
	 * Value is of type <code>String</code>.
	 * </p>
	 *
	 * @see #PREFERENCE_HYPERLINK_KEY_MODIFIER
	 * @since 3.1
	 */
	public static final String PREFERENCE_HYPERLINK_KEY_MODIFIER_MASK= "hyperlinkKeyModifierMask"; //$NON-NLS-1$
	/**
	 * A named preference that controls the visible ruler column contributions.
	 * <p>
	 * Value is of type <code>String</code> and should be read using a {@link RulerColumnPreferenceAdapter}.
	 * </p>
	 *
	 * @since 3.3
	 */
	public static final String PREFERENCE_RULER_CONTRIBUTIONS= "rulerContributions"; //$NON-NLS-1$

	/**
	 * A named preference that controls the display of whitespace characters.
	 * <p>
	 * Value is of type <code>Boolean</code>.
	 * </p>
	 *
	 * <p>
	 * The following preferences can be used for fine-grained configuration when
	 * enabled.
	 * </p>
	 * <ul>
	 * <li>{@link #PREFERENCE_SHOW_LEADING_SPACES}</li>
	 * <li>{@link #PREFERENCE_SHOW_ENCLOSED_SPACES}</li>
	 * <li>{@link #PREFERENCE_SHOW_TRAILING_SPACES}</li>
	 * <li>{@link #PREFERENCE_SHOW_LEADING_IDEOGRAPHIC_SPACES}</li>
	 * <li>{@link #PREFERENCE_SHOW_ENCLOSED_IDEOGRAPHIC_SPACES}</li>
	 * <li>{@link #PREFERENCE_SHOW_TRAILING_IDEOGRAPHIC_SPACES}</li>
	 * <li>{@link #PREFERENCE_SHOW_LEADING_TABS}</li>
	 * <li>{@link #PREFERENCE_SHOW_ENCLOSED_TABS}</li>
	 * <li>{@link #PREFERENCE_SHOW_TRAILING_TABS}</li>
	 * <li>{@link #PREFERENCE_SHOW_CARRIAGE_RETURN}</li>
	 * <li>{@link #PREFERENCE_SHOW_LINE_FEED}</li>
	 * <li>{@link #PREFERENCE_WHITESPACE_CHARACTER_ALPHA_VALUE}</li>
	 * </ul>
	 *
	 * @since 3.3
	 */
	public static final String PREFERENCE_SHOW_WHITESPACE_CHARACTERS= "showWhitespaceCharacters"; //$NON-NLS-1$

	/**
	 * A named preference that controls the display of leading Space characters. The value is used
	 * only if the value of {@link #PREFERENCE_SHOW_WHITESPACE_CHARACTERS} is <code>true</code>.
	 * <p>
	 * Value is of type <code>Boolean</code>.
	 * </p>
	 *
	 * @since 3.7
	 */
	public static final String PREFERENCE_SHOW_LEADING_SPACES= "showLeadingSpaces"; //$NON-NLS-1$

	/**
	 * A named preference that controls the display of enclosed Space characters. The value is used
	 * only if the value of {@link #PREFERENCE_SHOW_WHITESPACE_CHARACTERS} is <code>true</code>.
	 * <p>
	 * Value is of type <code>Boolean</code>.
	 * </p>
	 *
	 * @since 3.7
	 */
	public static final String PREFERENCE_SHOW_ENCLOSED_SPACES= "showEnclosedSpaces"; //$NON-NLS-1$

	/**
	 * A named preference that controls the display of trailing Space characters. The value is used
	 * only if the value of {@link #PREFERENCE_SHOW_WHITESPACE_CHARACTERS} is <code>true</code>.
	 * <p>
	 * Value is of type <code>Boolean</code>.
	 * </p>
	 *
	 * @since 3.7
	 */
	public static final String PREFERENCE_SHOW_TRAILING_SPACES= "showTrailingSpaces"; //$NON-NLS-1$

	/**
	 * A named preference that controls the display of leading Ideographic Space characters. The
	 * value is used only if the value of {@link #PREFERENCE_SHOW_WHITESPACE_CHARACTERS} is
	 * <code>true</code>.
	 * <p>
	 * Value is of type <code>Boolean</code>.
	 * </p>
	 *
	 * @since 3.7
	 */
	public static final String PREFERENCE_SHOW_LEADING_IDEOGRAPHIC_SPACES= "showLeadingIdeographicSpaces"; //$NON-NLS-1$

	/**
	 * A named preference that controls the display of enclosed Ideographic Space characters. The
	 * value is used only if the value of {@link #PREFERENCE_SHOW_WHITESPACE_CHARACTERS} is
	 * <code>true</code>.
	 * <p>
	 * Value is of type <code>Boolean</code>.
	 * </p>
	 *
	 * @since 3.7
	 */
	public static final String PREFERENCE_SHOW_ENCLOSED_IDEOGRAPHIC_SPACES= "showEnclosedIdeographicSpaces"; //$NON-NLS-1$

	/**
	 * A named preference that controls the display of trailing Ideographic Space characters. The
	 * value is used only if the value of {@link #PREFERENCE_SHOW_WHITESPACE_CHARACTERS} is
	 * <code>true</code>.
	 * <p>
	 * Value is of type <code>Boolean</code>.
	 * </p>
	 *
	 * @since 3.7
	 */
	public static final String PREFERENCE_SHOW_TRAILING_IDEOGRAPHIC_SPACES= "showTrailingIdeographicSpaces"; //$NON-NLS-1$

	/**
	 * A named preference that controls the display of leading Tab characters. The value is used
	 * only if the value of {@link #PREFERENCE_SHOW_WHITESPACE_CHARACTERS} is <code>true</code>.
	 * <p>
	 * Value is of type <code>Boolean</code>.
	 * </p>
	 *
	 * @since 3.7
	 */
	public static final String PREFERENCE_SHOW_LEADING_TABS= "showLeadingTabs"; //$NON-NLS-1$

	/**
	 * A named preference that controls the display of enclosed Tab characters. The value is used
	 * only if the value of {@link #PREFERENCE_SHOW_WHITESPACE_CHARACTERS} is <code>true</code>.
	 * <p>
	 * Value is of type <code>Boolean</code>.
	 * </p>
	 *
	 * @since 3.7
	 */
	public static final String PREFERENCE_SHOW_ENCLOSED_TABS= "showEnclosedTabs"; //$NON-NLS-1$

	/**
	 * A named preference that controls the display of trailing Tab characters. The value is used
	 * only if the value of {@link #PREFERENCE_SHOW_WHITESPACE_CHARACTERS} is <code>true</code>.
	 * <p>
	 * Value is of type <code>Boolean</code>.
	 * </p>
	 *
	 * @since 3.7
	 */
	public static final String PREFERENCE_SHOW_TRAILING_TABS= "showTrailingTabs"; //$NON-NLS-1$

	/**
	 * A named preference that controls the display of Carriage Return characters. The value is used
	 * only if the value of {@link #PREFERENCE_SHOW_WHITESPACE_CHARACTERS} is <code>true</code>.
	 * <p>
	 * Value is of type <code>Boolean</code>.
	 * </p>
	 *
	 * @since 3.7
	 */
	public static final String PREFERENCE_SHOW_CARRIAGE_RETURN= "showCarriageReturn"; //$NON-NLS-1$

	/**
	 * A named preference that controls the display of Line Feed characters. The value is used only
	 * if the value of {@link #PREFERENCE_SHOW_WHITESPACE_CHARACTERS} is <code>true</code>.
	 * <p>
	 * Value is of type <code>Boolean</code>.
	 * </p>
	 *
	 * @since 3.7
	 */
	public static final String PREFERENCE_SHOW_LINE_FEED= "showLineFeed"; //$NON-NLS-1$

	/**
	 * A named preference that controls the alpha value of whitespace characters. The value is used
	 * only if the value of {@link #PREFERENCE_SHOW_WHITESPACE_CHARACTERS} is <code>true</code>.
	 * <p>
	 * Value is of type <code>Integer</code>.
	 * </p>
	 *
	 * @since 3.7
	 */
	public static final String PREFERENCE_WHITESPACE_CHARACTER_ALPHA_VALUE= "whitespaceCharacterAlphaValue"; //$NON-NLS-1$

	/**
	 * A named preference that controls whether text drag and drop is enabled.
	 * <p>
	 * Value is of type <code>Boolean</code>.
	 * </p>
	 *
	 * @since 3.3
	 */
	public static final String PREFERENCE_TEXT_DRAG_AND_DROP_ENABLED= "textDragAndDropEnabled"; //$NON-NLS-1$

	/**
	 * A named preference that controls if hovers should automatically be closed
	 * when the mouse is moved into them, or when they should be enriched.
	 * <p>
	 * Value is of type <code>Integer</code> and maps to the following
	 * {@link org.eclipse.jface.text.ITextViewerExtension8.EnrichMode}:
	 * </p>
	 * <ul>
	 * <li>-1: <code>null</code> (don't allow moving the mouse into a hover),</li>
	 * <li>0: {@link org.eclipse.jface.text.ITextViewerExtension8.EnrichMode#AFTER_DELAY},</li>
	 * <li>1: {@link org.eclipse.jface.text.ITextViewerExtension8.EnrichMode#IMMEDIATELY},</li>
	 * <li>2: {@link org.eclipse.jface.text.ITextViewerExtension8.EnrichMode#ON_CLICK}.</li>
	 * </ul>
	 *
	 * @since 3.4
	 */
	public static final String PREFERENCE_HOVER_ENRICH_MODE= "hoverReplaceMode"; //$NON-NLS-1$

	/**
	 * A named preference to control the initial word wrap status.
	 * <p>
	 * Value is of type <code>Boolean</code>.
	 * </p>
	 *
	 * @since 3.10
	 */
	public static final String PREFERENCE_WORD_WRAP_ENABLED= "wordwrap.enabled"; //$NON-NLS-1$

	/**
	 * A named preference to control the initial caret offset visibility on the status line.
	 * <p>
	 * Value is of type <code>Boolean</code>.
	 * </p>
	 *
	 * @since 3.13
	 */
	public static final String PREFERENCE_SHOW_CARET_OFFSET = "showCaretOffset"; //$NON-NLS-1$

	/**
	 * A named preference to control the selection visibility on the status line.
	 * <p>
	 * Value is of type <code>Boolean</code>.
	 * </p>
	 *
	 * @since 3.13
	 */
	public static final String PREFERENCE_SHOW_SELECTION_SIZE = "showSelectionSize"; //$NON-NLS-1$

	/** Menu id for the editor context menu. */
	public static final String DEFAULT_EDITOR_CONTEXT_MENU_ID= "#EditorContext"; //$NON-NLS-1$
	/** Menu id for the ruler context menu. */
	public static final String DEFAULT_RULER_CONTEXT_MENU_ID= "#RulerContext"; //$NON-NLS-1$

	/**
	 * Menu id used to contribute to the editor context menu of all textual editors.
	 *
	 * @since 3.5
	 */
	public static final String COMMON_EDITOR_CONTEXT_MENU_ID= "#AbstractTextEditorContext"; //$NON-NLS-1$

	/**
	 * Menu id used to contribute to the ruler context menu of all textual editors.
	 *
	 * @since 3.5
	 */
	public static final String COMMON_RULER_CONTEXT_MENU_ID= "#AbstractTextEditorRulerContext"; //$NON-NLS-1$

	/** The width of the vertical ruler. */
	protected static final int VERTICAL_RULER_WIDTH= 12;

	/**
	 * The complete mapping between action definition IDs used by eclipse and StyledText actions.
	 *
	 * @since 2.0
	 */
	protected static final IdMapEntry[] ACTION_MAP= new IdMapEntry[] {
		// navigation
		new IdMapEntry(ITextEditorActionDefinitionIds.LINE_UP, ST.LINE_UP),
		new IdMapEntry(ITextEditorActionDefinitionIds.LINE_DOWN, ST.LINE_DOWN),
		new IdMapEntry(ITextEditorActionDefinitionIds.LINE_START, ST.LINE_START),
		new IdMapEntry(ITextEditorActionDefinitionIds.LINE_END, ST.LINE_END),
		new IdMapEntry(ITextEditorActionDefinitionIds.COLUMN_PREVIOUS, ST.COLUMN_PREVIOUS),
		new IdMapEntry(ITextEditorActionDefinitionIds.COLUMN_NEXT, ST.COLUMN_NEXT),
		new IdMapEntry(ITextEditorActionDefinitionIds.PAGE_UP, ST.PAGE_UP),
		new IdMapEntry(ITextEditorActionDefinitionIds.PAGE_DOWN, ST.PAGE_DOWN),
		new IdMapEntry(ITextEditorActionDefinitionIds.WORD_PREVIOUS, ST.WORD_PREVIOUS),
		new IdMapEntry(ITextEditorActionDefinitionIds.WORD_NEXT, ST.WORD_NEXT),
		new IdMapEntry(ITextEditorActionDefinitionIds.TEXT_START, ST.TEXT_START),
		new IdMapEntry(ITextEditorActionDefinitionIds.TEXT_END, ST.TEXT_END),
		new IdMapEntry(ITextEditorActionDefinitionIds.WINDOW_START, ST.WINDOW_START),
		new IdMapEntry(ITextEditorActionDefinitionIds.WINDOW_END, ST.WINDOW_END),
		// selection
		new IdMapEntry(ITextEditorActionDefinitionIds.SELECT_LINE_UP, ST.SELECT_LINE_UP),
		new IdMapEntry(ITextEditorActionDefinitionIds.SELECT_LINE_DOWN, ST.SELECT_LINE_DOWN),
		new IdMapEntry(ITextEditorActionDefinitionIds.SELECT_LINE_START, ST.SELECT_LINE_START),
		new IdMapEntry(ITextEditorActionDefinitionIds.SELECT_LINE_END, ST.SELECT_LINE_END),
		new IdMapEntry(ITextEditorActionDefinitionIds.SELECT_COLUMN_PREVIOUS, ST.SELECT_COLUMN_PREVIOUS),
		new IdMapEntry(ITextEditorActionDefinitionIds.SELECT_COLUMN_NEXT, ST.SELECT_COLUMN_NEXT),
		new IdMapEntry(ITextEditorActionDefinitionIds.SELECT_PAGE_UP, ST.SELECT_PAGE_UP),
		new IdMapEntry(ITextEditorActionDefinitionIds.SELECT_PAGE_DOWN, ST.SELECT_PAGE_DOWN),
		new IdMapEntry(ITextEditorActionDefinitionIds.SELECT_WORD_PREVIOUS, ST.SELECT_WORD_PREVIOUS),
		new IdMapEntry(ITextEditorActionDefinitionIds.SELECT_WORD_NEXT,  ST.SELECT_WORD_NEXT),
		new IdMapEntry(ITextEditorActionDefinitionIds.SELECT_TEXT_START, ST.SELECT_TEXT_START),
		new IdMapEntry(ITextEditorActionDefinitionIds.SELECT_TEXT_END, ST.SELECT_TEXT_END),
		new IdMapEntry(ITextEditorActionDefinitionIds.SELECT_WINDOW_START, ST.SELECT_WINDOW_START),
		new IdMapEntry(ITextEditorActionDefinitionIds.SELECT_WINDOW_END, ST.SELECT_WINDOW_END),
		// modification
		new IdMapEntry(IWorkbenchCommandConstants.EDIT_CUT, ST.CUT),
		new IdMapEntry(IWorkbenchCommandConstants.EDIT_COPY, ST.COPY),
		new IdMapEntry(IWorkbenchCommandConstants.EDIT_PASTE, ST.PASTE),
		new IdMapEntry(ITextEditorActionDefinitionIds.DELETE_PREVIOUS, ST.DELETE_PREVIOUS),
		new IdMapEntry(ITextEditorActionDefinitionIds.DELETE_NEXT, ST.DELETE_NEXT),
		new IdMapEntry(ITextEditorActionDefinitionIds.DELETE_PREVIOUS_WORD, ST.DELETE_WORD_PREVIOUS),
		new IdMapEntry(ITextEditorActionDefinitionIds.DELETE_NEXT_WORD, ST.DELETE_WORD_NEXT),
		// miscellaneous
		new IdMapEntry(ITextEditorActionDefinitionIds.TOGGLE_OVERWRITE, ST.TOGGLE_OVERWRITE)
	};

	private final String fReadOnlyLabel= EditorMessages.Editor_statusline_state_readonly_label;
	private final String fWritableLabel= EditorMessages.Editor_statusline_state_writable_label;
	private final String fInsertModeLabel= EditorMessages.Editor_statusline_mode_insert_label;
	private final String fOverwriteModeLabel= EditorMessages.Editor_statusline_mode_overwrite_label;
	private final String fSmartInsertModeLabel= EditorMessages.Editor_statusline_mode_smartinsert_label;

	/** The error message shown in the status line in case of failed information look up. */
	protected final String fErrorLabel= EditorMessages.Editor_statusline_error_label;

	/**
	 * Data structure for the position label value.
	 */
	private static class PositionLabelValue {

		public int fValue;

		@Override
		public String toString() {
			return String.valueOf(fValue);
		}
	}
	/** The pattern used to show the position label in the status line. */
	private final String fPositionLabelPattern= EditorMessages.Editor_statusline_position_pattern;
	/** The position label value of the current line. */
	private final PositionLabelValue fLineLabel= new PositionLabelValue();
	/** The position label value of the current column. */
	private final PositionLabelValue fColumnLabel= new PositionLabelValue();
	/** The position label value of the current offset. */
	private final PositionLabelValue fOffsetLabel = new PositionLabelValue();
	/** The arguments for the position label pattern. */
	private final Object[] fPositionLabelPatternArguments = new Object[] { fLineLabel, fColumnLabel, fOffsetLabel };
	/**
	 * The column support of this editor.
	 * @since 3.3
	 */
	private IColumnSupport fColumnSupport;

	/** The editor's explicit document provider. */
	private IDocumentProvider fExplicitDocumentProvider;
	/** The editor's preference store. */
	private IPreferenceStore fPreferenceStore;
	/** The editor's range indicator. */
	private Annotation fRangeIndicator;
	/** The editor's source viewer configuration. */
	private SourceViewerConfiguration fConfiguration;
	/** The editor's source viewer. */
	private ISourceViewer fSourceViewer;
	/**
	 * The editor's selection provider.
	 * @since 2.1
	 */
	private SelectionProvider fSelectionProvider= new SelectionProvider();
	/**
	 * The editor's selection listener.
	 * @since 3.0
	 */
	private SelectionListener fSelectionListener;
	/** The editor's font. */
	private Font fFont;
	/**
	 * The find scope's highlight color.
	 * @since 2.0
	 */
	private Color fFindScopeHighlightColor;

	/**
	 * The editor's status line.
	 * @since 2.1
	 */
	private IEditorStatusLine fEditorStatusLine;
	/** The editor's vertical ruler. */
	private IVerticalRuler fVerticalRuler;
	/** The editor's context menu id. */
	private String fEditorContextMenuId;
	/** The ruler's context menu id. */
	private String fRulerContextMenuId;
	/** The editor's help context id. */
	private String fHelpContextId;
	/** The editor's presentation mode. */
	private boolean fShowHighlightRangeOnly;
	/** The actions registered with the editor. */
	private Map<String, IAction> fActions= new HashMap<>(10);
	/** The actions marked as selection dependent. */
	private List<String> fSelectionActions= new ArrayList<>(5);
	/** The actions marked as content dependent. */
	private List<String> fContentActions= new ArrayList<>(5);
	/**
	 * The actions marked as property dependent.
	 * @since 2.0
	 */
	private List<String> fPropertyActions= new ArrayList<>(5);
	/**
	 * The actions marked as state dependent.
	 * @since 2.0
	 */
	private List<String> fStateActions= new ArrayList<>(5);
	/** The editor's action activation codes. */
	private List<ActionActivationCode> fActivationCodes= new ArrayList<>(2);
	/** The verify key listener for activation code triggering. */
	private ActivationCodeTrigger fActivationCodeTrigger= new ActivationCodeTrigger();
	/** Context menu listener. */
	private IMenuListener fMenuListener;
	/** Vertical ruler mouse listener. */
	private MouseListener fMouseListener;
	/** Selection changed listener. */
	private ISelectionChangedListener fSelectionChangedListener;
	/** Title image to be disposed. */
	private Image fTitleImage;
	/** The text context menu to be disposed. */
	private Menu fTextContextMenu;
	/** The ruler context menu to be disposed. */
	private Menu fRulerContextMenu;
	/** The editor's element state listener. */
	private IElementStateListener fElementStateListener= new ElementStateListener();
	/**
	 * The editor's text input listener.
	 * @since 2.1
	 */
	private TextInputListener fTextInputListener= new TextInputListener();
	/** The editor's text listener. */
	private TextListener fTextListener= new TextListener();
	/** The editor's property change listener. */
	private IPropertyChangeListener fPropertyChangeListener= new PropertyChangeListener();
	/**
	 * The editor's font properties change listener.
	 * @since 2.1
	 */
	private IPropertyChangeListener fFontPropertyChangeListener= new FontPropertyChangeListener();

	/**
	 * The editor's activation listener.
	 * @since 2.0
	 */
	private ActivationListener fActivationListener;
	/**
	 * Indicates activation should be handled.
	 * @since 3.9
	 */
	private boolean fHandleActivation= true;
	/**
	 * The map of the editor's status fields.
	 * @since 2.0
	 */
	private Map<String, IStatusField> fStatusFields;
	/**
	 * The editor's cursor listener.
	 * @since 2.0
	 */
	private ICursorListener fCursorListener;
	/**
	 * The editor's remembered text selection.
	 * @since 2.0
	 */
	private ISelection fRememberedSelection;
	/**
	 * Indicates whether the editor runs in 1.0 context menu registration compatibility mode.
	 * @since 2.0
	 */
	private boolean fCompatibilityMode= true;
	/**
	 * The number of re-entrances into error correction code while saving.
	 * @since 2.0
	 */
	private int fErrorCorrectionOnSave;
	/**
	 * The delete line target.
	 * @since 2.1
	 */
	private IDeleteLineTarget fDeleteLineTarget;
	/**
	 * The incremental find target.
	 * @since 2.0
	 */
	private IncrementalFindTarget fIncrementalFindTarget;
	/**
	 * The mark region target.
	 * @since 2.0
	 */
	private IMarkRegionTarget fMarkRegionTarget;
	/**
	 * Cached modification stamp of the editor's input.
	 * @since 2.0
	 */
	private long fModificationStamp= -1;
	/**
	 * Ruler context menu listeners.
	 * @since 2.0
	 */
	private List<IMenuListener> fRulerContextMenuListeners= new ArrayList<>();
	/**
	 * Indicates whether sanity checking in enabled.
	 * @since 2.0
	 */
	private boolean fIsSanityCheckEnabled= true;
	/**
	 * The find replace target.
	 * @since 2.1
	 */
	private FindReplaceTarget fFindReplaceTarget;
	/**
	 * Indicates whether state validation is enabled.
	 * @since 2.1
	 */
	private boolean fIsStateValidationEnabled= true;
	/**
	 * The key binding scopes of this editor.
	 * @since 2.1
	 */
	private String[] fKeyBindingScopes;
	/**
	 * Whether the overwrite mode can be turned on.
	 * @since 3.0
	 */
	private boolean fIsOverwriteModeEnabled= true;
	/**
	 * Whether the overwrite mode is currently on.
	 * @since 3.0
	 */
	private boolean fIsOverwriting= false;
	/**
	 * The editor's insert mode.
	 * @since 3.0
	 */
	private InsertMode fInsertMode= SMART_INSERT;
	/**
	 * The sequence of legal editor insert modes.
	 * @since 3.0
	 */
	private List<InsertMode> fLegalInsertModes= null;
	/**
	 * The non-default caret.
	 * @since 3.0
	 */
	private Caret fNonDefaultCaret;
	/**
	 * The image used in non-default caret.
	 * @since 3.0
	 */
	private Image fNonDefaultCaretImage;
	/**
	 * The styled text's initial caret.
	 * @since 3.0
	 */
	private Caret fInitialCaret;
	/**
	 * The operation approver used to warn on undoing of non-local operations.
	 * @since 3.1
	 */
	private IOperationApprover fNonLocalOperationApprover;
	/**
	 * The operation approver used to warn of linear undo violations.
	 * @since 3.1
	 */
	private IOperationApprover fLinearUndoViolationApprover;
	/**
	 * This editor's memento holding data for restoring it after restart.
	 * @since 3.3
	 */
	private IMemento fMementoToRestore;
	/**
	 * This editor's savable.
	 * @since 3.3
	 */
	private TextEditorSavable fSavable;
	/**
	 * Tells whether text drag and drop has been installed on the control.
	 * @since 3.3
	 */
	private boolean fIsTextDragAndDropInstalled= false;
	/**
	 * Helper token to decide whether drag and
	 * drop happens inside the same editor.
	 * @since 3.3
	 */
	private Object fTextDragAndDropToken;
	/**
	 * The information presenter, may be <code>null</code>.
	 * @since 3.3
	 */
	private FocusedInformationPresenter fInformationPresenter;

	/**
	 * Tells whether this editor has been activated at least once.
	 * @since 3.3.2
	 */
	private boolean fHasBeenActivated= false;
	/**
	 * Key binding support for the quick assist assistant.
	 * @since 3.4
	 */
	private KeyBindingSupportForAssistant fKeyBindingSupportForQuickAssistant;

	/**
	 * Key binding support for the quick assist assistant.
	 * @since 3.5
	 */
	private KeyBindingSupportForAssistant fKeyBindingSupportForContentAssistant;

	/**
	 * The save action.
	 * @since 3.6.1
	 */
	private IWorkbenchAction fSaveAction;


	/**
	 * Creates a new text editor. If not explicitly set, this editor uses
	 * a <code>SourceViewerConfiguration</code> to configure its
	 * source viewer. This viewer does not have a range indicator installed,
	 * nor any menu id set. By default, the created editor runs in 1.0 context
	 * menu registration compatibility mode.
	 */
	protected AbstractTextEditor() {
		super();
		fEditorContextMenuId= null;
		fRulerContextMenuId= null;
		fHelpContextId= null;
	}

	@Override
	public IDocumentProvider getDocumentProvider() {
		return fExplicitDocumentProvider;
	}

	/**
	 * Returns the editor's range indicator. May return <code>null</code> if no
	 * range indicator is installed.
	 *
	 * @return the editor's range indicator which may be <code>null</code>
	 */
	protected final Annotation getRangeIndicator() {
		return fRangeIndicator;
	}

	/**
	 * Returns the editor's source viewer configuration. May return <code>null</code>
	 * before the editor's part has been created and after disposal.
	 *
	 * @return the editor's source viewer configuration which may be <code>null</code>
	 */
	protected final SourceViewerConfiguration getSourceViewerConfiguration() {
		return fConfiguration;
	}

	/**
	 * Returns the editor's source viewer. May return <code>null</code> before
	 * the editor's part has been created and after disposal.
	 *
	 * @return the editor's source viewer which may be <code>null</code>
	 */
	protected final ISourceViewer getSourceViewer() {
		return fSourceViewer;
	}

	/**
	 * Returns the editor's vertical ruler. May return <code>null</code> before
	 * the editor's part has been created and after disposal.
	 *
	 * @return the editor's vertical ruler which may be <code>null</code>
	 */
	protected final IVerticalRuler getVerticalRuler() {
		return fVerticalRuler;
	}

	/**
	 * Returns the editor's context menu id. May return <code>null</code> before
	 * the editor's part has been created.
	 *
	 * @return the editor's context menu id which may be <code>null</code>
	 */
	protected final String getEditorContextMenuId() {
		return fEditorContextMenuId;
	}

	/**
	 * Returns the ruler's context menu id. May return <code>null</code> before
	 * the editor's part has been created.
	 *
	 * @return the ruler's context menu id which may be <code>null</code>
	 */
	protected final String getRulerContextMenuId() {
		return fRulerContextMenuId;
	}

	/**
	 * Returns the editor's help context id or <code>null</code> if none has
	 * been set.
	 *
	 * @return the editor's help context id which may be <code>null</code>
	 */
	protected final String getHelpContextId() {
		return fHelpContextId;
	}

	/**
	 * Returns this editor's preference store or <code>null</code> if none has
	 * been set.
	 *
	 * @return this editor's preference store which may be <code>null</code>
	 */
	protected final IPreferenceStore getPreferenceStore() {
		return fPreferenceStore;
	}

	/**
	 * Sets this editor's document provider. This method must be
	 * called before the editor's control is created.
	 *
	 * @param provider the document provider
	 */
	protected void setDocumentProvider(IDocumentProvider provider) {
		fExplicitDocumentProvider= provider;
	}

	/**
	 * Sets this editor's source viewer configuration used to configure its
	 * internal source viewer. This method must be called before the editor's
	 * control is created. If not, this editor uses a <code>SourceViewerConfiguration</code>.
	 *
	 * @param configuration the source viewer configuration object
	 */
	protected void setSourceViewerConfiguration(SourceViewerConfiguration configuration) {
		Assert.isNotNull(configuration);
		fConfiguration= configuration;
	}

	/**
	 * Sets the annotation which this editor uses to represent the highlight
	 * range if the editor is configured to show the entire document. If the
	 * range indicator is not set, this editor will not show a range indication.
	 *
	 * @param rangeIndicator the annotation
	 */
	protected void setRangeIndicator(Annotation rangeIndicator) {
		Assert.isNotNull(rangeIndicator);
		fRangeIndicator= rangeIndicator;
	}

	/**
	 * Sets this editor's context menu id.
	 *
	 * @param contextMenuId the context menu id
	 */
	protected void setEditorContextMenuId(String contextMenuId) {
		Assert.isNotNull(contextMenuId);
		fEditorContextMenuId= contextMenuId;
	}

	/**
	 * Sets the ruler's context menu id.
	 *
	 * @param contextMenuId the context menu id
	 */
	protected void setRulerContextMenuId(String contextMenuId) {
		Assert.isNotNull(contextMenuId);
		fRulerContextMenuId= contextMenuId;
	}

	/**
	 * Sets the context menu registration 1.0 compatibility mode. (See class
	 * description for more details.)
	 *
	 * @param compatible <code>true</code> if compatibility mode is enabled
	 * @since 2.0
	 */
	protected final void setCompatibilityMode(boolean compatible) {
		fCompatibilityMode= compatible;
	}

	/**
	 * Sets the editor's help context id.
	 *
	 * @param helpContextId the help context id
	 */
	protected void setHelpContextId(String helpContextId) {
		Assert.isNotNull(helpContextId);
		fHelpContextId= helpContextId;
	}

	/**
	 * Sets the key binding scopes for this editor.
	 *
	 * @param scopes a non-empty array of key binding scope identifiers
	 * @since 2.1
	 */
	protected void setKeyBindingScopes(String[] scopes) {
		Assert.isTrue(scopes != null && scopes.length > 0);
		fKeyBindingScopes= scopes;
	}

	/**
	 * Sets this editor's preference store. This method must be
	 * called before the editor's control is created.
	 *
	 * @param store the preference store or <code>null</code> to remove the
	 * 		  preference store
	 */
	protected void setPreferenceStore(IPreferenceStore store) {
		if (fPreferenceStore != null) {
			fPreferenceStore.removePropertyChangeListener(fPropertyChangeListener);
			fPreferenceStore.removePropertyChangeListener(fFontPropertyChangeListener);
		}

		fPreferenceStore= store;

		if (fPreferenceStore != null) {
			fPreferenceStore.addPropertyChangeListener(fPropertyChangeListener);
			fPreferenceStore.addPropertyChangeListener(fFontPropertyChangeListener);
		}
	}

	@Override
	public boolean isEditable() {
		IDocumentProvider provider= getDocumentProvider();
		if (provider instanceof IDocumentProviderExtension) {
			IDocumentProviderExtension extension= (IDocumentProviderExtension) provider;
			return extension.isModifiable(getEditorInput());
		}
		return false;
	}

	/**
	 * {@inheritDoc}
	 * <p>
	 * Returns <code>null</code> after disposal.
	 * </p>
	 *
	 * @return the selection provider or <code>null</code> if the editor has
	 *         been disposed
	 */
	@Override
	public ISelectionProvider getSelectionProvider() {
		return fSelectionProvider;
	}

	/**
	 * Remembers the current selection of this editor. This method is called when, e.g.,
	 * the content of the editor is about to be reverted to the saved state. This method
	 * remembers the selection in a semantic format, i.e., in a format which allows to
	 * restore the selection even if the originally selected text is no longer part of the
	 * editor's content.
	 * <p>
	 * Subclasses should implement this method including all necessary state. This
	 * default implementation remembers the textual range only and is thus purely
	 * syntactic.</p>
	 *
	 * @see #restoreSelection()
	 * @since 2.0
	 */
	protected void rememberSelection() {
		fRememberedSelection= doGetSelection();
	}

	/**
	 * Returns the current selection.
	 * @return ISelection
	 * @since 2.1
	 */
	protected ISelection doGetSelection() {
		ISelectionProvider sp= null;
		if (fSourceViewer != null)
			sp= fSourceViewer.getSelectionProvider();
		return (sp == null ? null : sp.getSelection());
	}

	/**
	 * Restores a selection previously remembered by <code>rememberSelection</code>.
	 * Subclasses may reimplement this method and thereby semantically adapt the
	 * remembered selection. This default implementation just selects the
	 * remembered textual range.
	 *
	 * @see #rememberSelection()
	 * @since 2.0
	 */
	protected void restoreSelection() {
		if (fRememberedSelection instanceof ITextSelection) {
			ITextSelection textSelection= (ITextSelection)fRememberedSelection;
			if (isValidSelection(textSelection.getOffset(), textSelection.getLength()))
				doSetSelection(fRememberedSelection);
		}
		fRememberedSelection= null;
	}

	/**
	 * Tells whether the given selection is valid.
	 *
	 * @param offset the offset of the selection
	 * @param length the length of the selection
	 * @return <code>true</code> if the selection is valid
	 * @since 2.1
	 */
	private boolean isValidSelection(int offset, int length) {
		IDocumentProvider provider= getDocumentProvider();
		if (provider != null) {
			IDocument document= provider.getDocument(getEditorInput());
			if (document != null) {
				int end= offset + length;
				int documentLength= document.getLength();
				return 0 <= offset  && offset <= documentLength && 0 <= end && end <= documentLength && length >= 0;
			}
		}
		return false;
	}

	/**
	 * Sets the given selection.
	 *
	 * @param selection the selection
	 * @since 2.1
	 */
	protected void doSetSelection(ISelection selection) {
		if (selection instanceof IMultiTextSelection && ((IMultiTextSelection) selection).getRegions().length > 1) {
			getSourceViewer().getSelectionProvider().setSelection(selection);
		} else if (selection instanceof ITextSelection) {
			ITextSelection textSelection= (ITextSelection) selection;
			selectAndReveal(textSelection.getOffset(), textSelection.getLength());
		}
	}

	/**
	 * Creates the listener on this editor's context menus.
	 *
	 * @return the created menu listener
	 * @since 3.4
	 */
	protected IMenuListener createContextMenuListener() {
		return menu -> {
			String id = menu.getId();
			if (getRulerContextMenuId().equals(id)) {
				setFocus();
				rulerContextMenuAboutToShow(menu);
			} else if (getEditorContextMenuId().equals(id)) {
				setFocus();
				editorContextMenuAboutToShow(menu);
			}
		};
	}

	/**
	 * Creates and returns the listener on this editor's context menus.
	 *
	 * @return the menu listener
	 */
	protected final IMenuListener getContextMenuListener() {
		if (fMenuListener == null)
			fMenuListener= createContextMenuListener();
		return fMenuListener;
	}

	/**
	 * Creates and returns the listener on this editor's vertical ruler.
	 *
	 * @return the mouse listener
	 */
	protected final MouseListener getRulerMouseListener() {
		if (fMouseListener == null) {
			fMouseListener= new MouseListener() {

				private boolean fDoubleClicked= false;
				private final int fDoubleClickTime= getSite().getShell().getDisplay().getDoubleClickTime();
				private long fMouseUpDelta= 0;

				private void triggerAction(String actionID, MouseEvent e) {
					// ActionId can be prefixed with modifiers
					StringBuilder newActionId = new StringBuilder(""); //$NON-NLS-1$
					if ((e.stateMask & SWT.MOD1) > 0) {
						newActionId.append("M1+"); //$NON-NLS-1$
					}
					if ((e.stateMask & SWT.MOD2) > 0) {
						newActionId.append("M2+"); //$NON-NLS-1$
					}
					if ((e.stateMask & SWT.MOD3) > 0) {
						newActionId.append("M3+"); //$NON-NLS-1$
					}
					newActionId.append(actionID);
					IAction action = getAction(newActionId.toString());
					// If action does not exist with specified
					// modifiers+actionId, try to retrieve action with only
					// actionId
					if (action == null) {
						action = getAction(actionID);
					}
					if (action != null) {
						if (action instanceof IUpdate)
							((IUpdate) action).update();
						if (action.isEnabled()) {
							Event event= new Event();
							event.type= fDoubleClicked ? SWT.MouseDoubleClick : SWT.MouseUp;
							event.display= e.display;
							event.widget= e.widget;
							event.time= e.time;
							event.data= e.data;
							event.x= e.x;
							event.y= e.y;
							event.button= e.button;
							event.stateMask= e.stateMask;
							event.count= e.count;
							action.runWithEvent(event);
						}
					}
				}

				@Override
				public void mouseUp(final MouseEvent e) {
					setFocus();
					final int delay= fMouseUpDelta == 0 ? 0 : fDoubleClickTime - (int)(System.currentTimeMillis() - fMouseUpDelta);
					if (1 != e.button)
						return;

					Runnable runnable = () -> {
						if (!fDoubleClicked)
							triggerAction(ITextEditorActionConstants.RULER_CLICK, e);
					};
					if (delay <= 0)
						runnable.run();
					else
						e.widget.getDisplay().timerExec(delay, runnable);
				}

				@Override
				public void mouseDoubleClick(MouseEvent e) {
					if (1 == e.button) {
						fDoubleClicked= true;
						triggerAction(ITextEditorActionConstants.RULER_DOUBLE_CLICK, e);
					}
				}

				@Override
				public void mouseDown(MouseEvent e) {
					fMouseUpDelta= System.currentTimeMillis();
					fDoubleClicked= false;
					if (fRulerContextMenu != null && !fRulerContextMenu.isDisposed()) {
						Display display= fRulerContextMenu.getDisplay();
						Point location= display.getCursorLocation();
						fRulerContextMenu.setLocation(location.x, location.y);
					}
				}
			};
		}
		return fMouseListener;
	}

	/**
	 * Returns this editor's selection changed listener to be installed
	 * on the editor's source viewer.
	 *
	 * @return the listener
	 */
	protected final ISelectionChangedListener getSelectionChangedListener() {
		if (fSelectionChangedListener == null) {
			fSelectionChangedListener= new ISelectionChangedListener() {

				private Runnable fRunnable = () -> {
					// check whether editor has not been disposed yet
					if (fSourceViewer != null && fSourceViewer.getDocument() != null) {
						handleCursorPositionChangedWrapper();
						updateSelectionDependentActions();
					}
				};

				private Display fDisplay;

				@Override
				public void selectionChanged(SelectionChangedEvent event) {
					if (fDisplay == null)
						fDisplay= getSite().getShell().getDisplay();
					if (Display.getCurrent() == fDisplay)
						fRunnable.run();
					else
						fDisplay.asyncExec(fRunnable);
				}
			};
		}

		return fSelectionChangedListener;
	}

	/**
	 * Returns this editor's "cursor" listener to be installed on the editor's
	 * source viewer. This listener is listening to key and mouse button events.
	 * It triggers the updating of the status line by calling
	 * <code>handleCursorPositionChanged()</code>.
	 *
	 * @return the listener
	 * @since 2.0
	 */
	protected final ICursorListener getCursorListener() {
		if (fCursorListener == null) {
			fCursorListener= new ICursorListener() {

				@Override
				public void keyPressed(KeyEvent e) {
					handleCursorPositionChangedWrapper();
				}

				@Override
				public void keyReleased(KeyEvent e) {
				}

				@Override
				public void mouseDoubleClick(MouseEvent e) {
				}

				@Override
				public void mouseDown(MouseEvent e) {
				}

				@Override
				public void mouseUp(MouseEvent e) {
					handleCursorPositionChangedWrapper();
				}
			};
		}
		return fCursorListener;
	}

	/**
	 * Implements the <code>init</code> method of <code>IEditorPart</code>.
	 * Subclasses replacing <code>init</code> may choose to call this method in
	 * their implementation.
	 *
	 * @param window the workbench window
	 * @param site the editor's site
	 * @param input the editor input for the editor being created
	 * @throws PartInitException if {@link #doSetInput(IEditorInput)} fails or gets canceled
	 *
	 * @see org.eclipse.ui.IEditorPart#init(org.eclipse.ui.IEditorSite, org.eclipse.ui.IEditorInput)
	 * @since 2.1
	 */
	protected final void internalInit(IWorkbenchWindow window, final IEditorSite site, final IEditorInput input) throws PartInitException {

		IRunnableWithProgress runnable = monitor -> {
			try {

				if (getDocumentProvider() instanceof IDocumentProviderExtension2) {
					IDocumentProviderExtension2 extension1 = (IDocumentProviderExtension2) getDocumentProvider();
					extension1.setProgressMonitor(monitor);
				}

				doSetInput(input);

			} catch (CoreException x) {
				throw new InvocationTargetException(x);
			} finally {
				if (getDocumentProvider() instanceof IDocumentProviderExtension2) {
					IDocumentProviderExtension2 extension2 = (IDocumentProviderExtension2) getDocumentProvider();
					extension2.setProgressMonitor(null);
				}
			}
		};

		try {
//			When using the progress service always a modal dialog pops up. The site should be asked for a runnable context
//			which could be the workbench window or the progress service, depending on what the site represents.
//			getSite().getWorkbenchWindow().getWorkbench().getProgressService().run(false, true, runnable);

			getSite().getWorkbenchWindow().run(false, true, runnable);

		} catch (InterruptedException x) {
		} catch (InvocationTargetException x) {
			Throwable t= x.getTargetException();
			if (t instanceof CoreException) {
				/*
				/* XXX: Remove unpacking of CoreException once the following bug is
				 *		fixed: https://bugs.eclipse.org/bugs/show_bug.cgi?id=81640
				 */
				CoreException e= (CoreException)t;
				IStatus status= e.getStatus();
				if (status.getException() != null)
					throw new PartInitException(status);
				throw new PartInitException(new Status(status.getSeverity(), status.getPlugin(), status.getCode(), status.getMessage(), t));
			}
			throw new PartInitException(new Status(IStatus.ERROR, TextEditorPlugin.PLUGIN_ID, IStatus.OK, EditorMessages.Editor_error_init, t));
		}
	}

	@Override
	public void init(final IEditorSite site, final IEditorInput input) throws PartInitException {

		setSite(site);

		internalInit(site.getWorkbenchWindow(), site, input);
		fActivationListener= new ActivationListener(site.getWorkbenchWindow().getPartService());
	}

	/**
	 * Creates the vertical ruler to be used by this editor.
	 * Subclasses may re-implement this method.
	 *
	 * @return the vertical ruler
	 */
	protected IVerticalRuler createVerticalRuler() {
		return new VerticalRuler(VERTICAL_RULER_WIDTH);
	}

	/**
	 * Adds enabled ruler contributions to the vertical ruler.
	 * <p>
	 * Clients may extend or replace.</p>
	 *
	 * @param ruler the composite ruler to add contributions to
	 * @since 3.3
	 */
	protected void updateContributedRulerColumns(CompositeRuler ruler) {
		IColumnSupport support= getAdapter(IColumnSupport.class);
		if (support == null)
			return;

		RulerColumnPreferenceAdapter adapter= null;
		if (fPreferenceStore != null)
			adapter= new RulerColumnPreferenceAdapter(getPreferenceStore(), PREFERENCE_RULER_CONTRIBUTIONS);

		RulerColumnRegistry registry= RulerColumnRegistry.getDefault();
		List<RulerColumnDescriptor> descriptors= registry.getColumnDescriptors();
		for (RulerColumnDescriptor descriptor : descriptors) {
			support.setColumnVisible(descriptor, adapter == null || adapter.isEnabled(descriptor));
		}
	}

	/**
	 * Creates the column support to be used by this editor to manage the
	 * contributed ruler columns.
	 * Subclasses may re-implement this method using the {@link ColumnSupport},
	 * e.g. by returning <code>new ColumnSupport(this, RulerColumnRegistry.getDefault());</code>.
	 * <p>
	 * <strong>Note:</strong> If you override this method to provide column support you will
	 * also need to override {@link #createVerticalRuler()} to return a {@link CompositeRuler}.</p>
	 * <p>
	 * Out of the box this class does not install this support and hence this
	 * implementation always returns <code>null</code>.</p>
	 *
	 * @return the column support or <code>null</code> if none
	 * @since 3.3
	 */
	protected IColumnSupport createColumnSupport() {
		return null;
	}

	/**
	 * Creates the source viewer to be used by this editor.
	 * Subclasses may re-implement this method.
	 *
	 * @param parent the parent control
	 * @param ruler the vertical ruler
	 * @param styles style bits, <code>SWT.WRAP</code> is currently not supported
	 * @return the source viewer
	 */
	protected ISourceViewer createSourceViewer(Composite parent, IVerticalRuler ruler, int styles) {
		return new SourceViewer(parent, ruler, styles);
	}

	/**
	 * Initializes the drag and drop support for the given viewer based on
	 * provided editor adapter for drop target listeners.
	 *
	 * @param viewer the viewer
	 * @since 3.0
	 */
	protected void initializeDragAndDrop(ISourceViewer viewer) {
		IDragAndDropService dndService= getSite().getService(IDragAndDropService.class);
		if (dndService == null)
			return;

		ITextEditorDropTargetListener listener= getAdapter(ITextEditorDropTargetListener.class);

		if (listener == null) {
			Object object= Platform.getAdapterManager().loadAdapter(this, "org.eclipse.ui.texteditor.ITextEditorDropTargetListener"); //$NON-NLS-1$
			if (object instanceof ITextEditorDropTargetListener)
				listener= (ITextEditorDropTargetListener)object;
		}

		if (listener != null)
			dndService.addMergedDropTarget(viewer.getTextWidget(), DND.DROP_MOVE | DND.DROP_COPY, listener.getTransfers(), listener);

		IPreferenceStore store= getPreferenceStore();
		if (store != null && store.getBoolean(PREFERENCE_TEXT_DRAG_AND_DROP_ENABLED))
			installTextDragAndDrop(viewer);

	}

	/**
	 * The <code>AbstractTextEditor</code> implementation of this
	 * <code>IWorkbenchPart</code> method creates the vertical ruler and source
	 * viewer.
	 * <p>
	 * Subclasses may extend this method. Besides extending this method, the
	 * behavior of <code>createPartControl</code> may be customized by calling,
	 * extending or replacing the following methods: <br>
	 * Subclasses may supply customized implementations for some members using
	 * the following methods before <code>createPartControl</code> is invoked:
	 * </p>
	 * <ul>
	 * <li>{@linkplain #setSourceViewerConfiguration(SourceViewerConfiguration)
	 * setSourceViewerConfiguration} to supply a custom source viewer
	 * configuration,</li>
	 * <li>{@linkplain #setRangeIndicator(Annotation) setRangeIndicator} to
	 * provide a range indicator,</li>
	 * <li>{@linkplain #setHelpContextId(String) setHelpContextId} to provide a
	 * help context id,</li>
	 * <li>{@linkplain #setEditorContextMenuId(String) setEditorContextMenuId}
	 * to set a custom context menu id,</li>
	 * <li>{@linkplain #setRulerContextMenuId(String) setRulerContextMenuId} to
	 * set a custom ruler context menu id.</li>
	 * </ul>
	 * <br>
	 * Subclasses may replace the following methods called from within
	 * <code>createPartControl</code>:
	 * <ul>
	 * <li>{@linkplain #createVerticalRuler() createVerticalRuler} to supply a
	 * custom vertical ruler,</li>
	 * <li>{@linkplain #createSourceViewer(Composite, IVerticalRuler, int)
	 * createSourceViewer} to supply a custom source viewer,</li>
	 * <li>{@linkplain #getSelectionProvider() getSelectionProvider} to supply a
	 * custom selection provider.</li>
	 * </ul>
	 * <br>
	 * Subclasses may extend the following methods called from within
	 * <code>createPartControl</code>:
	 * <ul>
	 * <li>{@linkplain #initializeViewerColors(ISourceViewer)
	 * initializeViewerColors} to customize the viewer color scheme (may also be
	 * replaced),</li>
	 * <li>{@linkplain #initializeDragAndDrop(ISourceViewer)
	 * initializeDragAndDrop} to customize drag and drop (may also be
	 * replaced),</li>
	 * <li>{@linkplain #createNavigationActions() createNavigationActions} to
	 * add navigation actions,</li>
	 * <li>{@linkplain #createActions() createActions} to add text editor
	 * actions.</li>
	 * </ul>
	 *
	 * @param parent
	 *            the parent composite
	 */
	@Override
	public void createPartControl(Composite parent) {

		fVerticalRuler= createVerticalRuler();

		int styles= SWT.V_SCROLL | SWT.H_SCROLL | SWT.MULTI | SWT.BORDER | SWT.FULL_SELECTION;
		fSourceViewer= createSourceViewer(parent, fVerticalRuler, styles);

		if (fConfiguration == null)
			fConfiguration= new SourceViewerConfiguration();
		fSourceViewer.configure(fConfiguration);

		if (fSourceViewer instanceof ISourceViewerExtension4)
			fKeyBindingSupportForContentAssistant= new KeyBindingSupportForAssistant(((ISourceViewerExtension4)fSourceViewer));

		if (fSourceViewer instanceof ISourceViewerExtension3) {
			IQuickAssistAssistant assistant= ((ISourceViewerExtension3)fSourceViewer).getQuickAssistAssistant();
			if (assistant != null)
				fKeyBindingSupportForQuickAssistant= new KeyBindingSupportForAssistant(assistant);
		}

		if (fRangeIndicator != null)
			fSourceViewer.setRangeIndicator(fRangeIndicator);

		fSourceViewer.addTextListener(fTextListener);
		fSourceViewer.addTextInputListener(fTextListener);
		getSelectionProvider().addSelectionChangedListener(getSelectionChangedListener());

		initializeViewerFont(fSourceViewer);
		initializeViewerColors(fSourceViewer);
		initializeFindScopeColor(fSourceViewer);
		initializeDragAndDrop(fSourceViewer);

		StyledText styledText= fSourceViewer.getTextWidget();
		styledText.addMouseListener(getCursorListener());
		styledText.addKeyListener(getCursorListener());

		// Disable orientation switching until we fully support it.
		styledText.addListener(SWT.OrientationChange, event -> event.doit = false);

		if (getHelpContextId() != null)
			PlatformUI.getWorkbench().getHelpSystem().setHelp(styledText, getHelpContextId());


		String id= fEditorContextMenuId != null ?  fEditorContextMenuId : DEFAULT_EDITOR_CONTEXT_MENU_ID;

		MenuManager manager= new MenuManager(id, id);
		manager.setRemoveAllWhenShown(true);
		manager.addMenuListener(getContextMenuListener());
		fTextContextMenu= manager.createContextMenu(styledText);

		styledText.setMenu(fTextContextMenu);

		if (fEditorContextMenuId != null)
			getEditorSite().registerContextMenu(fEditorContextMenuId, manager, getSelectionProvider(), isEditorInputIncludedInContextMenu());
		else if (fCompatibilityMode)
			getEditorSite().registerContextMenu(DEFAULT_EDITOR_CONTEXT_MENU_ID, manager, getSelectionProvider(), isEditorInputIncludedInContextMenu());

		if ((fEditorContextMenuId != null && fCompatibilityMode) || fEditorContextMenuId  == null) {
			String partId= getEditorSite().getId();
			if (partId != null)
				getEditorSite().registerContextMenu(partId + ".EditorContext", manager, getSelectionProvider(), isEditorInputIncludedInContextMenu()); //$NON-NLS-1$
		}

		getEditorSite().registerContextMenu(COMMON_EDITOR_CONTEXT_MENU_ID, manager, getSelectionProvider(), false);

		if (fEditorContextMenuId == null)
			fEditorContextMenuId= DEFAULT_EDITOR_CONTEXT_MENU_ID;


		id= fRulerContextMenuId != null ? fRulerContextMenuId : DEFAULT_RULER_CONTEXT_MENU_ID;
		manager= new MenuManager(id, id);
		manager.setRemoveAllWhenShown(true);
		manager.addMenuListener(getContextMenuListener());

		Control rulerControl= fVerticalRuler.getControl();
		fRulerContextMenu= manager.createContextMenu(rulerControl);
		rulerControl.setMenu(fRulerContextMenu);
		rulerControl.addMouseListener(getRulerMouseListener());

		if (fRulerContextMenuId != null)
			getEditorSite().registerContextMenu(fRulerContextMenuId, manager, getSelectionProvider(), false);
		else if (fCompatibilityMode)
			getEditorSite().registerContextMenu(DEFAULT_RULER_CONTEXT_MENU_ID, manager, getSelectionProvider(), false);

		if ((fRulerContextMenuId != null && fCompatibilityMode) || fRulerContextMenuId  == null) {
			String partId= getSite().getId();
			if (partId != null)
				getEditorSite().registerContextMenu(partId + ".RulerContext", manager, getSelectionProvider(), false); //$NON-NLS-1$
		}

		getEditorSite().registerContextMenu(COMMON_RULER_CONTEXT_MENU_ID, manager, getSelectionProvider(), false);

		if (fRulerContextMenuId == null)
			fRulerContextMenuId= DEFAULT_RULER_CONTEXT_MENU_ID;

		initializeZoomGestures(rulerControl, fSourceViewer);

		getSite().setSelectionProvider(getSelectionProvider());

		fSelectionListener= new SelectionListener();
		fSelectionListener.install(getSelectionProvider());
		fSelectionListener.setDocument(getDocumentProvider().getDocument(getEditorInput()));

		initializeActivationCodeTrigger();

		createNavigationActions();
		createAccessibilityActions();
		createActions();

		initializeSourceViewer(getEditorInput());

		/* since 3.2 - undo redo actions should be created after
		 * the source viewer is initialized, so that the undo manager
		 * can obtain its undo context from its document.
		 */
		createUndoRedoActions();

		JFaceResources.getFontRegistry().addListener(fFontPropertyChangeListener);

		IVerticalRuler ruler= getVerticalRuler();
		if (ruler instanceof CompositeRuler)
			updateContributedRulerColumns((CompositeRuler) ruler);

		if (isWordWrapSupported()) {
			setWordWrap(getInitialWordWrapStatus());
		}
	}

	/**
	 * Installs text drag and drop on the given source viewer.
	 *
	 * @param viewer the viewer
	 * @since 3.3
	 */
	protected void installTextDragAndDrop(final ISourceViewer viewer) {
		if (viewer == null || fIsTextDragAndDropInstalled)
			return;

		final IDragAndDropService dndService= getSite().getService(IDragAndDropService.class);
		if (dndService == null)
			return;

		final StyledText st= viewer.getTextWidget();

		// Install drag source
		final ISelectionProvider selectionProvider= viewer.getSelectionProvider();
		final DragSource source= new DragSource(st, DND.DROP_COPY | DND.DROP_MOVE);
		source.setTransfer(TextTransfer.getInstance());
		source.addDragListener(new DragSourceAdapter() {
			String fSelectedText;
			Point fSelection;
			@Override
			public void dragStart(DragSourceEvent event) {
				fTextDragAndDropToken= null;
				try {
					fSelection= st.getSelection();
					event.doit= isLocationSelected(new Point(event.x, event.y));

					ISelection selection= selectionProvider.getSelection();
					if (selection instanceof ITextSelection)
						fSelectedText= ((ITextSelection)selection).getText();
					else // fallback to widget
						fSelectedText= st.getSelectionText();
				} catch (IllegalArgumentException ex) {
					event.doit= false;
				}
			}

			private boolean isLocationSelected(Point point) {
				// FIXME: https://bugs.eclipse.org/bugs/show_bug.cgi?id=260922
				if (isBlockSelectionModeEnabled())
					return false;

				int offset = st.getOffsetAtPoint(point);
				Point p= st.getLocationAtOffset(offset);
				if (p.x > point.x)
					offset--;
				return offset >= fSelection.x && offset < fSelection.y;
			}

			@Override
			public void dragSetData(DragSourceEvent event) {
				event.data= fSelectedText;
				fTextDragAndDropToken= this; // Can be any non-null object
			}

			@Override
			public void dragFinished(DragSourceEvent event) {
				try {
					if (event.detail == DND.DROP_MOVE && validateEditorInputState()) {
						Point newSelection= st.getSelection();
						int length= fSelection.y - fSelection.x;
						int delta= 0;
						if (newSelection.x < fSelection.x)
							delta= length;
						st.replaceTextRange(fSelection.x + delta, length, ""); //$NON-NLS-1$

						if (fTextDragAndDropToken == null) {
							// Move in same editor - end compound change
							IRewriteTarget target= getAdapter(IRewriteTarget.class);
							if (target != null)
								target.endCompoundChange();
						}

					}
				} finally {
					fTextDragAndDropToken= null;
				}
			}
		});

		// Install drag target
		DropTargetListener dropTargetListener= new DropTargetAdapter() {

			private Point fSelection;

			@Override
			public void dragEnter(DropTargetEvent event) {
				fTextDragAndDropToken= null;
				fSelection= st.getSelection();
				if (event.detail == DND.DROP_DEFAULT) {
					if ((event.operations & DND.DROP_MOVE) != 0) {
						event.detail= DND.DROP_MOVE;
					} else if ((event.operations & DND.DROP_COPY) != 0) {
						event.detail= DND.DROP_COPY;
					} else {
						event.detail= DND.DROP_NONE;
					}
				}
			}

			@Override
			public void dragOperationChanged(DropTargetEvent event) {
				if (event.detail == DND.DROP_DEFAULT) {
					if ((event.operations & DND.DROP_MOVE) != 0) {
						event.detail= DND.DROP_MOVE;
					} else if ((event.operations & DND.DROP_COPY) != 0) {
						event.detail= DND.DROP_COPY;
					} else {
						event.detail= DND.DROP_NONE;
					}
				}
			}

			@Override
			public void dragOver(DropTargetEvent event) {
				event.feedback |= DND.FEEDBACK_SCROLL;
			}

			@Override
			public void drop(DropTargetEvent event) {
				try {
					if (fTextDragAndDropToken != null && event.detail == DND.DROP_MOVE) {
						// Move in same editor
						int caretOffset= st.getCaretOffset();
						if (fSelection.x <= caretOffset && caretOffset <= fSelection.y) {
							event.detail= DND.DROP_NONE;
							return;
						}

						// Start compound change
						IRewriteTarget target= getAdapter(IRewriteTarget.class);
						if (target != null)
							target.beginCompoundChange();
					}

					if (!validateEditorInputState()) {
						event.detail= DND.DROP_NONE;
						return;
					}

					String text= (String)event.data;
					if (isBlockSelectionModeEnabled()) {
						// FIXME fix block selection and DND
//						if (fTextDNDColumnSelection != null && fTextDragAndDropToken != null && event.detail == DND.DROP_MOVE) {
//							// DND_MOVE within same editor - remove origin before inserting
//							Rectangle newSelection= st.getColumnSelection();
//							st.replaceColumnSelection(fTextDNDColumnSelection, ""); //$NON-NLS-1$
//							st.replaceColumnSelection(newSelection, text);
//							st.setColumnSelection(newSelection.x, newSelection.y, newSelection.x + fTextDNDColumnSelection.width - fTextDNDColumnSelection.x, newSelection.y + fTextDNDColumnSelection.height - fTextDNDColumnSelection.y);
//						} else {
//							Point newSelection= st.getSelection();
//							st.insert(text);
//							IDocument document= getDocumentProvider().getDocument(getEditorInput());
//							int startLine= st.getLineAtOffset(newSelection.x);
//							int startColumn= newSelection.x - st.getOffsetAtLine(startLine);
//							int endLine= startLine + document.computeNumberOfLines(text);
//							int endColumn= startColumn + TextUtilities.indexOf(document.getLegalLineDelimiters(), text, 0)[0];
//							st.setColumnSelection(startColumn, startLine, endColumn, endLine);
//						}
					} else {
						Point newSelection= st.getSelection();
						try {
							int modelOffset= widgetOffset2ModelOffset(viewer, newSelection.x);
							viewer.getDocument().replace(modelOffset, 0, text);
						} catch (BadLocationException e) {
							return;
						}
						st.setSelectionRange(newSelection.x, text.length());
					}
				} finally {
					fTextDragAndDropToken= null;
				}
			}
		};
		dndService.addMergedDropTarget(st, DND.DROP_MOVE | DND.DROP_COPY, new Transfer[] {TextTransfer.getInstance()}, dropTargetListener);

		fIsTextDragAndDropInstalled= true;
	}

	/**
	 * Uninstalls text drag and drop from the given source viewer.
	 *
	 * @param viewer the viewer
	 * @since 3.3
	 */
	protected void uninstallTextDragAndDrop(ISourceViewer viewer) {
		if (viewer == null || !fIsTextDragAndDropInstalled)
			return;

		final IDragAndDropService dndService= getSite().getService(IDragAndDropService.class);
		if (dndService == null)
			return;

		StyledText st= viewer.getTextWidget();
		dndService.removeMergedDropTarget(st);

		DragSource dragSource= (DragSource)st.getData(DND.DRAG_SOURCE_KEY);
		if (dragSource != null) {
			dragSource.dispose();
			st.setData(DND.DRAG_SOURCE_KEY, null);
		}

		fIsTextDragAndDropInstalled= false;
	}

	/**
	 * Tells whether the editor input should be included when adding object
	 * contributions to this editor's context menu.
	 * <p>
	 * This implementation always returns <code>true</code>.
	 * </p>
	 *
	 * @return <code>true</code> if the editor input should be considered
	 * @since 3.2
	 */
	protected boolean isEditorInputIncludedInContextMenu() {
		return true;
	}

	/**
	 * Initializes the activation code trigger.
	 *
	 * @since 2.1
	 */
	private void initializeActivationCodeTrigger() {
		fActivationCodeTrigger.install();
		fActivationCodeTrigger.setScopes(fKeyBindingScopes);
	}

	/**
	 * Initializes the given viewer's font.
	 *
	 * @param viewer the viewer
	 * @since 2.0
	 */
	private void initializeViewerFont(ISourceViewer viewer) {

		boolean isSharedFont= true;
		Font font= null;
		String symbolicFontName= getSymbolicFontName();

		if (symbolicFontName != null)
			font= JFaceResources.getFont(symbolicFontName);
		else if (fPreferenceStore != null) {
			// Backward compatibility
			if (fPreferenceStore.contains(JFaceResources.TEXT_FONT) && !fPreferenceStore.isDefault(JFaceResources.TEXT_FONT)) {
				FontData data= PreferenceConverter.getFontData(fPreferenceStore, JFaceResources.TEXT_FONT);

				if (data != null) {
					isSharedFont= false;
					font= new Font(viewer.getTextWidget().getDisplay(), data);
				}
			}
		}
		if (font == null)
			font= JFaceResources.getTextFont();

		if (!font.equals(fSourceViewer.getTextWidget().getFont())) {
			setFont(viewer, font);

			disposeFont();
			if (!isSharedFont)
				fFont= font;
		} else if (!isSharedFont) {
			font.dispose();
		}
	}

	/**
	 * Disposes of the non-shared font.
	 *
	 * @since 3.5
	 */
	private void disposeFont() {
		if (fFont != null) {
			fFont.dispose();
			fFont= null;
		}
	}

	/**
	 * Sets the font for the given viewer sustaining selection and scroll position.
	 *
	 * @param sourceViewer the source viewer
	 * @param font the font
	 * @since 2.0
	 */
	private void setFont(ISourceViewer sourceViewer, Font font) {
		if (sourceViewer.getDocument() != null) {

			ISelectionProvider provider= sourceViewer.getSelectionProvider();
			ISelection selection= provider.getSelection();
			int topIndex= sourceViewer.getTopIndex();

			StyledText styledText= sourceViewer.getTextWidget();
			Control parent= styledText;
			if (sourceViewer instanceof ITextViewerExtension) {
				ITextViewerExtension extension= (ITextViewerExtension) sourceViewer;
				parent= extension.getControl();
			}

			parent.setRedraw(false);

			styledText.setFont(font);

			if (fVerticalRuler instanceof IVerticalRulerExtension) {
				IVerticalRulerExtension e= (IVerticalRulerExtension) fVerticalRuler;
				e.setFont(font);
			}

			provider.setSelection(selection);
			sourceViewer.setTopIndex(topIndex);

			if (parent instanceof Composite) {
				Composite composite= (Composite) parent;
				composite.layout(true);
			}

			parent.setRedraw(true);


		} else {

			StyledText styledText= sourceViewer.getTextWidget();
			styledText.setFont(font);

			if (fVerticalRuler instanceof IVerticalRulerExtension) {
				IVerticalRulerExtension e= (IVerticalRulerExtension) fVerticalRuler;
				e.setFont(font);
			}
		}
	}

	private void initializeZoomGestures(Control rulerControl, final ISourceViewer sourceViewer) {
		final StyledText styledText= sourceViewer.getTextWidget();
		GestureListener gestureListener= new GestureListener() {
			private Font fMagnificationStartFont;
			private int fLastHeight= -1;

			@Override
			public void gesture(GestureEvent e) {
				if (e.detail == SWT.GESTURE_BEGIN) {
					fMagnificationStartFont= styledText.getFont();
				} else if (e.detail == SWT.GESTURE_END) {
					fMagnificationStartFont= null;
					updateStatusField(ITextEditorActionConstants.STATUS_CATEGORY_INPUT_POSITION);
				} else if (e.detail == SWT.GESTURE_ROTATE) {
					if (Math.abs(e.rotation) > 45) {
						fMagnificationStartFont= null; // don't observe magnify events after reset
						initializeViewerFont(fSourceViewer);
						updateCaret();
						IStatusField statusField= getStatusField(ITextEditorActionConstants.STATUS_CATEGORY_INPUT_POSITION);
						if (statusField != null) {
							int newHeight= styledText.getFont().getFontData()[0].getHeight();
							statusField.setText(NLSUtility.format(EditorMessages.Editor_font_reset_message, Integer.valueOf(newHeight)));
						}
					}
				} else if (e.detail == SWT.GESTURE_MAGNIFY && fMagnificationStartFont != null) {
					FontData fontData= fMagnificationStartFont.getFontData()[0];
					int startHeight= fontData.getHeight();
					int newHeight= Math.max(1, (int) (startHeight * e.magnification));
					if (newHeight != fLastHeight) {
						fLastHeight= newHeight;
						fontData.setHeight(newHeight);
						Font newFont= new Font(fMagnificationStartFont.getDevice(), fontData);
						setFont(sourceViewer, newFont);
						disposeFont();
						updateCaret();
						IStatusField statusField= getStatusField(ITextEditorActionConstants.STATUS_CATEGORY_INPUT_POSITION);
						if (statusField != null) {
							statusField.setText(NLSUtility.format(EditorMessages.Editor_font_zoom_message, new Object[] { Integer.valueOf(startHeight), Integer.valueOf(newHeight) }));
						}
					}
				}
			}
		};
		styledText.addGestureListener(gestureListener);
		rulerControl.addGestureListener(gestureListener);
	}

	/**
	 * Creates a color from the information stored in the given preference store.
	 * Returns <code>null</code> if there is no such information available.
	 *
	 * @param store the store to read from
	 * @param key the key used for the lookup in the preference store
	 * @param display the display used create the color
	 * @return the created color according to the specification in the preference store
	 * @since 2.0
	 */
	private Color createColor(IPreferenceStore store, String key, Display display) {

		RGB rgb= null;

		if (store.contains(key)) {

			if (store.isDefault(key))
				rgb= PreferenceConverter.getDefaultColor(store, key);
			else
				rgb= PreferenceConverter.getColor(store, key);

			if (rgb != null)
				return new Color(display, rgb);
		}

		return null;
	}

	/**
	 * Initializes the fore- and background colors of the given viewer for both
	 * normal and selected text.
	 *
	 * @param viewer the viewer to be initialized
	 * @since 2.0
	 */
	protected void initializeViewerColors(ISourceViewer viewer) {

		IPreferenceStore store= getPreferenceStore();
		if (store != null) {

			StyledText styledText= viewer.getTextWidget();

			// ----------- foreground color --------------------
			Color color= store.getBoolean(PREFERENCE_COLOR_FOREGROUND_SYSTEM_DEFAULT)
				? null
				: createColor(store, PREFERENCE_COLOR_FOREGROUND, styledText.getDisplay());
			styledText.setForeground(color);

			// ---------- background color ----------------------
			color= store.getBoolean(PREFERENCE_COLOR_BACKGROUND_SYSTEM_DEFAULT)
				? null
				: createColor(store, PREFERENCE_COLOR_BACKGROUND, styledText.getDisplay());
			styledText.setBackground(color);

			// ----------- selection foreground color --------------------
			color= store.getBoolean(PREFERENCE_COLOR_SELECTION_FOREGROUND_SYSTEM_DEFAULT)
				? null
				: createColor(store, PREFERENCE_COLOR_SELECTION_FOREGROUND, styledText.getDisplay());
			styledText.setSelectionForeground(color);


			// ---------- selection background color ----------------------
			color= store.getBoolean(PREFERENCE_COLOR_SELECTION_BACKGROUND_SYSTEM_DEFAULT)
				? null
				: createColor(store, PREFERENCE_COLOR_SELECTION_BACKGROUND, styledText.getDisplay());
			styledText.setSelectionBackground(color);

		}
	}

	/**
	 * Initializes the background color used for highlighting the document ranges
	 * defining search scopes.
	 *
	 * @param viewer the viewer to initialize
	 * @since 2.0
	 */
	private void initializeFindScopeColor(ISourceViewer viewer) {

		IPreferenceStore store= getPreferenceStore();
		if (store != null) {

			StyledText styledText= viewer.getTextWidget();

			Color color= createColor(store, PREFERENCE_COLOR_FIND_SCOPE, styledText.getDisplay());

			IFindReplaceTarget target= viewer.getFindReplaceTarget();
			if (target instanceof IFindReplaceTargetExtension)
				((IFindReplaceTargetExtension) target).setScopeHighlightColor(color);

		}
	}


	/**
	 * Initializes the editor's source viewer based on the given editor input.
	 *
	 * @param input the editor input to be used to initialize the source viewer
	 */
	private void initializeSourceViewer(IEditorInput input) {

		IDocumentProvider documentProvider= getDocumentProvider();
		IAnnotationModel model= documentProvider.getAnnotationModel(input);
		IDocument document= documentProvider.getDocument(input);

		if (document != null) {
			fSourceViewer.setDocument(document, model);
			fSourceViewer.setEditable(isEditable());
			fSourceViewer.showAnnotations(model != null);
		}

		if (fElementStateListener instanceof IElementStateListenerExtension) {
			boolean isStateValidated= false;
			if (documentProvider instanceof IDocumentProviderExtension)
				isStateValidated= ((IDocumentProviderExtension)documentProvider).isStateValidated(input);

			IElementStateListenerExtension extension= (IElementStateListenerExtension) fElementStateListener;
			extension.elementStateValidationChanged(input, isStateValidated);
		}

		if (fInitialCaret == null)
			fInitialCaret= fSourceViewer.getTextWidget().getCaret();

		if (fIsOverwriting)
			fSourceViewer.getTextWidget().invokeAction(ST.TOGGLE_OVERWRITE);
		handleInsertModeChanged();

		if (isTabsToSpacesConversionEnabled())
			installTabsToSpacesConverter();

		if (fSourceViewer instanceof ITextViewerExtension8) {
			IPreferenceStore store= getPreferenceStore();
			EnrichMode mode= store != null ? convertEnrichModePreference(store.getInt(PREFERENCE_HOVER_ENRICH_MODE)) : EnrichMode.AFTER_DELAY;
			((ITextViewerExtension8)fSourceViewer).setHoverEnrichMode(mode);
		}

		if (fSourceViewer instanceof ISourceViewerExtension5)
			installCodeMiningProviders();
	}

	/**
	 * Install codemining providers.
	 *
	 * @since 3.11
	 */
	protected void installCodeMiningProviders() {
		ICodeMiningProvider[] providers = TextEditorPlugin.getDefault().getCodeMiningProviderRegistry()
				.getProviders(this.getSourceViewer(), this);
		((ISourceViewerExtension5) fSourceViewer).setCodeMiningProviders(providers);
	}

	/**
	 * Converts the {link #PREFERENCE_HOVER_ENRICH_MODE} preference value to
	 * {@link org.eclipse.jface.text.ITextViewerExtension8.EnrichMode}.
	 *
	 * @param mode the preference value
	 * @return the enrich mode, can be <code>null</code>
	 * @since 3.4
	 */
	private EnrichMode convertEnrichModePreference(int mode) {
		switch (mode) {
			case -1:
				return null;
			case 0:
				return EnrichMode.AFTER_DELAY;
			case 1:
				return EnrichMode.IMMEDIATELY;
			case 2:
				return EnrichMode.ON_CLICK;
			default:
				Assert.isLegal(false);
			return null;
		}
	}

	/**
	 * Initializes the editor's title based on the given editor input.
	 * <p>
	 * <strong>Note:</strong> We use the editor's image instead of the image from the
	 * editor input to distinguish situations where the same editor input is
	 * opened in different kinds of editors.
	 * </p>
	 *
	 * @param input the editor input to be used
	 */
	private void initializeTitle(IEditorInput input) {

		Image oldImage= fTitleImage;
		fTitleImage= null;
		String title= ""; //$NON-NLS-1$

		if (input != null) {
			IEditorRegistry editorRegistry= PlatformUI.getWorkbench().getEditorRegistry();
			IEditorDescriptor editorDesc= editorRegistry.findEditor(getSite().getId());
			ImageDescriptor imageDesc= editorDesc != null ? editorDesc.getImageDescriptor() : null;

			fTitleImage= imageDesc != null ? imageDesc.createImage() : null;
			title= input.getName();
		}

		setTitleImage(fTitleImage);
		setPartName(title);

		firePropertyChange(PROP_DIRTY);

		if (oldImage != null && !oldImage.isDisposed())
			oldImage.dispose();
	}

	/**
	 * Hook method for setting the document provider for the given input.
	 * This default implementation does nothing. Clients may
	 * reimplement.
	 *
	 * @param input the input of this editor.
	 * @since 3.0
	 */
	protected void setDocumentProvider(IEditorInput input) {
	}

	/**
	 * If there is no explicit document provider set, the implicit one is
	 * re-initialized based on the given editor input.
	 *
	 * @param input the editor input.
	 */
	private void updateDocumentProvider(IEditorInput input) {

		IProgressMonitor rememberedProgressMonitor= null;

		IDocumentProvider provider= getDocumentProvider();
		if (provider != null) {
			provider.removeElementStateListener(fElementStateListener);
			if (provider instanceof IDocumentProviderExtension2) {
				IDocumentProviderExtension2 extension= (IDocumentProviderExtension2) provider;
				rememberedProgressMonitor= extension.getProgressMonitor();
				extension.setProgressMonitor(null);
			}
		}

		setDocumentProvider(input);

		provider= getDocumentProvider();
		if (provider != null) {
			provider.addElementStateListener(fElementStateListener);
			if (provider instanceof IDocumentProviderExtension2) {
				IDocumentProviderExtension2 extension= (IDocumentProviderExtension2) provider;
				extension.setProgressMonitor(rememberedProgressMonitor);
			}
		}
	}

	/**
	 * Called directly from <code>setInput</code> and from within a workspace
	 * runnable from <code>init</code>, this method does the actual setting
	 * of the editor input. Closes the editor if <code>input</code> is
	 * <code>null</code>. Disconnects from any previous editor input and its
	 * document provider and connects to the new one.
	 * <p>
	 * Subclasses may extend.
	 * </p>
	 *
	 * @param input the input to be set
	 * @exception CoreException if input cannot be connected to the document
	 *            provider
	 */
	protected void doSetInput(IEditorInput input) throws CoreException {
		ISaveablesLifecycleListener listener= getSite().getService(ISaveablesLifecycleListener.class);
		if (listener == null)
			fSavable= null;

		if (input == null) {
			close(isSaveOnCloseNeeded());

			if (fSavable != null) {
				listener.handleLifecycleEvent(new SaveablesLifecycleEvent(this,	SaveablesLifecycleEvent.POST_CLOSE,	getSaveables(), false));
				fSavable.disconnectEditor();
				fSavable= null;
			}

		} else {
			boolean mustSendLifeCycleEvent= false;
			if (fSavable != null) {
				listener.handleLifecycleEvent(new SaveablesLifecycleEvent(this,	SaveablesLifecycleEvent.POST_CLOSE,	getSaveables(), false));
				fSavable.disconnectEditor();
				fSavable= null;
				mustSendLifeCycleEvent= true;
			}

			IEditorInput oldInput= getEditorInput();
			if (oldInput != null)
				getDocumentProvider().disconnect(oldInput);

			super.setInput(input);

			updateDocumentProvider(input);

			IDocumentProvider provider= getDocumentProvider();
			if (provider == null) {
				IStatus s= new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, IStatus.OK, EditorMessages.Editor_error_no_provider, null);
				throw new CoreException(s);
			}

			provider.connect(input);

			initializeTitle(input);

			if (fSourceViewer != null) {
				initializeSourceViewer(input);

				// Reset the undo context for the undo and redo action handlers
				IAction undoAction= getAction(ITextEditorActionConstants.UNDO);
				IAction redoAction= getAction(ITextEditorActionConstants.REDO);
				boolean areOperationActionHandlersInstalled= undoAction instanceof OperationHistoryActionHandler && redoAction instanceof OperationHistoryActionHandler;
				IUndoContext undoContext= getUndoContext();
				if (undoContext != null && areOperationActionHandlersInstalled) {
					((OperationHistoryActionHandler)undoAction).setContext(undoContext);
					((OperationHistoryActionHandler)redoAction).setContext(undoContext);
				} else {
					createUndoRedoActions();
				}
			}

			if (fIsOverwriting)
				toggleOverwriteMode();
			setInsertMode(getLegalInsertModes().get(0));
			updateCaret();

			updateStatusField(ITextEditorActionConstants.STATUS_CATEGORY_ELEMENT_STATE);

			if (fSelectionListener != null)
				fSelectionListener.setDocument(getDocumentProvider().getDocument(input));

			IVerticalRuler ruler= getVerticalRuler();
			if (ruler instanceof CompositeRuler)
				updateContributedRulerColumns((CompositeRuler) ruler);

			// Send savable life-cycle if needed.
			if (mustSendLifeCycleEvent && listener != null)
				listener.handleLifecycleEvent(new SaveablesLifecycleEvent(this,	SaveablesLifecycleEvent.POST_OPEN, getSaveables(), false));

		}

	}

	/**
	 * Returns this editor's viewer's undo manager undo context.
	 *
	 * @return the undo context or <code>null</code> if not available
	 * @since 3.1
	 */
	private IUndoContext getUndoContext() {
		if (fSourceViewer instanceof ITextViewerExtension6) {
			IUndoManager undoManager= ((ITextViewerExtension6)fSourceViewer).getUndoManager();
			if (undoManager instanceof IUndoManagerExtension)
				return ((IUndoManagerExtension)undoManager).getUndoContext();
		}
		return null;
	}

	@Override
	protected final void setInputWithNotify(IEditorInput input) {
		try {

			doSetInput(input);

			/*
			 * The following bugs explain why we fire this property change:
			 * 	https://bugs.eclipse.org/bugs/show_bug.cgi?id=90283
			 * 	https://bugs.eclipse.org/bugs/show_bug.cgi?id=92049
			 * 	https://bugs.eclipse.org/bugs/show_bug.cgi?id=92286
			 */
			firePropertyChange(IEditorPart.PROP_INPUT);

		} catch (CoreException x) {
			String title= EditorMessages.Editor_error_setinput_title;
			String msg= EditorMessages.Editor_error_setinput_message;
			Shell shell= getSite().getShell();
			ErrorDialog.openError(shell, title, msg, x.getStatus());
		}
	}

	@Override
	public final void setInput(IEditorInput input) {
		setInputWithNotify(input);
	}

	/*
	 * @see ITextEditor#close
	 */
	@Override
	public void close(final boolean save) {

		enableSanityChecking(false);

		Display display= getSite().getShell().getDisplay();
		display.asyncExec(() -> {
			if (fSourceViewer != null)
				getSite().getPage().closeEditor(AbstractTextEditor.this, save);
		});
	}

	/**
	 * The <code>AbstractTextEditor</code> implementation of this
	 * <code>IWorkbenchPart</code> method may be extended by subclasses.
	 * Subclasses must call <code>super.dispose()</code>.
	 * <p>
	 * Note that many methods may return <code>null</code> after the editor is
	 * disposed.
	 * </p>
	 */
	@Override
	public void dispose() {

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

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

		disposeFont();

		disposeNonDefaultCaret();
		fInitialCaret= null;

		if (fFontPropertyChangeListener != null) {
			JFaceResources.getFontRegistry().removeListener(fFontPropertyChangeListener);
			if (fPreferenceStore != null)
				fPreferenceStore.removePropertyChangeListener(fFontPropertyChangeListener);
			fFontPropertyChangeListener= null;
		}

		if (fPropertyChangeListener != null) {
			if (fPreferenceStore != null) {
				fPreferenceStore.removePropertyChangeListener(fPropertyChangeListener);
				fPreferenceStore= null;
			}
			fPropertyChangeListener= null;
		}

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

		if (fSelectionListener != null)  {
			fSelectionListener.uninstall(getSelectionProvider());
			fSelectionListener= null;
		}

		if (fSavable != null) {
			fSavable.disconnectEditor();
			fSavable= null;
		}

		disposeDocumentProvider();

		if (fSourceViewer != null) {

			if (fTextListener != null) {
				fSourceViewer.removeTextListener(fTextListener);
				fSourceViewer.removeTextInputListener(fTextListener);
				fTextListener= null;
			}

			uninstallTabsToSpacesConverter();

			fTextInputListener= null;
			fSelectionProvider= null;
			fSourceViewer= null;
		}

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

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

		if (fActions != null) {
			registerUndoRedoAction(ITextEditorActionConstants.UNDO, null);
			registerUndoRedoAction(ITextEditorActionConstants.REDO, null);
			fActions.clear();
			fActions= null;
		}

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

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

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

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

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

		if (fEditorStatusLine != null)
			fEditorStatusLine= null;

		if (fConfiguration != null)
			fConfiguration= null;

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

		if (fVerticalRuler != null)
			fVerticalRuler= null;

		IOperationHistory history= OperationHistoryFactory.getOperationHistory();
		if (history != null) {
			if (fNonLocalOperationApprover != null)
				history.removeOperationApprover(fNonLocalOperationApprover);
			if (fLinearUndoViolationApprover != null)
				history.removeOperationApprover(fLinearUndoViolationApprover);
		}
		fNonLocalOperationApprover= null;
		fLinearUndoViolationApprover= null;

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

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

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

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

		super.dispose();
	}

	/**
	 * Disposes of the connection with the document provider. Subclasses
	 * may extend.
	 *
	 * @since 3.0
	 */
	protected void disposeDocumentProvider() {
		IDocumentProvider provider= getDocumentProvider();
		if (provider != null) {

			IEditorInput input= getEditorInput();
			if (input != null)
				provider.disconnect(input);

			if (fElementStateListener != null) {
				provider.removeElementStateListener(fElementStateListener);
				fElementStateListener= null;
			}

		}
		fExplicitDocumentProvider= null;
	}

	/**
	 * Determines whether the given preference change affects the editor's
	 * presentation. This implementation always returns <code>false</code>.
	 * May be reimplemented by subclasses.
	 *
	 * @param event the event which should be investigated
	 * @return <code>true</code> if the event describes a preference change affecting the editor's presentation
	 * @since 2.0
	 */
	protected boolean affectsTextPresentation(PropertyChangeEvent event) {
		return false;
	}

	/**
	 * Returns the symbolic font name for this editor as defined in XML.
	 *
	 * @return a String with the symbolic font name or <code>null</code> if
	 *         none is defined
	 * @since 2.1
	 */
	/*package*/ String getSymbolicFontName() {
		if (getConfigurationElement() != null)
			return getConfigurationElement().getAttribute("symbolicFontName"); //$NON-NLS-1$
		return null;
	}

	/**
	 * Returns the property preference key for the editor font.
	 * <p>
	 * If the editor is defined with a <code>symbolicFontName </code> then this name is returned and
	 * the font is looked up in the JFace resource registry. Otherwise,
	 * {@link JFaceResources#TEXT_FONT} is returned and the font is looked up in this editor's
	 * preference store.
	 * </p>
	 *
	 * @return a String with the key
	 * @since 2.1
	 */
	protected final String getFontPropertyPreferenceKey() {
		String symbolicFontName= getSymbolicFontName();
		if (symbolicFontName != null)
			return symbolicFontName;
		return JFaceResources.TEXT_FONT;
	}

	/**
	 * Handles a property change event describing a change of the editor's
	 * preference store and updates the preference related editor properties.
	 * <p>
	 * Subclasses may extend.
	 * </p>
	 *
	 * @param event the property change event
	 */
	protected void handlePreferenceStoreChanged(PropertyChangeEvent event) {

		if (fSourceViewer == null)
			return;

		String property= event.getProperty();

		if (getFontPropertyPreferenceKey().equals(property))
			// There is a separate handler for font preference changes
			return;

		if (property != null) {
			switch (property) {
			case PREFERENCE_COLOR_FOREGROUND:
			case PREFERENCE_COLOR_FOREGROUND_SYSTEM_DEFAULT:
			case PREFERENCE_COLOR_BACKGROUND:
			case PREFERENCE_COLOR_BACKGROUND_SYSTEM_DEFAULT:
			case PREFERENCE_COLOR_SELECTION_FOREGROUND:
			case PREFERENCE_COLOR_SELECTION_FOREGROUND_SYSTEM_DEFAULT:
			case PREFERENCE_COLOR_SELECTION_BACKGROUND:
			case PREFERENCE_COLOR_SELECTION_BACKGROUND_SYSTEM_DEFAULT:
				initializeViewerColors(fSourceViewer);
				break;
			case PREFERENCE_COLOR_FIND_SCOPE:
				initializeFindScopeColor(fSourceViewer);
				break;
			case PREFERENCE_USE_CUSTOM_CARETS:
			case PREFERENCE_WIDE_CARET:
				updateCaret();
				break;
			default:
				break;
			}
		}

		if (affectsTextPresentation(event))
			fSourceViewer.invalidateTextPresentation();

		if (PREFERENCE_HYPERLINKS_ENABLED.equals(property)) {
			if (fSourceViewer instanceof ITextViewerExtension6) {
				IHyperlinkDetector[] detectors= getSourceViewerConfiguration().getHyperlinkDetectors(fSourceViewer);
				int stateMask= getSourceViewerConfiguration().getHyperlinkStateMask(fSourceViewer);
				ITextViewerExtension6 textViewer6= (ITextViewerExtension6)fSourceViewer;
				textViewer6.setHyperlinkDetectors(detectors, stateMask);
			}
			return;
		}

		if (PREFERENCE_HYPERLINK_KEY_MODIFIER.equals(property)) {
			if (fSourceViewer instanceof ITextViewerExtension6) {
				ITextViewerExtension6 textViewer6= (ITextViewerExtension6)fSourceViewer;
				IHyperlinkDetector[] detectors= getSourceViewerConfiguration().getHyperlinkDetectors(fSourceViewer);
				int stateMask= getSourceViewerConfiguration().getHyperlinkStateMask(fSourceViewer);
				textViewer6.setHyperlinkDetectors(detectors, stateMask);
			}
			return;
		}

		if (PREFERENCE_RULER_CONTRIBUTIONS.equals(property)) {
			String[] difference= StringSetSerializer.getDifference((String) event.getOldValue(), (String) event.getNewValue());
			IColumnSupport support= getAdapter(IColumnSupport.class);
			for (String element : difference) {
				RulerColumnDescriptor desc= RulerColumnRegistry.getDefault().getColumnDescriptor(element);
				if (desc != null &&  support.isColumnSupported(desc)) {
					boolean newState= !support.isColumnVisible(desc);
					support.setColumnVisible(desc, newState);
				}
			}
			return;
		}

		if (PREFERENCE_SHOW_WHITESPACE_CHARACTERS.equals(property) ||
				PREFERENCE_SHOW_LEADING_SPACES.equals(property) ||
				PREFERENCE_SHOW_ENCLOSED_SPACES.equals(property) ||
				PREFERENCE_SHOW_TRAILING_SPACES.equals(property) ||
				PREFERENCE_SHOW_LEADING_IDEOGRAPHIC_SPACES.equals(property) ||
				PREFERENCE_SHOW_ENCLOSED_IDEOGRAPHIC_SPACES.equals(property) ||
				PREFERENCE_SHOW_TRAILING_IDEOGRAPHIC_SPACES.equals(property) ||
				PREFERENCE_SHOW_LEADING_TABS.equals(property) ||
				PREFERENCE_SHOW_ENCLOSED_TABS.equals(property) ||
				PREFERENCE_SHOW_TRAILING_TABS.equals(property) ||
				PREFERENCE_SHOW_CARRIAGE_RETURN.equals(property) ||
				PREFERENCE_SHOW_LINE_FEED.equals(property) ||
				PREFERENCE_WHITESPACE_CHARACTER_ALPHA_VALUE.equals(property)) {
			IAction action= getAction(ITextEditorActionConstants.SHOW_WHITESPACE_CHARACTERS);
			if (action instanceof IUpdate)
				((IUpdate)action).update();
			return;
		}

		if (PREFERENCE_TEXT_DRAG_AND_DROP_ENABLED.equals(property)) {
			IPreferenceStore store= getPreferenceStore();
			if (store != null && store.getBoolean(PREFERENCE_TEXT_DRAG_AND_DROP_ENABLED))
				installTextDragAndDrop(getSourceViewer());
			else
				uninstallTextDragAndDrop(getSourceViewer());
			return;
		}

		if (PREFERENCE_HOVER_ENRICH_MODE.equals(property)) {
			if (fSourceViewer instanceof ITextViewerExtension8) {
				IPreferenceStore store= getPreferenceStore();
				if (store != null) {
					((ITextViewerExtension8)fSourceViewer).setHoverEnrichMode(convertEnrichModePreference(store.getInt(PREFERENCE_HOVER_ENRICH_MODE)));
				}
			}
			return;
		}

	}

	/**
	 * Returns the progress monitor related to this editor. It should not be
	 * necessary to extend this method.
	 *
	 * @return the progress monitor related to this editor
	 * @since 2.1
	 */
	protected IProgressMonitor getProgressMonitor() {

		IProgressMonitor pm= null;

		IStatusLineManager manager= getStatusLineManager();
		if (manager != null)
			pm= manager.getProgressMonitor();

		return pm != null ? pm : new NullProgressMonitor();
	}

	/**
	 * Handles an external change of the editor's input element. Subclasses may
	 * extend.
	 */
	protected void handleEditorInputChanged() {

		String title;
		String msg;
		Shell shell= getSite().getShell();

		final IDocumentProvider provider= getDocumentProvider();
		if (provider == null) {
			// fix for http://dev.eclipse.org/bugs/show_bug.cgi?id=15066
			close(false);
			return;
		}

		final IEditorInput input= getEditorInput();
		final String inputName= input.getToolTipText();

		if (provider.isDeleted(input)) {

			if (isSaveAsAllowed()) {

				title= EditorMessages.Editor_error_activated_deleted_save_title;
				msg= NLSUtility.format(EditorMessages.Editor_error_activated_deleted_save_message, inputName);

				String[] buttons= {
						EditorMessages.Editor_error_activated_deleted_save_button_save,
						EditorMessages.Editor_error_activated_deleted_save_button_close,
				};

				MessageDialog dialog= new MessageDialog(shell, title, null, msg, MessageDialog.QUESTION, buttons, 0);

				if (dialog.open() == 0) {
					IProgressMonitor pm= getProgressMonitor();
					try {
						performSaveAs(pm);
						if (pm.isCanceled())
							handleEditorInputChanged();
					} finally {
						pm.done();
					}
				} else {
					close(false);
				}

			} else {

				title= EditorMessages.Editor_error_activated_deleted_close_title;
				msg= NLSUtility.format(EditorMessages.Editor_error_activated_deleted_close_message, inputName);
				if (MessageDialog.openConfirm(shell, title, msg))
					close(false);
			}

		} else if (fHasBeenActivated) {

			title= EditorMessages.Editor_error_activated_outofsync_title;
			msg= NLSUtility.format(EditorMessages.Editor_error_activated_outofsync_message, inputName);

			if (MessageDialog.open(MessageDialog.QUESTION, shell, title, msg, SWT.NONE,
					EditorMessages.Editor_error_replace_button_label,
					EditorMessages.Editor_error_dontreplace_button_label) == 0) {

				try {
					if (provider instanceof IDocumentProviderExtension) {
						IDocumentProviderExtension extension= (IDocumentProviderExtension) provider;
						extension.synchronize(input);
					} else {
						doSetInput(input);
					}
				} catch (CoreException x) {
					IStatus status= x.getStatus();
					if (status == null || status.getSeverity() != IStatus.CANCEL) {
						title= EditorMessages.Editor_error_refresh_outofsync_title;
						msg= NLSUtility.format(EditorMessages.Editor_error_refresh_outofsync_message, inputName);
						ErrorDialog.openError(shell, title, msg, x.getStatus());
					}
				}
			} else if (!isDirty()) {
				// Trigger dummy change to dirty the editor, for details see https://bugs.eclipse.org/344101 .
				try {
					IDocument document= provider.getDocument(input);
					if (document != null)
						document.replace(0, 0, ""); //$NON-NLS-1$
				} catch (BadLocationException e) {
					// Ignore as this can't happen
				}
			}
		}
	}

	/**
	 * The <code>AbstractTextEditor</code> implementation of this
	 * <code>IEditorPart</code> method calls <code>performSaveAs</code>.
	 * Subclasses may reimplement.
	 */
	@Override
	public void doSaveAs() {
		IProgressMonitor monitor= getProgressMonitor();
		try {
			/*
			 * 1GEUSSR: ITPUI:ALL - User should never loose changes made in the editors.
			 * Changed Behavior to make sure that if called inside a regular save (because
			 * of deletion of input element) there is a way to report back to the caller.
			 */
			performSaveAs(monitor);
		} finally {
			monitor.done();
		}
	}

	/**
	 * Performs a save as and reports the result state back to the
	 * given progress monitor. This default implementation does nothing.
	 * Subclasses may reimplement.
	 *
	 * @param progressMonitor the progress monitor for communicating result state or <code>null</code>
	 */
	protected void performSaveAs(IProgressMonitor progressMonitor) {
	}

	/**
	 * The <code>AbstractTextEditor</code> implementation of this
	 * <code>IEditorPart</code> method may be extended by subclasses.
	 *
	 * @param progressMonitor the progress monitor for communicating result state or <code>null</code>
	 */
	@Override
	public void doSave(IProgressMonitor progressMonitor) {

		IDocumentProvider p= getDocumentProvider();
		if (p == null)
			return;

		if (p.isDeleted(getEditorInput())) {

			if (isSaveAsAllowed()) {

				/*
				 * 1GEUSSR: ITPUI:ALL - User should never loose changes made in the editors.
				 * Changed Behavior to make sure that if called inside a regular save (because
				 * of deletion of input element) there is a way to report back to the caller.
				 */
				performSaveAs(progressMonitor);

			} else {

				Shell shell= getSite().getShell();
				String title= EditorMessages.Editor_error_save_deleted_title;
				String msg= EditorMessages.Editor_error_save_deleted_message;
				MessageDialog.openError(shell, title, msg);
			}

		} else {
			updateState(getEditorInput());
			validateState(getEditorInput());
			performSave(false, progressMonitor);
		}
	}

	/**
	 * Enables/disables sanity checking.
	 * @param enable <code>true</code> if sanity checking should be enabled, <code>false</code> otherwise
	 * @since 2.0
	 */
	protected void enableSanityChecking(boolean enable) {
		synchronized (this) {
			fIsSanityCheckEnabled= enable;
		}
	}

	/**
	 * Checks the state of the given editor input if sanity checking is enabled.
	 * @param input the editor input whose state is to be checked
	 * @since 2.0
	 */
	protected void safelySanityCheckState(IEditorInput input) {
		boolean enabled= false;

		synchronized (this) {
			enabled= fIsSanityCheckEnabled;
		}

		if (enabled)
			sanityCheckState(input);
	}

	/**
	 * Checks the state of the given editor input.
	 * @param input the editor input whose state is to be checked
	 * @since 2.0
	 */
	protected void sanityCheckState(IEditorInput input) {

		IDocumentProvider p= getDocumentProvider();
		if (p == null)
			return;

		if (p instanceof IDocumentProviderExtension3)  {

			IDocumentProviderExtension3 p3= (IDocumentProviderExtension3) p;

			long stamp= p.getModificationStamp(input);
			if (stamp != fModificationStamp) {
				fModificationStamp= stamp;
				if (!p3.isSynchronized(input))
					handleEditorInputChanged();
			}

		} else  {

			if (fModificationStamp == -1)
				fModificationStamp= p.getSynchronizationStamp(input);

			long stamp= p.getModificationStamp(input);
			if (stamp != fModificationStamp) {
				fModificationStamp= stamp;
				if (stamp != p.getSynchronizationStamp(input))
					handleEditorInputChanged();
			}
		}

		updateState(getEditorInput());
		updateStatusField(ITextEditorActionConstants.STATUS_CATEGORY_ELEMENT_STATE);
	}

	/**
	 * Enables/disables state validation.
	 * @param enable <code>true</code> if state validation should be enabled, <code>false</code> otherwise
	 * @since 2.1
	 */
	protected void enableStateValidation(boolean enable) {
		synchronized (this) {
			fIsStateValidationEnabled= enable;
		}
	}

	/**
	 * Validates the state of the given editor input. The predominate intent
	 * of this method is to take any action probably necessary to ensure that
	 * the input can persistently be changed.
	 *
	 * @param input the input to be validated
	 * @since 2.0
	 */
	protected void validateState(IEditorInput input) {

		IDocumentProvider provider= getDocumentProvider();
		if (! (provider instanceof IDocumentProviderExtension))
			return;

		IDocumentProviderExtension extension= (IDocumentProviderExtension) provider;

		try {

			extension.validateState(input, getSite().getShell());

		} catch (CoreException x) {
			IStatus status= x.getStatus();
			if (status == null || status.getSeverity() != IStatus.CANCEL) {
				Bundle bundle= Platform.getBundle(PlatformUI.PLUGIN_ID);
				ILog log= Platform.getLog(bundle);
				log.log(x.getStatus());

				Shell shell= getSite().getShell();
				String title= EditorMessages.Editor_error_validateEdit_title;
				String msg= EditorMessages.Editor_error_validateEdit_message;
				ErrorDialog.openError(shell, title, msg, x.getStatus());
			}
			return;
		}

		if (fSourceViewer != null)
			fSourceViewer.setEditable(isEditable());

		updateStateDependentActions();
	}

	@Override
	public boolean validateEditorInputState() {

		boolean enabled= false;

		synchronized (this) {
			enabled= fIsStateValidationEnabled;
		}

		if (enabled) {

			ISourceViewer viewer= fSourceViewer;
			if (viewer == null)
				return false;

			fTextInputListener.inputChanged= false;
			viewer.addTextInputListener(fTextInputListener);

			try {
				final IEditorInput input= getEditorInput();
				BusyIndicator.showWhile(getSite().getShell().getDisplay(), () -> validateState(input));
				sanityCheckState(input);
				return !isEditorInputReadOnly() && !fTextInputListener.inputChanged;

			} finally {
				viewer.removeTextInputListener(fTextInputListener);
			}

		}

		return !isEditorInputReadOnly();
	}

	/**
	 * Updates the state of the given editor input such as read-only flag.
	 *
	 * @param input the input to be validated
	 * @since 2.0
	 */
	protected void updateState(IEditorInput input) {
		IDocumentProvider provider= getDocumentProvider();
		if (provider instanceof IDocumentProviderExtension) {
			IDocumentProviderExtension extension= (IDocumentProviderExtension) provider;
			try {

				boolean wasReadOnly= isEditorInputReadOnly();
				extension.updateStateCache(input);

				if (fSourceViewer != null)
					fSourceViewer.setEditable(isEditable());

				if (wasReadOnly != isEditorInputReadOnly())
					updateStateDependentActions();

			} catch (CoreException x) {
				Bundle bundle= Platform.getBundle(PlatformUI.PLUGIN_ID);
				ILog log= Platform.getLog(bundle);
				log.log(x.getStatus());
			}
		}
	}

	/**
	 * Performs the save and handles errors appropriately.
	 *
	 * @param overwrite indicates whether or not overwriting is allowed
	 * @param progressMonitor the monitor in which to run the operation
	 * @since 3.0
	 */
	protected void performSave(boolean overwrite, IProgressMonitor progressMonitor) {
		IDocumentProvider provider= getDocumentProvider();
		if (provider == null)
			return;

		fHandleActivation= false;
		try {
			provider.aboutToChange(getEditorInput());
			IEditorInput input= getEditorInput();
			provider.saveDocument(progressMonitor, input, getDocumentProvider().getDocument(input), overwrite);
			editorSaved();

		} catch (CoreException x) {
			IStatus status= x.getStatus();
			if (status == null || status.getSeverity() != IStatus.CANCEL)
				handleExceptionOnSave(x, progressMonitor);
		} finally {
			provider.changed(getEditorInput());
			fHandleActivation= true;
		}
	}

	/**
	 * Handles the given exception. If the exception reports an out-of-sync
	 * situation, this is reported to the user. Otherwise, the exception
	 * is generically reported.
	 *
	 * @param exception the exception to handle
	 * @param progressMonitor the progress monitor
	 */
	protected void handleExceptionOnSave(CoreException exception, IProgressMonitor progressMonitor) {

		try {
			++fErrorCorrectionOnSave;

			boolean isSynchronized= false;
			IDocumentProvider p= getDocumentProvider();

			if (p instanceof IDocumentProviderExtension3)  {
				IDocumentProviderExtension3 p3= (IDocumentProviderExtension3) p;
				isSynchronized= p3.isSynchronized(getEditorInput());
			} else if (p != null) {
				long modifiedStamp= p.getModificationStamp(getEditorInput());
				long synchStamp= p.getSynchronizationStamp(getEditorInput());
				isSynchronized= (modifiedStamp == synchStamp);
			}

			if (isNotSynchronizedException(exception) && fErrorCorrectionOnSave == 1 && !isSynchronized) {
				String title= EditorMessages.Editor_error_save_outofsync_title;
				String msg= NLSUtility.format(EditorMessages.Editor_error_save_outofsync_message, getEditorInput().getToolTipText());

				if (MessageDialog.openQuestion(getSite().getShell(), title, msg))
					performSave(true, progressMonitor);
				else {
					/*
					 * 1GEUPKR: ITPJUI:ALL - Loosing work with simultaneous edits
					 * Set progress monitor to canceled in order to report back
					 * to enclosing operations.
					 */
					if (progressMonitor != null)
						progressMonitor.setCanceled(true);
				}
			} else {
				String title= EditorMessages.Editor_error_save_title;
				String msg= EditorMessages.Editor_error_save_message;
				openSaveErrorDialog(title, msg, exception);

				/*
				 * 1GEUPKR: ITPJUI:ALL - Loosing work with simultaneous edits
				 * Set progress monitor to canceled in order to report back
				 * to enclosing operations.
				 */
				if (progressMonitor != null)
					progressMonitor.setCanceled(true);
			}
		} finally {
			--fErrorCorrectionOnSave;
		}
	}

	/**
	 * Presents an error dialog to the user when a problem
	 * happens during save.
	 * <p>
	 * Subclasses can decide to override the given title and message.
	 * </p>
	 *
	 * @param title	the dialog title
	 * @param message the message to display
	 * @param exception the exception to handle
	 * @since 3.3
	 */
	protected void openSaveErrorDialog(String title, String message, CoreException  exception) {
		ErrorDialog.openError(getSite().getShell(), title, message, exception.getStatus());
	}

	/**
	 * Tells whether the given core exception is exactly the
	 * exception which is thrown for a non-synchronized element.
	 *
	 * @param ex the core exception
	 * @return <code>true</code> iff the given core exception is exactly the
	 *			exception which is thrown for a non-synchronized element
	 * @since 3.1
	 */
	private boolean isNotSynchronizedException(CoreException ex) {
		IDocumentProvider provider= getDocumentProvider();
		if (provider instanceof IDocumentProviderExtension5)
			return ((IDocumentProviderExtension5)provider).isNotSynchronizedException(getEditorInput(), ex);
		return false;
	}

	/**
	 * The <code>AbstractTextEditor</code> implementation of this
	 * <code>IEditorPart</code> method returns <code>false</code>.
	 * Subclasses may override.
	 *
	 * @return <code>false</code>
	 */
	@Override
	public boolean isSaveAsAllowed() {
		return false;
	}

	@Override
	public boolean isDirty() {
		IDocumentProvider p= getDocumentProvider();
		return p == null ? false : p.canSaveDocument(getEditorInput());
	}

	/**
	 * The <code>AbstractTextEditor</code> implementation of this
	 * <code>ITextEditor</code> method may be extended by subclasses.
	 */
	@Override
	public void doRevertToSaved() {
		IDocumentProvider p= getDocumentProvider();
		if (p == null)
			return;

		performRevert();
	}

	/**
	 * Performs revert and handles errors appropriately.
	 * <p>
	 * Subclasses may extend.
	 * </p>
	 *
	 * @since 3.0
	 */
	protected void performRevert() {

		IDocumentProvider provider= getDocumentProvider();
		if (provider == null)
			return;

		try {

			provider.aboutToChange(getEditorInput());
			provider.resetDocument(getEditorInput());
			editorSaved();

		} catch (CoreException x) {
			IStatus status= x.getStatus();
			if (status == null || status.getSeverity() != IStatus.CANCEL ) {
				Shell shell= getSite().getShell();
				String title= EditorMessages.Editor_error_revert_title;
				String msg= EditorMessages.Editor_error_revert_message;
				ErrorDialog.openError(shell, title, msg, x.getStatus());
			}
		} finally {
			provider.changed(getEditorInput());
		}
	}

	/**
	 * Performs any additional action necessary to perform after the input
	 * document's content has been replaced.
	 * <p>
	 * Clients may extended this method.
	 *
	 * @since 3.0
	 */
	protected void handleElementContentReplaced() {
	}

	@Override
	public void setAction(String actionID, IAction action) {
		Assert.isNotNull(actionID);
		if (action == null) {
			action= fActions.remove(actionID);
			if (action != null)
				fActivationCodeTrigger.unregisterActionFromKeyActivation(action);
		} else {
			if (action.getId() == null)
				action.setId(actionID); // make sure the action ID has been set
			fActions.put(actionID, action);
			fActivationCodeTrigger.registerActionForKeyActivation(action);
		}
	}

	/**
	 * Sets this editor's actions into activated (default) or deactived state.
	 * <p>
	 * XXX: This is called by the Java editor for its breadcrumb feature. We
	 * don't want to make this risky method API because the Java editor
	 * breadcrumb might become a Platform UI feature during 3.5 and hence we can
	 * then delete this workaround.
	 * </p>
	 *
	 * @param state <code>true</code> if activated
	 * @since 3.4
	 */
	private void setActionActivation(boolean state) {
		if (state) {
			fActivationCodeTrigger.install();
			Iterator<IAction> iter= fActions.values().iterator();
			while (iter.hasNext()) {
				IAction action= iter.next();
				if (action != null)
					fActivationCodeTrigger.registerActionForKeyActivation(action);
			}
			getEditorSite().getActionBarContributor().setActiveEditor(this);
		} else {
			getEditorSite().getActionBarContributor().setActiveEditor(null);
			Iterator<IAction> iter= fActions.values().iterator();
			while (iter.hasNext()) {
				IAction action= iter.next();
				if (action != null)
					fActivationCodeTrigger.unregisterActionFromKeyActivation(action);
			}
			fActivationCodeTrigger.uninstall();
		}
	}

	private static final boolean HACK_TO_SUPPRESS_UNUSUED_WARNING= false;
	{
		if (HACK_TO_SUPPRESS_UNUSUED_WARNING)
			setActionActivation(true);
	}

	@Override
	public void setActionActivationCode(String actionID, char activationCharacter, int activationKeyCode, int activationStateMask) {

		Assert.isNotNull(actionID);

		ActionActivationCode found= findActionActivationCode(actionID);
		if (found == null) {
			found= new ActionActivationCode(actionID);
			fActivationCodes.add(found);
		}

		found.fCharacter= activationCharacter;
		found.fKeyCode= activationKeyCode;
		found.fStateMask= activationStateMask;
	}

	/**
	 * Returns the activation code registered for the specified action.
	 *
	 * @param actionID the action id
	 * @return the registered activation code or <code>null</code> if no code has been installed
	 */
	private ActionActivationCode findActionActivationCode(String actionID) {
		int size= fActivationCodes.size();
		for (int i= 0; i < size; i++) {
			ActionActivationCode code= fActivationCodes.get(i);
			if (actionID.equals(code.fActionId))
				return code;
		}
		return null;
	}

	@Override
	public void removeActionActivationCode(String actionID) {
		Assert.isNotNull(actionID);
		ActionActivationCode code= findActionActivationCode(actionID);
		if (code != null)
			fActivationCodes.remove(code);
	}

	@Override
	public IAction getAction(String actionID) {
		Assert.isNotNull(actionID);
		IAction action= fActions.get(actionID);

		if (action == null) {
			action= findContributedAction(actionID);
			if (action != null)
				setAction(actionID, action);
		}

		return action;
	}

	/**
	 * Returns the action with the given action id that has been contributed via XML to this editor.
	 * The lookup honors the dependencies of plug-ins.
	 *
	 * @param actionID the action id to look up
	 * @return the action that has been contributed
	 * @since 2.0
	 */
	private IAction findContributedAction(String actionID) {
		List<IConfigurationElement> actions= new ArrayList<>();
		IConfigurationElement[] elements= Platform.getExtensionRegistry().getConfigurationElementsFor(PlatformUI.PLUGIN_ID, "editorActions"); //$NON-NLS-1$
		for (IConfigurationElement element : elements) {
			if (TAG_CONTRIBUTION_TYPE.equals(element.getName())) {
				IWorkbenchPartSite site = getSite();
				if (site == null) {
					return null;
				}
				if (!site.getId().equals(element.getAttribute("targetID"))) //$NON-NLS-1$
					continue;

				for (IConfigurationElement child : element.getChildren("action")) { //$NON-NLS-1$
					if (actionID.equals(child.getAttribute("actionID"))) //$NON-NLS-1$
						actions.add(child);
				}
			}
		}
		int actionSize= actions.size();
		if (actionSize > 0) {
			IConfigurationElement element;
			if (actionSize > 1) {
				IConfigurationElement[] actionArray= actions.toArray(new IConfigurationElement[actionSize]);
				ConfigurationElementSorter sorter= new ConfigurationElementSorter() {
					@Override
					public IConfigurationElement getConfigurationElement(Object object) {
						return (IConfigurationElement)object;
					}
				};
				sorter.sort(actionArray);
				element= actionArray[0];
			} else
				element= actions.get(0);

			try {
				return new ContributedAction(getSite(), element);
			} catch (CommandNotMappedException e) {
				// out of luck, no command action mapping
			}
		}

		return null;
	}

	/**
	 * Updates the specified action by calling <code>IUpdate.update</code>
	 * if applicable.
	 *
	 * @param actionId the action id
	 */
	private void updateAction(String actionId) {
		Assert.isNotNull(actionId);
		if (fActions != null) {
			IAction action= fActions.get(actionId);
			if (action instanceof IUpdate)
				((IUpdate) action).update();
		}
	}

	/**
	 * Marks or unmarks the given action to be updated on text selection changes.
	 *
	 * @param actionId the action id
	 * @param mark <code>true</code> if the action is selection dependent
	 */
	public void markAsSelectionDependentAction(String actionId, boolean mark) {
		Assert.isNotNull(actionId);
		if (mark) {
			if (!fSelectionActions.contains(actionId))
				fSelectionActions.add(actionId);
		} else
			fSelectionActions.remove(actionId);
	}

	/**
	 * Marks or unmarks the given action to be updated on content changes.
	 *
	 * @param actionId the action id
	 * @param mark <code>true</code> if the action is content dependent
	 */
	public void markAsContentDependentAction(String actionId, boolean mark) {
		Assert.isNotNull(actionId);
		if (mark) {
			if (!fContentActions.contains(actionId))
				fContentActions.add(actionId);
		} else
			fContentActions.remove(actionId);
	}

	/**
	 * Marks or unmarks the given action to be updated on property changes.
	 *
	 * @param actionId the action id
	 * @param mark <code>true</code> if the action is property dependent
	 * @since 2.0
	 */
	public void markAsPropertyDependentAction(String actionId, boolean mark) {
		Assert.isNotNull(actionId);
		if (mark) {
			if (!fPropertyActions.contains(actionId))
				fPropertyActions.add(actionId);
		} else
			fPropertyActions.remove(actionId);
	}

	/**
	 * Marks or unmarks the given action to be updated on state changes.
	 *
	 * @param actionId the action id
	 * @param mark <code>true</code> if the action is state dependent
	 * @since 2.0
	 */
	public void markAsStateDependentAction(String actionId, boolean mark) {
		Assert.isNotNull(actionId);
		if (mark) {
			if (!fStateActions.contains(actionId))
				fStateActions.add(actionId);
		} else
			fStateActions.remove(actionId);
	}

	/**
	 * Updates all selection dependent actions.
	 */
	protected void updateSelectionDependentActions() {
		if (fSelectionActions != null) {
			Iterator<String> e= fSelectionActions.iterator();
			while (e.hasNext())
				updateAction(e.next());
		}
	}

	/**
	 * Updates all content dependent actions.
	 */
	protected void updateContentDependentActions() {
		if (fContentActions != null) {
			Iterator<String> e= fContentActions.iterator();
			while (e.hasNext())
				updateAction(e.next());
		}
	}

	/**
	 * Updates all property dependent actions.
	 * @since 2.0
	 */
	protected void updatePropertyDependentActions() {
		if (fPropertyActions != null) {
			Iterator<String> e= fPropertyActions.iterator();
			while (e.hasNext())
				updateAction(e.next());
		}
	}

	/**
	 * Updates all state dependent actions.
	 * @since 2.0
	 */
	protected void updateStateDependentActions() {
		if (fStateActions != null) {
			Iterator<String> e= fStateActions.iterator();
			while (e.hasNext())
				updateAction(e.next());
		}
	}

	/**
	 * Creates action entries for all SWT StyledText actions as defined in
	 * <code>org.eclipse.swt.custom.ST</code>. Overwrites and
	 * extends the list of these actions afterwards.
	 * <p>
	 * Subclasses may extend.
	 * </p>
	 * @since 2.0
	 */
	protected void createNavigationActions() {

		IAction action;

		StyledText textWidget= fSourceViewer.getTextWidget();
		for (IdMapEntry entry : ACTION_MAP) {
			action= new TextNavigationAction(textWidget, entry.getAction());
			action.setActionDefinitionId(entry.getActionId());
			setAction(entry.getActionId(), action);
		}

		action= new ToggleOverwriteModeAction(EditorMessages.getBundleForConstructedKeys(), "Editor.ToggleOverwriteMode."); //$NON-NLS-1$
		action.setActionDefinitionId(ITextEditorActionDefinitionIds.TOGGLE_OVERWRITE);
		setAction(ITextEditorActionDefinitionIds.TOGGLE_OVERWRITE, action);
		textWidget.setKeyBinding(SWT.INSERT, SWT.NULL);

		action=  new ScrollLinesAction(-1);
		action.setActionDefinitionId(ITextEditorActionDefinitionIds.SCROLL_LINE_UP);
		setAction(ITextEditorActionDefinitionIds.SCROLL_LINE_UP, action);

		action= new ScrollLinesAction(1);
		action.setActionDefinitionId(ITextEditorActionDefinitionIds.SCROLL_LINE_DOWN);
		setAction(ITextEditorActionDefinitionIds.SCROLL_LINE_DOWN, action);

		action= new LineEndAction(textWidget, false);
		action.setActionDefinitionId(ITextEditorActionDefinitionIds.LINE_END);
		setAction(ITextEditorActionDefinitionIds.LINE_END, action);

		action= new LineStartAction(textWidget, false);
		action.setActionDefinitionId(ITextEditorActionDefinitionIds.LINE_START);
		setAction(ITextEditorActionDefinitionIds.LINE_START, action);

		action= new LineEndAction(textWidget, true);
		action.setActionDefinitionId(ITextEditorActionDefinitionIds.SELECT_LINE_END);
		setAction(ITextEditorActionDefinitionIds.SELECT_LINE_END, action);

		action= new LineStartAction(textWidget, true);
		action.setActionDefinitionId(ITextEditorActionDefinitionIds.SELECT_LINE_START);
		setAction(ITextEditorActionDefinitionIds.SELECT_LINE_START, action);

		// to accommodate https://bugs.eclipse.org/bugs/show_bug.cgi?id=51516
		// nullify handling of DELETE key by StyledText
		textWidget.setKeyBinding(SWT.DEL, SWT.NULL);
	}

	/**
	 * Creates this editor's accessibility actions.
	 * @since 2.0
	 */
	private void createAccessibilityActions() {
		IAction action= new ShowRulerContextMenuAction();
		action.setActionDefinitionId(ITextEditorActionDefinitionIds.SHOW_RULER_CONTEXT_MENU);
		setAction(ITextEditorActionDefinitionIds.SHOW_RULER_CONTEXT_MENU, action);
	}

	/**
	 * Creates this editor's undo/redo actions.
	 * <p>
	 * Subclasses may override or extend.</p>
	 *
	 * @since 3.1
	 */
	protected void createUndoRedoActions() {
		IUndoContext undoContext= getUndoContext();
		if (undoContext != null) {
			// Use actions provided by global undo/redo

			// Create the undo action
			OperationHistoryActionHandler undoAction= new UndoActionHandler(getEditorSite(), undoContext);
			PlatformUI.getWorkbench().getHelpSystem().setHelp(undoAction, IAbstractTextEditorHelpContextIds.UNDO_ACTION);
			undoAction.setActionDefinitionId(IWorkbenchCommandConstants.EDIT_UNDO);
			registerUndoRedoAction(ITextEditorActionConstants.UNDO, undoAction);

			// Create the redo action.
			OperationHistoryActionHandler redoAction= new RedoActionHandler(getEditorSite(), undoContext);
			PlatformUI.getWorkbench().getHelpSystem().setHelp(redoAction, IAbstractTextEditorHelpContextIds.REDO_ACTION);
			redoAction.setActionDefinitionId(IWorkbenchCommandConstants.EDIT_REDO);
			registerUndoRedoAction(ITextEditorActionConstants.REDO, redoAction);

			// Install operation approvers
			IOperationHistory history= OperationHistoryFactory.getOperationHistory();

			// The first approver will prompt when operations affecting outside elements are to be undone or redone.
			if (fNonLocalOperationApprover != null)
				history.removeOperationApprover(fNonLocalOperationApprover);
			fNonLocalOperationApprover= getUndoRedoOperationApprover(undoContext);
			history.addOperationApprover(fNonLocalOperationApprover);

			// The second approver will prompt from this editor when an undo is attempted on an operation
			// and it is not the most recent operation in the editor.
			if (fLinearUndoViolationApprover != null)
				history.removeOperationApprover(fLinearUndoViolationApprover);
			fLinearUndoViolationApprover= new LinearUndoViolationUserApprover(undoContext, this);
			history.addOperationApprover(fLinearUndoViolationApprover);

		} else {
			// Use text operation actions (pre 3.1 style)

			ResourceAction action;

			if (getAction(ITextEditorActionConstants.UNDO) == null) {
				action= new TextOperationAction(EditorMessages.getBundleForConstructedKeys(), "Editor.Undo.", this, ITextOperationTarget.UNDO); //$NON-NLS-1$
				action.setHelpContextId(IAbstractTextEditorHelpContextIds.UNDO_ACTION);
				action.setActionDefinitionId(IWorkbenchCommandConstants.EDIT_UNDO);
				setAction(ITextEditorActionConstants.UNDO, action);
			}

			if (getAction(ITextEditorActionConstants.REDO) == null) {
				action= new TextOperationAction(EditorMessages.getBundleForConstructedKeys(), "Editor.Redo.", this, ITextOperationTarget.REDO); //$NON-NLS-1$
				action.setHelpContextId(IAbstractTextEditorHelpContextIds.REDO_ACTION);
				action.setActionDefinitionId(IWorkbenchCommandConstants.EDIT_REDO);
				setAction(ITextEditorActionConstants.REDO, action);
			}
		}
	}

	/**
	 * Registers the given undo/redo action under the given ID and ensures that previously installed
	 * actions get disposed. It also takes care of re-registering the new action with the global
	 * action handler.
	 *
	 * @param actionId the action id under which to register the action
	 * @param action the action to register or <code>null</code> to dispose them
	 * @since 3.1
	 */
	private void registerUndoRedoAction(String actionId, OperationHistoryActionHandler action) {
		IAction oldAction= getAction(actionId);
		if (oldAction instanceof OperationHistoryActionHandler)
			((OperationHistoryActionHandler)oldAction).dispose();

		if (action == null)
			return;

		setAction(actionId, action);

		IActionBars actionBars= getEditorSite().getActionBars();
		if (actionBars != null)
			actionBars.setGlobalActionHandler(actionId, action);
	}

	/**
	 * Return an {@link IOperationApprover} appropriate for approving the undo and
	 * redo of operations that have the specified undo context.
	 * <p>
	 * Subclasses may override.
	 * </p>
	 * @param undoContext	the IUndoContext of operations that should be examined
	 * 						by the operation approver
	 * @return	the <code>IOperationApprover</code> appropriate for approving undo
	 * 			and redo operations inside this editor, or <code>null</code> if no
	 * 			approval is needed
	 * @since 3.1
	 */
	protected IOperationApprover getUndoRedoOperationApprover(IUndoContext undoContext) {
		return new NonLocalUndoUserApprover(undoContext, this, new Object [] { getEditorInput() }, Object.class);
	}

	/**
	 * Creates this editor's standard actions and connects them with the global
	 * workbench actions.
	 * <p>
	 * Subclasses may extend.</p>
	 */
	protected void createActions() {

		ResourceAction action;

		setAction(IWorkbenchCommandConstants.EDIT_CUT, null);
		action= new TextOperationAction(EditorMessages.getBundleForConstructedKeys(), "Editor.Cut.", this, ITextOperationTarget.CUT); //$NON-NLS-1$
		action.setHelpContextId(IAbstractTextEditorHelpContextIds.CUT_ACTION);
		action.setActionDefinitionId(IWorkbenchCommandConstants.EDIT_CUT);
		updateImages(action, IWorkbenchCommandConstants.EDIT_CUT);
		setAction(ITextEditorActionConstants.CUT, action);

		setAction(IWorkbenchCommandConstants.EDIT_COPY, null);
		action= new TextOperationAction(EditorMessages.getBundleForConstructedKeys(), "Editor.Copy.", this, ITextOperationTarget.COPY, true); //$NON-NLS-1$
		action.setHelpContextId(IAbstractTextEditorHelpContextIds.COPY_ACTION);
		action.setActionDefinitionId(IWorkbenchCommandConstants.EDIT_COPY);
		updateImages(action, IWorkbenchCommandConstants.EDIT_COPY);
		setAction(ITextEditorActionConstants.COPY, action);

		setAction(IWorkbenchCommandConstants.EDIT_PASTE, null);
		action= new TextOperationAction(EditorMessages.getBundleForConstructedKeys(), "Editor.Paste.", this, ITextOperationTarget.PASTE); //$NON-NLS-1$
		action.setHelpContextId(IAbstractTextEditorHelpContextIds.PASTE_ACTION);
		action.setActionDefinitionId(IWorkbenchCommandConstants.EDIT_PASTE);
		updateImages(action, IWorkbenchCommandConstants.EDIT_PASTE);
		setAction(ITextEditorActionConstants.PASTE, action);

		action= new TextOperationAction(EditorMessages.getBundleForConstructedKeys(), "Editor.Delete.", this, ITextOperationTarget.DELETE); //$NON-NLS-1$
		action.setHelpContextId(IAbstractTextEditorHelpContextIds.DELETE_ACTION);
		action.setActionDefinitionId(IWorkbenchCommandConstants.EDIT_DELETE);
		updateImages(action, IWorkbenchCommandConstants.EDIT_DELETE);
		setAction(ITextEditorActionConstants.DELETE, action);

		action= new DeleteLineAction(EditorMessages.getBundleForConstructedKeys(), "Editor.DeleteLine.", this, DeleteLineAction.WHOLE, false); //$NON-NLS-1$
		action.setHelpContextId(IAbstractTextEditorHelpContextIds.DELETE_LINE_ACTION);
		action.setActionDefinitionId(ITextEditorActionDefinitionIds.DELETE_LINE);
		setAction(ITextEditorActionConstants.DELETE_LINE, action);

		action= new DeleteLineAction(EditorMessages.getBundleForConstructedKeys(), "Editor.CutLine.", this, DeleteLineAction.WHOLE, true); //$NON-NLS-1$
		action.setHelpContextId(IAbstractTextEditorHelpContextIds.CUT_LINE_ACTION);
		action.setActionDefinitionId(ITextEditorActionDefinitionIds.CUT_LINE);
		setAction(ITextEditorActionConstants.CUT_LINE, action);

		action= new DeleteLineAction(EditorMessages.getBundleForConstructedKeys(), "Editor.DeleteLineToBeginning.", this, DeleteLineAction.TO_BEGINNING, false); //$NON-NLS-1$
		action.setHelpContextId(IAbstractTextEditorHelpContextIds.DELETE_LINE_TO_BEGINNING_ACTION);
		action.setActionDefinitionId(ITextEditorActionDefinitionIds.DELETE_LINE_TO_BEGINNING);
		setAction(ITextEditorActionConstants.DELETE_LINE_TO_BEGINNING, action);

		action= new DeleteLineAction(EditorMessages.getBundleForConstructedKeys(), "Editor.CutLineToBeginning.", this, DeleteLineAction.TO_BEGINNING, true); //$NON-NLS-1$
		action.setHelpContextId(IAbstractTextEditorHelpContextIds.CUT_LINE_TO_BEGINNING_ACTION);
		action.setActionDefinitionId(ITextEditorActionDefinitionIds.CUT_LINE_TO_BEGINNING);
		setAction(ITextEditorActionConstants.CUT_LINE_TO_BEGINNING, action);

		action= new DeleteLineAction(EditorMessages.getBundleForConstructedKeys(), "Editor.DeleteLineToEnd.", this, DeleteLineAction.TO_END, false); //$NON-NLS-1$
		action.setHelpContextId(IAbstractTextEditorHelpContextIds.DELETE_LINE_TO_END_ACTION);
		action.setActionDefinitionId(ITextEditorActionDefinitionIds.DELETE_LINE_TO_END);
		setAction(ITextEditorActionConstants.DELETE_LINE_TO_END, action);

		action= new DeleteLineAction(EditorMessages.getBundleForConstructedKeys(), "Editor.CutLineToEnd.", this, DeleteLineAction.TO_END, true); //$NON-NLS-1$
		action.setHelpContextId(IAbstractTextEditorHelpContextIds.CUT_LINE_TO_END_ACTION);
		action.setActionDefinitionId(ITextEditorActionDefinitionIds.CUT_LINE_TO_END);
		setAction(ITextEditorActionConstants.CUT_LINE_TO_END, action);

		action= new JoinLinesAction(EditorMessages.getBundleForConstructedKeys(), "Editor.JoinLines.", this, " "); //$NON-NLS-1$ //$NON-NLS-2$
		action.setHelpContextId(IAbstractTextEditorHelpContextIds.JOIN_LINES_ACTION);
		action.setActionDefinitionId(ITextEditorActionDefinitionIds.JOIN_LINES);
		setAction(ITextEditorActionConstants.JOIN_LINES, action);

		action= new MarkAction(EditorMessages.getBundleForConstructedKeys(), "Editor.SetMark.", this, MarkAction.SET_MARK); //$NON-NLS-1$
		action.setHelpContextId(IAbstractTextEditorHelpContextIds.SET_MARK_ACTION);
		action.setActionDefinitionId(ITextEditorActionDefinitionIds.SET_MARK);
		setAction(ITextEditorActionConstants.SET_MARK, action);

		action= new MarkAction(EditorMessages.getBundleForConstructedKeys(), "Editor.ClearMark.", this, MarkAction.CLEAR_MARK); //$NON-NLS-1$
		action.setHelpContextId(IAbstractTextEditorHelpContextIds.CLEAR_MARK_ACTION);
		action.setActionDefinitionId(ITextEditorActionDefinitionIds.CLEAR_MARK);
		setAction(ITextEditorActionConstants.CLEAR_MARK, action);

		action= new MarkAction(EditorMessages.getBundleForConstructedKeys(), "Editor.SwapMark.", this, MarkAction.SWAP_MARK); //$NON-NLS-1$
		action.setHelpContextId(IAbstractTextEditorHelpContextIds.SWAP_MARK_ACTION);
		action.setActionDefinitionId(ITextEditorActionDefinitionIds.SWAP_MARK);
		setAction(ITextEditorActionConstants.SWAP_MARK, action);

		action= new TextOperationAction(EditorMessages.getBundleForConstructedKeys(), "Editor.SelectAll.", this, ITextOperationTarget.SELECT_ALL, true); //$NON-NLS-1$
		action.setHelpContextId(IAbstractTextEditorHelpContextIds.SELECT_ALL_ACTION);
		action.setActionDefinitionId(IWorkbenchCommandConstants.EDIT_SELECT_ALL);
		setAction(ITextEditorActionConstants.SELECT_ALL, action);

		action= new ShiftAction(EditorMessages.getBundleForConstructedKeys(), "Editor.ShiftRight.", this, ITextOperationTarget.SHIFT_RIGHT); //$NON-NLS-1$
		action.setHelpContextId(IAbstractTextEditorHelpContextIds.SHIFT_RIGHT_ACTION);
		action.setActionDefinitionId(ITextEditorActionDefinitionIds.SHIFT_RIGHT);
		setAction(ITextEditorActionConstants.SHIFT_RIGHT, action);

		action= new ShiftAction(EditorMessages.getBundleForConstructedKeys(), "Editor.ShiftRight.", this, ITextOperationTarget.SHIFT_RIGHT) { //$NON-NLS-1$
			@Override
			public void update() {
				updateForTab();
			}
		};
		setAction(ITextEditorActionConstants.SHIFT_RIGHT_TAB, action);

		action= new ShiftAction(EditorMessages.getBundleForConstructedKeys(), "Editor.ShiftLeft.", this, ITextOperationTarget.SHIFT_LEFT); //$NON-NLS-1$
		action.setHelpContextId(IAbstractTextEditorHelpContextIds.SHIFT_LEFT_ACTION);
		action.setActionDefinitionId(ITextEditorActionDefinitionIds.SHIFT_LEFT);
		setAction(ITextEditorActionConstants.SHIFT_LEFT, action);

		action= new TextOperationAction(EditorMessages.getBundleForConstructedKeys(), "Editor.Print.", this, ITextOperationTarget.PRINT, true); //$NON-NLS-1$
		action.setHelpContextId(IAbstractTextEditorHelpContextIds.PRINT_ACTION);
		action.setActionDefinitionId(IWorkbenchCommandConstants.FILE_PRINT);
		updateImages(action, IWorkbenchCommandConstants.FILE_PRINT);
		setAction(ITextEditorActionConstants.PRINT, action);

		action= new FindReplaceAction(EditorMessages.getBundleForConstructedKeys(), "Editor.FindReplace.", this); //$NON-NLS-1$
		action.setHelpContextId(IAbstractTextEditorHelpContextIds.FIND_ACTION);
		action.setActionDefinitionId(IWorkbenchCommandConstants.EDIT_FIND_AND_REPLACE);
		updateImages(action, IWorkbenchCommandConstants.EDIT_FIND_AND_REPLACE);
		setAction(ITextEditorActionConstants.FIND, action);

		action= new FindNextAction(EditorMessages.getBundleForConstructedKeys(), "Editor.FindNext.", this, true); //$NON-NLS-1$
		action.setHelpContextId(IAbstractTextEditorHelpContextIds.FIND_NEXT_ACTION);
		action.setActionDefinitionId(IWorkbenchActionDefinitionIds.FIND_NEXT);
		setAction(ITextEditorActionConstants.FIND_NEXT, action);

		action= new FindNextAction(EditorMessages.getBundleForConstructedKeys(), "Editor.FindPrevious.", this, false); //$NON-NLS-1$
		action.setHelpContextId(IAbstractTextEditorHelpContextIds.FIND_PREVIOUS_ACTION);
		action.setActionDefinitionId(IWorkbenchActionDefinitionIds.FIND_PREVIOUS);
		setAction(ITextEditorActionConstants.FIND_PREVIOUS, action);

		action= new IncrementalFindAction(EditorMessages.getBundleForConstructedKeys(), "Editor.FindIncremental.", this, true); //$NON-NLS-1$
		action.setHelpContextId(IAbstractTextEditorHelpContextIds.FIND_INCREMENTAL_ACTION);
		action.setActionDefinitionId(IWorkbenchActionDefinitionIds.FIND_INCREMENTAL);
		setAction(ITextEditorActionConstants.FIND_INCREMENTAL, action);

		action= new IncrementalFindAction(EditorMessages.getBundleForConstructedKeys(), "Editor.FindIncrementalReverse.", this, false); //$NON-NLS-1$
		action.setHelpContextId(IAbstractTextEditorHelpContextIds.FIND_INCREMENTAL_REVERSE_ACTION);
		action.setActionDefinitionId(IWorkbenchActionDefinitionIds.FIND_INCREMENTAL_REVERSE);
		setAction(ITextEditorActionConstants.FIND_INCREMENTAL_REVERSE, action);

		fSaveAction= ActionFactory.SAVE.create(getSite().getWorkbenchWindow());
		setAction(ITextEditorActionConstants.SAVE, fSaveAction);

		action= new RevertToSavedAction(EditorMessages.getBundleForConstructedKeys(), "Editor.Revert.", this); //$NON-NLS-1$
		action.setHelpContextId(IAbstractTextEditorHelpContextIds.REVERT_TO_SAVED_ACTION);
		action.setActionDefinitionId(IWorkbenchCommandConstants.FILE_REVERT);
		updateImages(action, IWorkbenchCommandConstants.FILE_REVERT);
		setAction(ITextEditorActionConstants.REVERT_TO_SAVED, action);

		action= new GotoLineAction(EditorMessages.getBundleForConstructedKeys(), "Editor.GotoLine.", this); //$NON-NLS-1$
		action.setHelpContextId(IAbstractTextEditorHelpContextIds.GOTO_LINE_ACTION);
		action.setActionDefinitionId(ITextEditorActionDefinitionIds.LINE_GOTO);
		setAction(ITextEditorActionConstants.GOTO_LINE, action);

		action= new MoveLinesAction(EditorMessages.getBundleForConstructedKeys(), "Editor.MoveLinesUp.", this, getSourceViewer(), true, false); //$NON-NLS-1$
		action.setHelpContextId(IAbstractTextEditorHelpContextIds.MOVE_LINES_ACTION);
		action.setActionDefinitionId(ITextEditorActionDefinitionIds.MOVE_LINES_UP);
		setAction(ITextEditorActionConstants.MOVE_LINE_UP, action);

		action= new MoveLinesAction(EditorMessages.getBundleForConstructedKeys(), "Editor.MoveLinesDown.", this, getSourceViewer(), false, false); //$NON-NLS-1$
		action.setHelpContextId(IAbstractTextEditorHelpContextIds.MOVE_LINES_ACTION);
		action.setActionDefinitionId(ITextEditorActionDefinitionIds.MOVE_LINES_DOWN);
		setAction(ITextEditorActionConstants.MOVE_LINE_DOWN, action);

		action= new MoveLinesAction(EditorMessages.getBundleForConstructedKeys(), "Editor.CopyLineUp.", this, getSourceViewer(), true, true); //$NON-NLS-1$
		action.setHelpContextId(IAbstractTextEditorHelpContextIds.COPY_LINES_ACTION);
		action.setActionDefinitionId(ITextEditorActionDefinitionIds.COPY_LINES_UP);
		setAction(ITextEditorActionConstants.COPY_LINE_UP, action);

		action= new MoveLinesAction(EditorMessages.getBundleForConstructedKeys(), "Editor.CopyLineDown.", this, getSourceViewer(), false, true); //$NON-NLS-1$
		action.setHelpContextId(IAbstractTextEditorHelpContextIds.COPY_LINES_ACTION);
		action.setActionDefinitionId(ITextEditorActionDefinitionIds.COPY_LINES_DOWN);
		setAction(ITextEditorActionConstants.COPY_LINE_DOWN, action);

		action= new CaseAction(EditorMessages.getBundleForConstructedKeys(), "Editor.UpperCase.", this, true); //$NON-NLS-1$
		action.setHelpContextId(IAbstractTextEditorHelpContextIds.UPPER_CASE_ACTION);
		action.setActionDefinitionId(ITextEditorActionDefinitionIds.UPPER_CASE);
		setAction(ITextEditorActionConstants.UPPER_CASE, action);

		action= new CaseAction(EditorMessages.getBundleForConstructedKeys(), "Editor.LowerCase.", this, false); //$NON-NLS-1$
		action.setHelpContextId(IAbstractTextEditorHelpContextIds.LOWER_CASE_ACTION);
		action.setActionDefinitionId(ITextEditorActionDefinitionIds.LOWER_CASE);
		setAction(ITextEditorActionConstants.LOWER_CASE, action);

		action= new InsertLineAction(EditorMessages.getBundleForConstructedKeys(), "Editor.SmartEnter.", this, false); //$NON-NLS-1$
		action.setHelpContextId(IAbstractTextEditorHelpContextIds.SMART_ENTER_ACTION);
		action.setActionDefinitionId(ITextEditorActionDefinitionIds.SMART_ENTER);
		setAction(ITextEditorActionConstants.SMART_ENTER, action);

		action= new InsertLineAction(EditorMessages.getBundleForConstructedKeys(), "Editor.SmartEnterInverse.", this, true); //$NON-NLS-1$
		action.setHelpContextId(IAbstractTextEditorHelpContextIds.SMART_ENTER_ACTION);
		action.setActionDefinitionId(ITextEditorActionDefinitionIds.SMART_ENTER_INVERSE);
		setAction(ITextEditorActionConstants.SMART_ENTER_INVERSE, action);

		action= new ToggleInsertModeAction(EditorMessages.getBundleForConstructedKeys(), "Editor.ToggleInsertMode."); //$NON-NLS-1$
		action.setHelpContextId(IAbstractTextEditorHelpContextIds.TOGGLE_INSERT_MODE_ACTION);
		action.setActionDefinitionId(ITextEditorActionDefinitionIds.TOGGLE_INSERT_MODE);
		setAction(ITextEditorActionConstants.TOGGLE_INSERT_MODE, action);

		action= new HippieCompleteAction(EditorMessages.getBundleForConstructedKeys(), "Editor.HippieCompletion.", this); //$NON-NLS-1$
		action.setHelpContextId(IAbstractTextEditorHelpContextIds.HIPPIE_COMPLETION_ACTION);
		action.setActionDefinitionId(ITextEditorActionDefinitionIds.HIPPIE_COMPLETION);
		setAction(ITextEditorActionConstants.HIPPIE_COMPLETION, action);

		action= new ContentAssistAction(EditorMessages.getBundleForConstructedKeys(), "Editor.ContentAssistProposal.", this); //$NON-NLS-1$
		action.setHelpContextId(IAbstractTextEditorHelpContextIds.CONTENT_ASSIST_ACTION);
		action.setActionDefinitionId(ITextEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS);
		setAction(ITextEditorActionConstants.CONTENT_ASSIST, action);
		markAsStateDependentAction(ITextEditorActionConstants.CONTENT_ASSIST, true);

		action= new TextOperationAction(EditorMessages.getBundleForConstructedKeys(), "Editor.ContentAssistContextInformation.", this, ISourceViewer.CONTENTASSIST_CONTEXT_INFORMATION); //$NON-NLS-1$
		action.setHelpContextId(IAbstractTextEditorHelpContextIds.CONTENT_ASSIST_CONTEXT_INFORMATION_ACTION);
		action.setActionDefinitionId(ITextEditorActionDefinitionIds.CONTENT_ASSIST_CONTEXT_INFORMATION);
		setAction(ITextEditorActionConstants.CONTENT_ASSIST_CONTEXT_INFORMATION, action);
		markAsStateDependentAction(ITextEditorActionConstants.CONTENT_ASSIST_CONTEXT_INFORMATION, true);

		action= new TextOperationAction(EditorMessages.getBundleForConstructedKeys(), "Editor.QuickAssist.", this, ISourceViewer.QUICK_ASSIST); //$NON-NLS-1$
		action.setHelpContextId(IAbstractTextEditorHelpContextIds.QUICK_ASSIST_ACTION);
		action.setActionDefinitionId(ITextEditorActionDefinitionIds.QUICK_ASSIST);
		setAction(ITextEditorActionConstants.QUICK_ASSIST, action);
		markAsStateDependentAction(ITextEditorActionConstants.QUICK_ASSIST, true);

		action= new GotoAnnotationAction(this, true);
		setAction(ITextEditorActionConstants.NEXT, action);
		action= new GotoAnnotationAction(this, false);
		setAction(ITextEditorActionConstants.PREVIOUS, action);

		action= new RecenterAction(EditorMessages.getBundleForConstructedKeys(), "Editor.Recenter.", this); //$NON-NLS-1$
		action.setHelpContextId(IAbstractTextEditorHelpContextIds.RECENTER_ACTION);
		action.setActionDefinitionId(ITextEditorActionDefinitionIds.RECENTER);
		setAction(ITextEditorActionConstants.RECENTER, action);

		action= new ShowWhitespaceCharactersAction(EditorMessages.getBundleForConstructedKeys(), "Editor.ShowWhitespaceCharacters.", this, getPreferenceStore()); //$NON-NLS-1$
		action.setHelpContextId(IAbstractTextEditorHelpContextIds.SHOW_WHITESPACE_CHARACTERS_ACTION);
		action.setActionDefinitionId(ITextEditorActionDefinitionIds.SHOW_WHITESPACE_CHARACTERS);
		setAction(ITextEditorActionConstants.SHOW_WHITESPACE_CHARACTERS, action);

		action= new TextOperationAction(EditorMessages.getBundleForConstructedKeys(), "Editor.ShowInformation.", this, ISourceViewer.INFORMATION, true); //$NON-NLS-1$
		action= new InformationDispatchAction(EditorMessages.getBundleForConstructedKeys(), "Editor.ShowInformation.", (TextOperationAction) action); //$NON-NLS-1$
		action.setHelpContextId(IAbstractTextEditorHelpContextIds.SHOW_INFORMATION_ACTION);
		action.setActionDefinitionId(ITextEditorActionDefinitionIds.SHOW_INFORMATION);
		setAction(ITextEditorActionConstants.SHOW_INFORMATION, action);

		final BlockSelectionModeToggleAction blockAction= new BlockSelectionModeToggleAction(EditorMessages.getBundleForConstructedKeys(), "Editor.ToggleBlockSelectionMode.", this); //$NON-NLS-1$
		action= blockAction;
		action.setHelpContextId(IAbstractTextEditorHelpContextIds.BLOCK_SELECTION_MODE_ACTION);
		action.setActionDefinitionId(ITextEditorActionDefinitionIds.BLOCK_SELECTION_MODE);
		setAction(ITextEditorActionConstants.BLOCK_SELECTION_MODE, action);

		if (isWordWrapSupported()) {
			final WordWrapToggleAction wrapAction= new WordWrapToggleAction(EditorMessages.getBundleForConstructedKeys(), "Editor.ToggleWordWrap.", this, getInitialWordWrapStatus()); //$NON-NLS-1$
			action= wrapAction;
			action.setHelpContextId(IAbstractTextEditorHelpContextIds.WORD_WRAP_TOGGLE_ACTION);
			action.setActionDefinitionId(ITextEditorActionDefinitionIds.WORD_WRAP);
			setAction(ITextEditorActionConstants.WORD_WRAP, action);

			blockAction.addPropertyChangeListener(event -> {
				if (IAction.CHECKED == event.getProperty() && Boolean.TRUE.equals(event.getNewValue())) {
					wrapAction.setChecked(false);
				}
			});
			wrapAction.addPropertyChangeListener(event -> {
				if (IAction.CHECKED == event.getProperty() && Boolean.TRUE.equals(event.getNewValue())) {
					blockAction.setChecked(false);
				}
			});
		}

		action= new TextOperationAction(EditorMessages.getBundleForConstructedKeys(), "Editor.OpenHyperlink.", this, HyperlinkManager.OPEN_HYPERLINK, true); //$NON-NLS-1$;
		action.setHelpContextId(IAbstractTextEditorHelpContextIds.OPEN_HYPERLINK_ACTION);
		action.setActionDefinitionId(ITextEditorActionDefinitionIds.OPEN_HYPERLINK);
		setAction(ITextEditorActionConstants.OPEN_HYPERLINK, action);

		PropertyDialogAction openProperties= new PropertyDialogAction(
				() -> getSite().getShell(),
				new ISelectionProvider() {
					@Override
					public void addSelectionChangedListener(ISelectionChangedListener listener) {
					}
					@Override
					public ISelection getSelection() {
						return new StructuredSelection(getEditorInput());
					}
					@Override
					public void removeSelectionChangedListener(ISelectionChangedListener listener) {
					}
					@Override
					public void setSelection(ISelection selection) {
					}
				});
		openProperties.setActionDefinitionId(IWorkbenchCommandConstants.FILE_PROPERTIES);
		updateImages(openProperties, IWorkbenchCommandConstants.FILE_PROPERTIES);
		setAction(ITextEditorActionConstants.PROPERTIES, openProperties);

		markAsContentDependentAction(ITextEditorActionConstants.UNDO, true);
		markAsContentDependentAction(ITextEditorActionConstants.REDO, true);
		markAsContentDependentAction(ITextEditorActionConstants.FIND, true);
		markAsContentDependentAction(ITextEditorActionConstants.FIND_NEXT, true);
		markAsContentDependentAction(ITextEditorActionConstants.FIND_PREVIOUS, true);
		markAsContentDependentAction(ITextEditorActionConstants.FIND_INCREMENTAL, true);
		markAsContentDependentAction(ITextEditorActionConstants.FIND_INCREMENTAL_REVERSE, true);

		markAsSelectionDependentAction(ITextEditorActionConstants.CUT, true);
		markAsSelectionDependentAction(ITextEditorActionConstants.COPY, true);
		markAsSelectionDependentAction(ITextEditorActionConstants.PASTE, true);
		markAsSelectionDependentAction(ITextEditorActionConstants.DELETE, true);
		markAsSelectionDependentAction(ITextEditorActionConstants.SHIFT_RIGHT, true);
		markAsSelectionDependentAction(ITextEditorActionConstants.SHIFT_RIGHT_TAB, true);
		markAsSelectionDependentAction(ITextEditorActionConstants.UPPER_CASE, true);
		markAsSelectionDependentAction(ITextEditorActionConstants.LOWER_CASE, true);

		markAsPropertyDependentAction(ITextEditorActionConstants.UNDO, true);
		markAsPropertyDependentAction(ITextEditorActionConstants.REDO, true);
		markAsPropertyDependentAction(ITextEditorActionConstants.REVERT_TO_SAVED, true);
		markAsPropertyDependentAction(ITextEditorActionConstants.SAVE, true);

		markAsStateDependentAction(ITextEditorActionConstants.UNDO, true);
		markAsStateDependentAction(ITextEditorActionConstants.REDO, true);
		markAsStateDependentAction(ITextEditorActionConstants.CUT, true);
		markAsStateDependentAction(ITextEditorActionConstants.PASTE, true);
		markAsStateDependentAction(ITextEditorActionConstants.DELETE, true);
		markAsStateDependentAction(ITextEditorActionConstants.SHIFT_RIGHT, true);
		markAsStateDependentAction(ITextEditorActionConstants.SHIFT_RIGHT_TAB, true);
		markAsStateDependentAction(ITextEditorActionConstants.SHIFT_LEFT, true);
		markAsStateDependentAction(ITextEditorActionConstants.FIND, true);
		markAsStateDependentAction(ITextEditorActionConstants.DELETE_LINE, true);
		markAsStateDependentAction(ITextEditorActionConstants.DELETE_LINE_TO_BEGINNING, true);
		markAsStateDependentAction(ITextEditorActionConstants.DELETE_LINE_TO_END, true);
		markAsStateDependentAction(ITextEditorActionConstants.MOVE_LINE_UP, true);
		markAsStateDependentAction(ITextEditorActionConstants.MOVE_LINE_DOWN, true);
		markAsStateDependentAction(ITextEditorActionConstants.CUT_LINE, true);
		markAsStateDependentAction(ITextEditorActionConstants.CUT_LINE_TO_BEGINNING, true);
		markAsStateDependentAction(ITextEditorActionConstants.CUT_LINE_TO_END, true);

		setActionActivationCode(ITextEditorActionConstants.SHIFT_RIGHT_TAB,'\t', -1, SWT.NONE);
		setActionActivationCode(ITextEditorActionConstants.SHIFT_LEFT, '\t', -1, SWT.SHIFT);
	}

	private void updateImages(IAction action, String commandId) {
		if (action.getImageDescriptor() != null) {
			return;
		}
		ICommandImageService imgService = getSite().getService(ICommandImageService.class);
		if (imgService == null) {
			return;
		}
		action.setImageDescriptor(imgService.getImageDescriptor(commandId));
		action.setDisabledImageDescriptor(imgService.getImageDescriptor(commandId, ICommandImageService.TYPE_DISABLED));
		action.setHoverImageDescriptor(imgService.getImageDescriptor(commandId, ICommandImageService.TYPE_HOVER));
	}

	/**
	 * Convenience method to add the action installed under the given action id to the given menu.
	 * @param menu the menu to add the action to
	 * @param actionId the id of the action to be added
	 */
	protected final void addAction(IMenuManager menu, String actionId) {
		IAction action= getAction(actionId);
		if (action != null) {
			if (action instanceof IUpdate)
				((IUpdate) action).update();
			menu.add(action);
		}
	}

	/**
	 * Convenience method to add the action installed under the given action id to the specified group of the menu.
	 * @param menu the menu to add the action to
	 * @param group the group in the menu
	 * @param actionId the id of the action to add
	 */
	protected final void addAction(IMenuManager menu, String group, String actionId) {
	 	IAction action= getAction(actionId);
	 	if (action != null) {
	 		if (action instanceof IUpdate)
	 			((IUpdate) action).update();

	 		IMenuManager subMenu= menu.findMenuUsingPath(group);
	 		if (subMenu != null)
	 			subMenu.add(action);
	 		else
	 			menu.appendToGroup(group, action);
	 	}
	}

	/**
	 * Convenience method to add a new group after the specified group.
	 * @param menu the menu to add the new group to
	 * @param existingGroup the group after which to insert the new group
	 * @param newGroup the new group
	 */
	protected final void addGroup(IMenuManager menu, String existingGroup, String newGroup) {
		IMenuManager subMenu= menu.findMenuUsingPath(existingGroup);
		if (subMenu != null)
			subMenu.add(new Separator(newGroup));
		else
			menu.appendToGroup(existingGroup, new Separator(newGroup));
	}

	/**
	 * Sets up the ruler context menu before it is made visible.
	 * <p>
	 * Subclasses may extend to add other actions.</p>
	 *
	 * @param menu the menu
	 */
	protected void rulerContextMenuAboutToShow(IMenuManager menu) {

		menu.add(new Separator(ITextEditorActionConstants.GROUP_REST));
		menu.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));

		for (IMenuListener iMenuListener : fRulerContextMenuListeners)
			iMenuListener.menuAboutToShow(menu);

		addAction(menu, ITextEditorActionConstants.RULER_MANAGE_BOOKMARKS);
		addAction(menu, ITextEditorActionConstants.RULER_MANAGE_TASKS);
	}

	/**
	 * Sets up this editor's context menu before it is made visible.
	 * <p>
	 * Subclasses may extend to add other actions.</p>
	 *
	 * @param menu the menu
	 */
	protected void editorContextMenuAboutToShow(IMenuManager menu) {

		menu.add(new Separator(ITextEditorActionConstants.GROUP_UNDO));
		menu.add(new GroupMarker(ITextEditorActionConstants.GROUP_SAVE));
		menu.add(new Separator(ITextEditorActionConstants.GROUP_COPY));
		menu.add(new Separator(ITextEditorActionConstants.GROUP_PRINT));
		menu.add(new Separator(ITextEditorActionConstants.GROUP_EDIT));
		menu.add(new Separator(ITextEditorActionConstants.GROUP_FIND));
		menu.add(new Separator(IWorkbenchActionConstants.GROUP_ADD));
		menu.add(new Separator(ITextEditorActionConstants.GROUP_REST));
		menu.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));

		if (isEditable()) {
			addAction(menu, ITextEditorActionConstants.GROUP_UNDO, ITextEditorActionConstants.UNDO);
			addAction(menu, ITextEditorActionConstants.GROUP_UNDO, ITextEditorActionConstants.REVERT_TO_SAVED);
			addAction(menu, ITextEditorActionConstants.GROUP_SAVE, ITextEditorActionConstants.SAVE);
			addAction(menu, ITextEditorActionConstants.GROUP_COPY, ITextEditorActionConstants.CUT);
			addAction(menu, ITextEditorActionConstants.GROUP_COPY, ITextEditorActionConstants.COPY);
			addAction(menu, ITextEditorActionConstants.GROUP_COPY, ITextEditorActionConstants.PASTE);
			IAction action= getAction(ITextEditorActionConstants.QUICK_ASSIST);
			if (action != null && action.isEnabled())
				addAction(menu, ITextEditorActionConstants.GROUP_EDIT, ITextEditorActionConstants.QUICK_ASSIST);
		} else {
			addAction(menu, ITextEditorActionConstants.GROUP_COPY, ITextEditorActionConstants.COPY);
		}
	}

	/**
	 * Returns the status line manager of this editor.
	 *
	 * @return the status line manager of this editor
	 * @since 2.0, protected since 3.3
	 */
	protected IStatusLineManager getStatusLineManager() {
		return getEditorSite().getActionBars().getStatusLineManager();
	}

	@SuppressWarnings("unchecked")
	@Override
	public <T> T getAdapter(Class<T> required) {

		if (IEditorStatusLine.class.equals(required)) {
			if (fEditorStatusLine == null) {
				IStatusLineManager statusLineManager= getStatusLineManager();
				ISelectionProvider selectionProvider= getSelectionProvider();
				if (statusLineManager != null && selectionProvider != null)
					fEditorStatusLine= new EditorStatusLine(statusLineManager, selectionProvider);
			}
			return (T) fEditorStatusLine;
		}

		if (IVerticalRulerInfo.class.equals(required)) {
			if (fVerticalRuler != null)
				return (T) fVerticalRuler;
		}

		if (IMarkRegionTarget.class.equals(required)) {
			if (fMarkRegionTarget == null) {
				IStatusLineManager manager= getStatusLineManager();
				if (manager != null)
					fMarkRegionTarget= (fSourceViewer == null ? null : new MarkRegionTarget(fSourceViewer, manager));
			}
			return (T) fMarkRegionTarget;
		}

		if (IDeleteLineTarget.class.equals(required)) {
			if (fDeleteLineTarget == null) {
				fDeleteLineTarget= new TextViewerDeleteLineTarget(fSourceViewer);
			}
			return (T) fDeleteLineTarget;
		}

		if (IncrementalFindTarget.class.equals(required)) {
			if (fIncrementalFindTarget == null) {
				IStatusLineManager manager= getStatusLineManager();
				if (manager != null)
					fIncrementalFindTarget= (fSourceViewer == null ? null : new IncrementalFindTarget(fSourceViewer, manager));
			}
			return (T) fIncrementalFindTarget;
		}

		if (IFindReplaceTarget.class.equals(required)) {
			if (fFindReplaceTarget == null) {
				IFindReplaceTarget target= (fSourceViewer == null ? null : fSourceViewer.getFindReplaceTarget());
				if (target != null) {
					fFindReplaceTarget= new FindReplaceTarget(this, target);
					if (fFindScopeHighlightColor != null)
						fFindReplaceTarget.setScopeHighlightColor(fFindScopeHighlightColor);
				}
			}
			return (T) fFindReplaceTarget;
		}

		if (ITextOperationTarget.class.equals(required))
			return (fSourceViewer == null ? null : (T) fSourceViewer.getTextOperationTarget());

		if (IRewriteTarget.class.equals(required)) {
			if (fSourceViewer instanceof ITextViewerExtension) {
				ITextViewerExtension extension= (ITextViewerExtension) fSourceViewer;
				return (T) extension.getRewriteTarget();
			}
			return null;
		}

		if (Control.class.equals(required))
			return fSourceViewer != null ? (T) fSourceViewer.getTextWidget() : null;

		if (IColumnSupport.class.equals(required)) {
			if (fColumnSupport == null)
				fColumnSupport= createColumnSupport();
			return (T) fColumnSupport;
		}

		if (ITextViewer.class.equals(required))
			return (fSourceViewer == null ? null : (T) fSourceViewer);

		return super.getAdapter(required);
	}

	@Override
	public void setFocus() {
		if (fSourceViewer != null) {
			StyledText widget= fSourceViewer.getTextWidget();
			if (widget != null && !widget.isDisposed()) {
				widget.setFocus();
			}
		}
	}

	@Override
	public boolean showsHighlightRangeOnly() {
		return fShowHighlightRangeOnly;
	}

	@Override
	public void showHighlightRangeOnly(boolean showHighlightRangeOnly) {
		fShowHighlightRangeOnly= showHighlightRangeOnly;
	}

	@Override
	public void setHighlightRange(int offset, int length, boolean moveCursor) {
		if (fSourceViewer == null)
			return;

		if (fShowHighlightRangeOnly) {
			if (moveCursor)
				fSourceViewer.setVisibleRegion(offset, length);
		} else {
			IRegion rangeIndication= fSourceViewer.getRangeIndication();
			if (rangeIndication == null || offset != rangeIndication.getOffset() || length != rangeIndication.getLength())
				fSourceViewer.setRangeIndication(offset, length, moveCursor);
		}
	}

	@Override
	public IRegion getHighlightRange() {
		if (fSourceViewer == null)
			return null;

		if (fShowHighlightRangeOnly)
			return getCoverage(fSourceViewer);

		return fSourceViewer.getRangeIndication();
	}

	/*
	 * @see ITextEditor#resetHighlightRange
	 */
	@Override
	public void resetHighlightRange() {
		if (fSourceViewer == null)
			return;

		if (fShowHighlightRangeOnly)
			fSourceViewer.resetVisibleRegion();
		else
			fSourceViewer.removeRangeIndication();
	}

	/**
	 * Adjusts the highlight range so that at least the specified range
	 * is highlighted.
	 * <p>
	 * Subclasses may re-implement this method.</p>
	 *
	 * @param offset the offset of the range which at least should be highlighted
	 * @param length the length of the range which at least should be highlighted
	 */
	protected void adjustHighlightRange(int offset, int length) {
		if (fSourceViewer == null)
			return;

		if (fSourceViewer instanceof ITextViewerExtension5) {
			ITextViewerExtension5 extension= (ITextViewerExtension5) fSourceViewer;
			extension.exposeModelRange(new Region(offset, length));
		} else if (!isVisible(fSourceViewer, offset, length)) {
			fSourceViewer.resetVisibleRegion();
		}
	}

	@Override
	public void selectAndReveal(int start, int length) {
		selectAndReveal(start, length, start, length);
	}

	/**
	 * Selects and reveals the specified ranges in this text editor.
	 *
	 * @param selectionStart the offset of the selection
	 * @param selectionLength the length of the selection
	 * @param revealStart the offset of the revealed range
	 * @param revealLength the length of the revealed range
	 * @since 3.0
	 */
	protected void selectAndReveal(int selectionStart, int selectionLength, int revealStart, int revealLength) {
		if (fSourceViewer == null)
			return;

		ISelection selection= getSelectionProvider().getSelection();
		if (selection instanceof ITextSelection) {
			ITextSelection textSelection= (ITextSelection) selection;
			if (textSelection.getOffset() != 0 || textSelection.getLength() != 0)
				markInNavigationHistory();
		}

		StyledText widget= fSourceViewer.getTextWidget();
		widget.setRedraw(false);
		adjustHighlightRange(revealStart, revealLength);
		fSourceViewer.revealRange(revealStart, revealLength);

		fSourceViewer.setSelectedRange(selectionStart, selectionLength);

		markInNavigationHistory();
		widget.setRedraw(true);
	}

	/*
	 * @see org.eclipse.ui.INavigationLocationProvider#createNavigationLocation()
	 * @since 2.1
	 */
	@Override
	public INavigationLocation createEmptyNavigationLocation() {
		return new TextSelectionNavigationLocation(this, false);
	}

	@Override
	public INavigationLocation createNavigationLocation() {
		return new TextSelectionNavigationLocation(this, true);
	}

	/**
	 * Writes a check mark of the given situation into the navigation history.
	 * @since 2.1
	 */
	protected void markInNavigationHistory() {
		getSite().getPage().getNavigationHistory().markLocation(this);
	}

	/**
	 * Hook which gets called when the editor has been saved.
	 * Subclasses may extend.
	 * @since 2.1
	 */
	protected void editorSaved() {
		IEditorInput input= getEditorInput();
		for (INavigationLocation location2 : getSite().getPage().getNavigationHistory().getLocations()) {
			if (location2 instanceof TextSelectionNavigationLocation) {
				if(input.equals(location2.getInput())) {
					TextSelectionNavigationLocation location= (TextSelectionNavigationLocation) location2;
					location.partSaved(this);
				}
			}
		}
	}

	@Override
	protected void firePropertyChange(int property) {
		super.firePropertyChange(property);
		updatePropertyDependentActions();
	}

	@Override
	public void setStatusField(IStatusField field, String category) {
		Assert.isNotNull(category);
		if (field != null) {

			if (fStatusFields == null)
				fStatusFields= new HashMap<>(3);

			fStatusFields.put(category, field);
			updateStatusField(category);

		} else if (fStatusFields != null)
			fStatusFields.remove(category);

		if (fIncrementalFindTarget != null && ITextEditorActionConstants.STATUS_CATEGORY_FIND_FIELD.equals(category))
			fIncrementalFindTarget.setStatusField(field);
	}

	/**
	 * Returns the current status field for the given status category.
	 *
	 * @param category the status category
	 * @return the current status field for the given status category
	 * @since 2.0
	 */
	protected IStatusField getStatusField(String category) {
		if (category != null && fStatusFields != null)
			return fStatusFields.get(category);
		return null;
	}

	/**
	 * Returns whether this editor is in overwrite or insert mode.
	 *
	 * @return <code>true</code> if in insert mode, <code>false</code> for overwrite mode
	 * @since 2.0
	 */
	protected boolean isInInsertMode() {
		return !fIsOverwriting;
	}

	@Override
	public InsertMode getInsertMode() {
		return fInsertMode;
	}

	@Override
	public void setInsertMode(InsertMode newMode) {
		List<InsertMode> legalModes= getLegalInsertModes();
		if (!legalModes.contains(newMode))
			throw new IllegalArgumentException();

		fInsertMode= newMode;

		handleInsertModeChanged();
	}

	/**
	 * Returns the set of legal insert modes. If insert modes are configured all defined insert modes
	 * are legal.
	 *
	 * @return the set of legal insert modes
	 * @since 3.0
	 */
	protected List<InsertMode> getLegalInsertModes() {
		if (fLegalInsertModes == null) {
			fLegalInsertModes= new ArrayList<>();
			fLegalInsertModes.add(SMART_INSERT);
			fLegalInsertModes.add(INSERT);
		}
		return fLegalInsertModes;
	}

	private void switchToNextInsertMode() {

		InsertMode mode= getInsertMode();
		List<InsertMode> legalModes= getLegalInsertModes();

		int i= 0;
		while (i < legalModes.size()) {
			if (legalModes.get(i) == mode) break;
			++ i;
		}

		i= (i + 1) % legalModes.size();
		InsertMode newMode= legalModes.get(i);
		setInsertMode(newMode);
	}

	private void toggleOverwriteMode() {
		if (fIsOverwriteModeEnabled) {
			fIsOverwriting= !fIsOverwriting;
			fSourceViewer.getTextWidget().invokeAction(ST.TOGGLE_OVERWRITE);
			handleInsertModeChanged();
		}
	}

	/**
	 * Configures the given insert mode as legal or illegal. This call is ignored if the set of legal
	 * input modes would be empty after the call.
	 *
	 * @param mode the insert mode to be configured
	 * @param legal <code>true</code> if the given mode is legal, <code>false</code> otherwise
	 * @since 3.0
	 */
	protected void configureInsertMode(InsertMode mode, boolean legal) {
		List<InsertMode> legalModes= getLegalInsertModes();
		if (legal) {
			if (!legalModes.contains(mode))
				legalModes.add(mode);
		} else if (legalModes.size() > 1) {
			if (getInsertMode() == mode)
				switchToNextInsertMode();
			legalModes.remove(mode);
		}
	}

	/**
	 * Sets the overwrite mode enablement.
	 *
	 * @param enable <code>true</code> to enable new overwrite mode,
	 *        <code>false</code> to disable
	 * @since 3.0
	 */
	protected void enableOverwriteMode(boolean enable) {
		if (fIsOverwriting && !enable)
			toggleOverwriteMode();
		fIsOverwriteModeEnabled= enable;
	}

	private Caret createOverwriteCaret(StyledText styledText) {
		Caret caret= new Caret(styledText, SWT.NULL);
		GC gc= new GC(styledText);
		// XXX: this overwrite box is not proportional-font aware
		// take 'a' as a medium sized character
		Point charSize= gc.stringExtent("a"); //$NON-NLS-1$

		// XXX: Filed request to get a caret with auto-height: https://bugs.eclipse.org/bugs/show_bug.cgi?id=118612
		caret.setSize(charSize.x, styledText.getLineHeight());
		caret.setFont(styledText.getFont());

		gc.dispose();

		return caret;
	}

	private Caret createInsertCaret(StyledText styledText) {
		Caret caret= new Caret(styledText, SWT.NULL);

		// XXX: Filed request to get a caret with auto-height: https://bugs.eclipse.org/bugs/show_bug.cgi?id=118612
		caret.setSize(getCaretWidthPreference(), styledText.getLineHeight());
		caret.setFont(styledText.getFont());

		return caret;
	}

	private Image createRawInsertModeCaretImage(StyledText styledText) {

		PaletteData caretPalette= new PaletteData(new RGB[] {new RGB (0,0,0), new RGB (255,255,255)});
		int width= getCaretWidthPreference();
		int widthOffset= width - 1;

		// XXX: Filed request to get a caret with auto-height: https://bugs.eclipse.org/bugs/show_bug.cgi?id=118612
		ImageData imageData= new ImageData(4 + widthOffset, styledText.getLineHeight(), 1, caretPalette);

		Display display= styledText.getDisplay();
		Image bracketImage= new Image(display, imageData);
		GC gc= new GC (bracketImage);
		gc.setForeground(display.getSystemColor(SWT.COLOR_WHITE));
		gc.setLineWidth(0); // NOTE: 0 means width is 1 but with optimized performance
		int height= imageData.height / 3;
		// gap between two bars of one third of the height
		// draw boxes using lines as drawing a line of a certain width produces
		// rounded corners.
		for (int i= 0; i < width ; i++) {
			gc.drawLine(i, 0, i, height - 1);
			gc.drawLine(i, imageData.height - height, i, imageData.height - 1);
		}

		gc.dispose();

		return bracketImage;
	}

	private Caret createRawInsertModeCaret(StyledText styledText) {
		// don't draw special raw caret if no smart mode is enabled
		if (!getLegalInsertModes().contains(SMART_INSERT))
			return createInsertCaret(styledText);

		Caret caret= new Caret(styledText, SWT.NULL);
		Image image= createRawInsertModeCaretImage(styledText);
		caret.setImage(image);
		caret.setFont(styledText.getFont());

		return caret;
	}

	private int getCaretWidthPreference() {
		if (getPreferenceStore() != null && getPreferenceStore().getBoolean(PREFERENCE_WIDE_CARET))
			return WIDE_CARET_WIDTH;

		return SINGLE_CARET_WIDTH;
	}

	private void updateCaret() {
		if (fSourceViewer == null || fSourceViewer.getTextWidget() == null) {
			return;
		}

		StyledText styledText= fSourceViewer.getTextWidget();

		InsertMode mode= getInsertMode();

		styledText.setCaret(null);
		disposeNonDefaultCaret();

		if (getPreferenceStore() == null || !getPreferenceStore().getBoolean(PREFERENCE_USE_CUSTOM_CARETS))
			Assert.isTrue(fNonDefaultCaret == null);
		else if (fIsOverwriting)
			fNonDefaultCaret= createOverwriteCaret(styledText);
		else if (SMART_INSERT == mode)
			fNonDefaultCaret= createInsertCaret(styledText);
		else if (INSERT == mode)
			fNonDefaultCaret= createRawInsertModeCaret(styledText);

		if (fNonDefaultCaret != null) {
			styledText.setCaret(fNonDefaultCaret);
			fNonDefaultCaretImage= fNonDefaultCaret.getImage();
		} else if (fInitialCaret != styledText.getCaret())
			styledText.setCaret(fInitialCaret);
	}

	private void disposeNonDefaultCaret() {
		if (fNonDefaultCaretImage != null) {
			fNonDefaultCaretImage.dispose();
			fNonDefaultCaretImage= null;
		}

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

	/**
	 * Handles a change of the editor's insert mode.
	 * Subclasses may extend.
	 *
	 * @since 2.0
	 */
	protected void handleInsertModeChanged() {
		updateInsertModeAction();
		updateCaret();
		updateStatusField(ITextEditorActionConstants.STATUS_CATEGORY_INPUT_MODE);
	}

	private void updateInsertModeAction() {

		// this may be called before the part is fully initialized (see configureInsertMode)
		// drop out in this case.
		if (getSite() == null)
			return;

		IAction action= getAction(ITextEditorActionConstants.TOGGLE_INSERT_MODE);
		if (action != null) {
			action.setEnabled(!fIsOverwriting);
			action.setChecked(fInsertMode == SMART_INSERT);
		}
	}

	/**
	 * Prepares to handles a potential change of the cursor position. Wraps the
	 * actual handler which cannot itself be modified for fear of disrupting
	 * existing subclasses which may have overridden it without calling
	 * super.handleCursorPositionChanged()
	 *
	 * @since 3.15
	 */
	private void handleCursorPositionChangedWrapper() {
		TextEditorPlugin.getDefault()
				.setEditHistoryTraversalDirection(TextEditorPlugin.TraversalDirection.NONE);
		handleCursorPositionChanged();
	}

	/**
	 * Handles a potential change of the cursor position. Subclasses may extend.
	 *
	 * @since 2.0
	 */
	protected void handleCursorPositionChanged() {
		updateStatusField(ITextEditorActionConstants.STATUS_CATEGORY_INPUT_POSITION);
	}

	/**
	 * Updates the status fields for the given category.
	 *
	 * @param category the category
	 * @since 2.0
	 */
	protected void updateStatusField(String category) {

		if (category == null)
			return;

		IStatusField field= getStatusField(category);
		if (field != null) {

			String text= null;

			switch (category) {
			case ITextEditorActionConstants.STATUS_CATEGORY_INPUT_POSITION:
				text= getCursorPosition();
				break;
			case ITextEditorActionConstants.STATUS_CATEGORY_ELEMENT_STATE:
				text= isEditorInputReadOnly() ? fReadOnlyLabel : fWritableLabel;
				break;
			case ITextEditorActionConstants.STATUS_CATEGORY_INPUT_MODE:
				InsertMode mode= getInsertMode();
				if (fIsOverwriting)
					text= fOverwriteModeLabel;
				else if (INSERT == mode)
					text= fInsertModeLabel;
				else if (SMART_INSERT == mode)
					text= fSmartInsertModeLabel;
				break;
			default:
				break;
			}

			field.setText(text == null ? fErrorLabel : text);
		}
	}

	/**
	 * Updates all status fields.
	 *
	 * @since 2.0
	 */
	protected void updateStatusFields() {
		if (fStatusFields != null) {
			Iterator<String> e= fStatusFields.keySet().iterator();
			while (e.hasNext())
				updateStatusField(e.next());
		}
	}

	/**
	 * Returns a description of the cursor position.
	 *
	 * @return a description of the cursor position
	 * @since 2.0
	 */
	protected String getCursorPosition() {

		if (fSourceViewer == null)
			return fErrorLabel;

		StyledText styledText= fSourceViewer.getTextWidget();
		int caret= widgetOffset2ModelOffset(fSourceViewer, styledText.getCaretOffset());
		IDocument document= fSourceViewer.getDocument();
		if (document == null)
			return fErrorLabel;

		try {

			int line= document.getLineOfOffset(caret);

			int lineOffset= document.getLineOffset(line);
			int tabWidth= styledText.getTabs();
			int column= 0;
			for (int i= lineOffset; i < caret; i++)
				if ('\t' == document.getChar(i))
					column += tabWidth - (tabWidth == 0 ? 0 : column % tabWidth);
				else
					column++;

			fLineLabel.fValue= line + 1;
			fColumnLabel.fValue= column + 1;
			boolean showSelection = getPreferenceStore().getBoolean(PREFERENCE_SHOW_SELECTION_SIZE);
			boolean showOffset = getPreferenceStore().getBoolean(PREFERENCE_SHOW_CARET_OFFSET);
			Point selectedRange = fSourceViewer.getSelectedRange();
			int selectionLength = selectedRange != null ? selectedRange.y : 0;
			showSelection = showSelection && selectionLength > 0;
			fOffsetLabel.fValue = showSelection ? selectionLength : caret;
			if (!showSelection) {
				if (!showOffset) {
					// shows line : column
					return NLSUtility.format(fPositionLabelPattern, fPositionLabelPatternArguments);
				}
				// shows line : column : offset
				return NLSUtility.format(EditorMessages.Editor_statusline_position_pattern_offset,
						fPositionLabelPatternArguments);
			}
			// To show *right* selection, we first need to know if we are in the
			// block selection mode or not
			if (isBlockSelectionModeSupported() && isBlockSelectionModeEnabled()) {
				BlockTextSelection block = (BlockTextSelection) fSourceViewer.getSelectionProvider().getSelection();
				AtomicInteger sum = new AtomicInteger();
				Arrays.asList(block.getRegions()).forEach(r -> sum.addAndGet(r.getLength()));
				fOffsetLabel.fValue = sum.intValue();
			}
			// shows line : column [selection size]
			return NLSUtility.format(EditorMessages.Editor_statusline_position_pattern_selection,
					fPositionLabelPatternArguments);
		} catch (BadLocationException x) {
			return fErrorLabel;
		}
	}

	@Override
	public boolean isEditorInputReadOnly() {
		IDocumentProvider provider= getDocumentProvider();
		if (provider instanceof IDocumentProviderExtension) {
			IDocumentProviderExtension extension= (IDocumentProviderExtension) provider;
			return extension.isReadOnly(getEditorInput());
		}
		return true;
	}

	@Override
	public boolean isEditorInputModifiable() {
		IDocumentProvider provider= getDocumentProvider();
		if (provider instanceof IDocumentProviderExtension) {
			IDocumentProviderExtension extension= (IDocumentProviderExtension) provider;
			return extension.isModifiable(getEditorInput());
		}
		return true;
	}

	@Override
	public void addRulerContextMenuListener(IMenuListener listener) {
		fRulerContextMenuListeners.add(listener);
	}

	@Override
	public void removeRulerContextMenuListener(IMenuListener listener) {
		fRulerContextMenuListeners.remove(listener);
	}

	/**
	 * Returns whether this editor can handle the move of the original element
	 * so that it ends up being the moved element. By default this method
	 * returns <code>true</code>. Subclasses may reimplement.
	 *
	 * @param originalElement the original element
	 * @param movedElement the moved element
	 * @return whether this editor can handle the move of the original element
	 *         so that it ends up being the moved element
	 * @since 2.0
	 */
	protected boolean canHandleMove(IEditorInput originalElement, IEditorInput movedElement) {
		return true;
	}

	/**
	 * Returns the offset of the given source viewer's document that corresponds
	 * to the given widget offset or <code>-1</code> if there is no such offset.
	 *
	 * @param viewer the source viewer
	 * @param widgetOffset the widget offset
	 * @return the corresponding offset in the source viewer's document or <code>-1</code>
	 * @since 2.1
	 */
	protected static final int widgetOffset2ModelOffset(ISourceViewer viewer, int widgetOffset) {
		if (viewer instanceof ITextViewerExtension5) {
			ITextViewerExtension5 extension= (ITextViewerExtension5) viewer;
			return extension.widgetOffset2ModelOffset(widgetOffset);
		}
		return widgetOffset + viewer.getVisibleRegion().getOffset();
	}

	/**
	 * Returns the offset of the given source viewer's text widget that corresponds
	 * to the given model offset or <code>-1</code> if there is no such offset.
	 *
	 * @param viewer the source viewer
	 * @param modelOffset the model offset
	 * @return the corresponding offset in the source viewer's text widget or <code>-1</code>
	 * @since 3.0
	 */
	protected static final int modelOffset2WidgetOffset(ISourceViewer viewer, int modelOffset) {
		if (viewer instanceof ITextViewerExtension5) {
			ITextViewerExtension5 extension= (ITextViewerExtension5) viewer;
			return extension.modelOffset2WidgetOffset(modelOffset);
		}
		return modelOffset - viewer.getVisibleRegion().getOffset();
	}

	/**
	 * Returns the minimal region of the given source viewer's document that completely
	 * comprises everything that is visible in the viewer's widget.
	 *
	 * @param viewer the viewer go return the coverage for
	 * @return the minimal region of the source viewer's document comprising the contents of the viewer's widget
	 * @since 2.1
	 */
	protected static final IRegion getCoverage(ISourceViewer viewer) {
		if (viewer instanceof ITextViewerExtension5) {
			ITextViewerExtension5 extension= (ITextViewerExtension5) viewer;
			return extension.getModelCoverage();
		}
		return viewer.getVisibleRegion();
	}

	/**
	 * Tells whether the given region is visible in the given source viewer.
	 *
	 * @param viewer the source viewer
	 * @param offset the offset of the region
	 * @param length the length of the region
	 * @return <code>true</code> if visible
	 * @since 2.1
	 */
	protected static final boolean isVisible(ISourceViewer viewer, int offset, int length) {
		if (viewer instanceof ITextViewerExtension5) {
			ITextViewerExtension5 extension= (ITextViewerExtension5) viewer;
			IRegion overlap= extension.modelRange2WidgetRange(new Region(offset, length));
			return overlap != null;
		}
		return viewer.overlapsWithVisibleRegion(offset, length);
	}

	@Override
	public void showChangeInformation(boolean show) {
		// do nothing
	}

	@Override
	public boolean isChangeInformationShowing() {
		return false;
	}

	/**
	 * Sets the given message as error message to this editor's status line.
	 *
	 * @param message message to be set
	 * @since 3.2
	 */
	protected void setStatusLineErrorMessage(String message) {
		IEditorStatusLine statusLine= getAdapter(IEditorStatusLine.class);
		if (statusLine != null)
			statusLine.setMessage(true, message, null);
	}

	/**
	 * Sets the given message as message to this editor's status line.
	 *
	 * @param message message to be set
	 * @since 3.2
	 */
	protected void setStatusLineMessage(String message) {
		IEditorStatusLine statusLine= getAdapter(IEditorStatusLine.class);
		if (statusLine != null)
			statusLine.setMessage(false, message, null);
	}

	/**
	 * Jumps to the next annotation according to the given direction.
	 *
	 * @param forward <code>true</code> if search direction is forward, <code>false</code> if backward
	 * @return the selected annotation or <code>null</code> if none
	 * @see #isNavigationTarget(Annotation)
	 * @see #findAnnotation(int, int, boolean, Position)
	 * @since 3.2
	 */
	@Override
	public Annotation gotoAnnotation(boolean forward) {
		ITextSelection selection= (ITextSelection) getSelectionProvider().getSelection();
		Position position= new Position(0, 0);
		Annotation annotation= findAnnotation(selection.getOffset(), selection.getLength(), forward, position);
		setStatusLineErrorMessage(null);
		setStatusLineMessage(null);

		if (annotation != null) {
			selectAndReveal(position.getOffset(), position.getLength());
			setStatusLineMessage(annotation.getText());
		}
		return annotation;
	}

	/**
	 * Returns the annotation closest to the given range respecting the given
	 * direction. If an annotation is found, the annotations current position
	 * is copied into the provided annotation position.
	 *
	 * @param offset the region offset
	 * @param length the region length
	 * @param forward <code>true</code> for forwards, <code>false</code> for backward
	 * @param annotationPosition the position of the found annotation
	 * @return the found annotation
	 * @since 3.2
	 */
	protected Annotation findAnnotation(final int offset, final int length, boolean forward, Position annotationPosition) {

		Annotation nextAnnotation= null;
		Position nextAnnotationPosition= null;
		Annotation containingAnnotation= null;
		Position containingAnnotationPosition= null;
		boolean currentAnnotation= false;

		IDocument document= getDocumentProvider().getDocument(getEditorInput());
		int endOfDocument = 0;
		if (document != null) {
			endOfDocument = document.getLength();
		}
		int distance= Integer.MAX_VALUE;

		IAnnotationModel model= getDocumentProvider().getAnnotationModel(getEditorInput());
		Iterator<Annotation> e= model.getAnnotationIterator();
		while (e.hasNext()) {
			Annotation a= e.next();
			if (!isNavigationTarget(a))
				continue;

			Position p= model.getPosition(a);
			if (p == null)
				continue;

			if (forward && p.offset == offset || !forward && p.offset + p.getLength() == offset + length) {// || p.includes(offset)) {
				if (containingAnnotation == null || (forward && p.length >= containingAnnotationPosition.length || !forward && p.length >= containingAnnotationPosition.length)) {
					containingAnnotation= a;
					containingAnnotationPosition= p;
					currentAnnotation= p.length == length;
				}
			} else {
				int currentDistance= 0;

				if (forward) {
					currentDistance= p.getOffset() - offset;
					if (currentDistance < 0)
						currentDistance= endOfDocument + currentDistance;

					if (currentDistance < distance || currentDistance == distance && p.length < nextAnnotationPosition.length) {
						distance= currentDistance;
						nextAnnotation= a;
						nextAnnotationPosition= p;
					}
				} else {
					currentDistance= offset + length - (p.getOffset() + p.length);
					if (currentDistance < 0)
						currentDistance= endOfDocument + currentDistance;

					if (currentDistance < distance || currentDistance == distance && p.length < nextAnnotationPosition.length) {
						distance= currentDistance;
						nextAnnotation= a;
						nextAnnotationPosition= p;
					}
				}
			}
		}
		if (containingAnnotationPosition != null && (!currentAnnotation || nextAnnotation == null)) {
			annotationPosition.setOffset(containingAnnotationPosition.getOffset());
			annotationPosition.setLength(containingAnnotationPosition.getLength());
			return containingAnnotation;
		}
		if (nextAnnotationPosition != null) {
			annotationPosition.setOffset(nextAnnotationPosition.getOffset());
			annotationPosition.setLength(nextAnnotationPosition.getLength());
		}

		return nextAnnotation;
	}

	/**
	 * Returns whether the given annotation is configured as a target for the
	 * "Go to Next/Previous Annotation" actions.
	 * <p>
	 * Per default every annotation is a target.
	 * </p>
	 *
	 * @param annotation the annotation
	 * @return <code>true</code> if this is a target, <code>false</code> otherwise
	 * @since 3.2
	 */
	protected boolean isNavigationTarget(Annotation annotation) {
		return true;
	}

	@Override
	public void showRevisionInformation(RevisionInformation info, String quickDiffProviderId) {
		// no implementation
	}

	@Override
	public void restoreState(IMemento memento) {
		fMementoToRestore= memento;
	}

	@Override
	public void saveState(IMemento memento) {
		ISelection selection= doGetSelection();
		if (selection instanceof ITextSelection) {
			memento.putInteger(TAG_SELECTION_OFFSET, ((ITextSelection)selection).getOffset());
			memento.putInteger(TAG_SELECTION_LENGTH, ((ITextSelection)selection).getLength());
		}
		final StyledText textWidget= fSourceViewer.getTextWidget();
		memento.putInteger(TAG_SELECTION_TOP_PIXEL, textWidget.getTopPixel());
		memento.putInteger(TAG_SELECTION_HORIZONTAL_PIXEL, textWidget.getHorizontalPixel());
	}

	/**
	 * Returns whether the given memento contains saved state
	 * <p>
	 * Subclasses may extend or override this method.</p>
	 *
	 * @param memento the saved state of this editor
	 * @return <code>true</code> if the given memento contains saved state
	 * @since 3.3
	 */
	protected boolean containsSavedState(IMemento memento) {
		return memento.getInteger(TAG_SELECTION_OFFSET) != null && memento.getInteger(TAG_SELECTION_LENGTH) != null;
	}

	/**
	 * Restores this editor's state using the given memento.
	 * <p>
	 * Subclasses may extend or override this method.</p>
	 *
	 * @param memento the saved state of this editor
	 * @since 3.3
	 */
	protected void doRestoreState(IMemento memento) {
		Integer offset= memento.getInteger(TAG_SELECTION_OFFSET);
		if (offset == null)
			return;

		Integer length= memento.getInteger(TAG_SELECTION_LENGTH);
		if (length == null)
			return;

		doSetSelection(new TextSelection(offset.intValue(), length.intValue()));

		final StyledText textWidget= fSourceViewer.getTextWidget();

		Integer topPixel= memento.getInteger(TAG_SELECTION_TOP_PIXEL);
		if (topPixel != null)
			textWidget.setTopPixel(topPixel.intValue());

		Integer horizontalPixel= memento.getInteger(TAG_SELECTION_HORIZONTAL_PIXEL);
		if (horizontalPixel != null)
			textWidget.setHorizontalPixel(horizontalPixel.intValue());
	}

	@Override
	public Saveable[] getSaveables() {
		if (fSavable == null)
			fSavable= new TextEditorSavable(this);

		return new Saveable[] { fSavable };
	}

	@Override
	public Saveable[] getActiveSaveables() {
		return getSaveables();
	}

	/**
	 * This text editor's savable.
	 *
	 * @since 3.3
	 */
	protected static class TextEditorSavable extends Saveable {

		/** The cached editor. */
		private ITextEditor fTextEditor;
		/** The cached editor input. */
		private IEditorInput fEditorInput;
		/** The cached document. */
		private IDocument fDocument;

		/** for debug only. see Bug 569286 **/
		private Exception disconnectStack;
		private boolean disconnectStackShown;

		/**
		 * Creates a new savable for this text editor.
		 *
		 * @param textEditor the text editor
		 */
		public TextEditorSavable(ITextEditor textEditor) {
			Assert.isLegal(textEditor != null);
			fTextEditor= textEditor;
			fEditorInput= fTextEditor.getEditorInput();
			Assert.isLegal(fEditorInput != null);
		}

		/**
		 * Disconnects the editor from this savable.
		 */
		public void disconnectEditor() {
			getAdapter(IDocument.class); // make sure the document is cached
			if (disconnectStack == null && !disconnectStackShown) {
				disconnectStack = new IllegalStateException(
						"Disconnected before saving. Please post stacktrace to https://bugs.eclipse.org/bugs/show_bug.cgi?id=569286 " //$NON-NLS-1$
								+ fTextEditor.getClass().getName() + " " + getName()); //$NON-NLS-1$
			}
			fTextEditor = null;
		}

		@Override
		public String getName() {
			return fEditorInput.getName();
		}

		@Override
		public String getToolTipText() {
			return fEditorInput.getToolTipText();
		}

		@Override
		public ImageDescriptor getImageDescriptor() {
			return fEditorInput.getImageDescriptor();
		}

		@Override
		public void doSave(IProgressMonitor monitor) throws CoreException {
			ITextEditor textEditor = fTextEditor;
			if (textEditor == null) { // disconnected Editor - for example due to disposed
				// This should not happen. Code added to handle the below bug.
				// https://bugs.eclipse.org/bugs/show_bug.cgi?id=569286
				if (disconnectStack != null && !disconnectStackShown) {
					Bundle bundle = Platform.getBundle(PlatformUI.PLUGIN_ID);
					ILog log = Platform.getLog(bundle);
					disconnectStack.addSuppressed(new IllegalStateException("doSave after disconnect")); //$NON-NLS-1$
					Status status = new Status(IStatus.ERROR, TextEditorPlugin.PLUGIN_ID, null, disconnectStack);
					log.log(status);
					disconnectStackShown = true; // shut up
				}
				return;
			}
			textEditor.doSave(monitor);
		}

		@Override
		public boolean isDirty() {
			ITextEditor textEditor = fTextEditor;
			if (textEditor == null) { // disconnected Editor - for example due to disposed
				// This should not happen. Code added to handle the below bug.
				// https://bugs.eclipse.org/bugs/show_bug.cgi?id=569286
				if (disconnectStack != null && !disconnectStackShown) {
					Bundle bundle = Platform.getBundle(PlatformUI.PLUGIN_ID);
					ILog log = Platform.getLog(bundle);
					disconnectStack.addSuppressed(new IllegalStateException("isDirty check after disconnect")); //$NON-NLS-1$
					Status status = new Status(IStatus.ERROR, TextEditorPlugin.PLUGIN_ID, disconnectStack.getMessage(),
							disconnectStack);
					log.log(status);
					disconnectStackShown = true; // shut up
				}
				return false;
			}
			return textEditor.isDirty();
		}

		/*
		 * @see org.eclipse.ui.Saveable#supportsBackgroundSave()
		 */
		public boolean supportsBackgroundSave() {
			return false;
		}

		@Override
		public int hashCode() {
			Object document= getAdapter(IDocument.class);
			if (document == null)
				return 0;
			return document.hashCode();
		}

		@Override
		public boolean equals(Object obj) {
			if (this == obj)
				return true;

			if (!(obj instanceof Saveable))
				return false;

			Object thisDocument= getAdapter(IDocument.class);
			Object otherDocument= ((Saveable)obj).getAdapter(IDocument.class);

			if (thisDocument == null && otherDocument == null)
				return true;

			return thisDocument != null && thisDocument.equals(otherDocument);
		}

		/**
		 * Explicit comment needed to suppress wrong warning caused by
		 * http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4848177
		 *
		 * @see org.eclipse.ui.Saveable#getAdapter(java.lang.Class)
		 */
		@SuppressWarnings("unchecked")
		@Override
		public <T> T getAdapter(Class<T> adapter) {
			if (adapter == IDocument.class) {
				if (fDocument == null) {
					IDocumentProvider documentProvider= fTextEditor.getDocumentProvider();
					if (documentProvider != null)
						fDocument= documentProvider.getDocument(fEditorInput);
				}
				return (T) fDocument;
			}
			return super.getAdapter(adapter);
		}
	}

	//---- Tabs to spaces conversion support ------------------

	/**
	 * Installs a tabs to spaces converter.
	 *
	 * <p>Subclasses may extend or override this method.</p>
	 *
	 * @since 3.3
	 */
	protected void installTabsToSpacesConverter() {
		SourceViewerConfiguration config= getSourceViewerConfiguration();
		if (config != null && fSourceViewer instanceof ITextViewerExtension7) {
			int tabWidth= config.getTabWidth(fSourceViewer);
			TabsToSpacesConverter tabToSpacesConverter= new TabsToSpacesConverter();
			tabToSpacesConverter.setLineTracker(new DefaultLineTracker());
			tabToSpacesConverter.setNumberOfSpacesPerTab(tabWidth);
			tabToSpacesConverter.setDeleteSpacesAsTab(isSpacesAsTabsDeletionEnabled());
			((ITextViewerExtension7)fSourceViewer).setTabsToSpacesConverter(tabToSpacesConverter);
			updateIndentPrefixes();
		}
	}

	/**
	 * Installs a tabs to spaces converter.
	 *
	 * <p>Subclasses may extend or override this method.</p>
	 *
	 * @since 3.3
	 */
	protected void uninstallTabsToSpacesConverter() {
		if (fSourceViewer instanceof ITextViewerExtension7) {
			((ITextViewerExtension7)fSourceViewer).setTabsToSpacesConverter(null);
			if (fSourceViewer.getTextWidget() != null)
				updateIndentPrefixes();
		}
	}

	/**
	 * Tells whether tabs should be converted to
	 * spaces while editing inside this editor.
	 *
	 * <p>Subclasses may override this method.</p>
	 *
	 * @return <code>true</code> if tabs should be converted to spaces
	 * @since 3.3
	 */
	protected boolean isTabsToSpacesConversionEnabled() {
		return false;
	}

	/**
	 * Tells whether delete and backspace keys should remove multiple spaces as
	 * if they were a tab. Only relevant when
	 * {@link #isTabsToSpacesConversionEnabled()} returns true.
	 *
	 * <p>
	 * Subclasses may override this method.
	 * </p>
	 *
	 * @return <code>true</code> if spaces should be removed as tabs
	 * @since 3.14
	 */
	protected boolean isSpacesAsTabsDeletionEnabled() {
		return false;
	}

	/**
	 * Updates the source viewer's indent prefixes with
	 * the values provided by the source viewer configuration.
	 *
	 * @since 3.3
	 */
	protected final void updateIndentPrefixes() {
		SourceViewerConfiguration configuration= getSourceViewerConfiguration();
		for (String type : configuration.getConfiguredContentTypes(fSourceViewer)) {
			String[] prefixes= configuration.getIndentPrefixes(fSourceViewer, type);
			if (prefixes != null && prefixes.length > 0)
				fSourceViewer.setIndentPrefixes(prefixes, type);
		}
	}

	/**
	 * Tells whether selection mode is supported.
	 * <p>
	 * By default block selection mode is supported. Subclasses may override this method to disable
	 * it.
	 * </p>
	 *
	 * @return <code>true</code> if block selection mode is supported, <code>false</code> otherwise
	 * @since 3.5
	 */
	protected boolean isBlockSelectionModeSupported() {
		return true;
	}

	/**
	 * @see org.eclipse.ui.texteditor.ITextEditorExtension5#isBlockSelectionModeEnabled()
	 * @since 3.5
	 */
	@Override
	public final boolean isBlockSelectionModeEnabled() {
		ISourceViewer viewer= getSourceViewer();
		if (viewer != null) {
			StyledText styledText= viewer.getTextWidget();
			if (styledText != null)
				return styledText.getBlockSelection();
		}
		return false;
	}

	/**
	 * @see org.eclipse.ui.texteditor.ITextEditorExtension5#setBlockSelectionMode(boolean)
	 * @since 3.5
	 */
	@Override
	public void setBlockSelectionMode(boolean enable) {
		if (!isBlockSelectionModeSupported())
			return;

		ISourceViewer viewer= getSourceViewer();
		if (viewer != null) {
			StyledText styledText= viewer.getTextWidget();
			if (styledText != null) {
				/*
				 * Font switching. block selection mode needs a monospace font.
				 *  - set the font _before enabling_ block selection mode in order to maintain the
				 * selection
				 * - revert the font _after disabling_ block selection mode in order to maintain the
				 * selection
				 */
				if (enable) {
					Font blockFont= JFaceResources.getFont(BLOCK_SELECTION_MODE_FONT);
					Font normalFont= styledText.getFont();
					if (!blockFont.equals(normalFont) && !normalFont.getFontData()[0].equals(blockFont.getFontData()[0])) {
						setFont(viewer, blockFont);
						disposeFont();
						updateCaret();
					}

					// we must unset word wrap before we can set block selection
					if (isWordWrapEnabled()) {
						setWordWrap(false);
					}
				}

				styledText.setBlockSelection(enable);

				if (!enable) {
					initializeViewerFont(viewer);
					updateCaret();
				}
			}
		}
	}

	/**
	 * Tells whether word wrap is supported.
	 * <p>
	 * By default word wrap is supported. Subclasses may override this method to disable
	 * it.
	 * </p>
	 *
	 * @return <code>true</code> if word wrap is supported, <code>false</code> otherwise
	 * @since 3.10
	 */
	protected boolean isWordWrapSupported() {
		return true;
	}

	/**
	 * <code>true</code> if word wrap is supported and enabled, <code>false</code> otherwise
	 * @return the receiver's word wrap state if word wrap is supported
	 * @since 3.10
	 * @see AbstractTextEditor#isWordWrapSupported()
	 */
	@Override
	public final boolean isWordWrapEnabled() {
		if (!isWordWrapSupported()) {
			return false;
		}
		ISourceViewer viewer= getSourceViewer();
		if (viewer != null) {
			StyledText styledText= viewer.getTextWidget();
			if (styledText != null) {
				return styledText.getWordWrap();
			}
		}
		return false;
	}

	/**
	 * @see org.eclipse.ui.texteditor.ITextEditorExtension6#setWordWrap(boolean)
	 * @since 3.10
	 */
	@Override
	public void setWordWrap(boolean enable) {
		if (!isWordWrapSupported() || isWordWrapEnabled() == enable) {
			return;
		}

		ISourceViewer viewer= getSourceViewer();
		if (viewer != null) {
			StyledText styledText= viewer.getTextWidget();
			if (styledText != null) {
				if (isBlockSelectionModeEnabled()) {
					setBlockSelectionMode(false);
				}
				styledText.setWordWrap(enable);
				if (fVerticalRuler != null) {
					// update ruler layout so that it can consider
					// changed horizontal scrollbar visibility
					boolean updated= false;
					if (viewer instanceof ITextViewerExtension) {
						Control control= ((ITextViewerExtension)viewer).getControl();
						if (control instanceof Composite) {
							((Composite)control).layout();
							updated= true;
						}
					}
					if (!updated) {
						fVerticalRuler.update();
					}
				}
			}
		}
	}

	/**
	 * Returns the initial word wrap status.
	 *
	 * @return initial word wrap status
	 * @since 3.10
	 */
	protected boolean getInitialWordWrapStatus() {
		IPreferenceStore store= getPreferenceStore();
		if (store == null) {
			return false;
		}
		return store.getBoolean(PREFERENCE_WORD_WRAP_ENABLED);
	}
}
