/*******************************************************************************
 * Copyright (c) 2005, 2017 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     xored software, Inc. - initial API and implementation
 *     xored software, Inc. - fix tab handling (Bug# 200024) (Alex Panchenko)
 *******************************************************************************/
package org.eclipse.dltk.internal.ui.editor;

import java.text.CharacterIterator;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Stack;

import org.eclipse.core.filebuffers.IPersistableAnnotationModel;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ProjectScope;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.ListenerList;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.core.runtime.preferences.DefaultScope;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.dltk.compiler.CharOperation;
import org.eclipse.dltk.core.DLTKCore;
import org.eclipse.dltk.core.DLTKLanguageManager;
import org.eclipse.dltk.core.IDLTKLanguageToolkit;
import org.eclipse.dltk.core.IImportDeclaration;
import org.eclipse.dltk.core.ILocalVariable;
import org.eclipse.dltk.core.IMember;
import org.eclipse.dltk.core.IModelElement;
import org.eclipse.dltk.core.IPackageDeclaration;
import org.eclipse.dltk.core.IScriptLanguageProvider;
import org.eclipse.dltk.core.IScriptProject;
import org.eclipse.dltk.core.ISourceModule;
import org.eclipse.dltk.core.ISourceRange;
import org.eclipse.dltk.core.ISourceReference;
import org.eclipse.dltk.core.ModelException;
import org.eclipse.dltk.core.PreferencesLookupDelegate;
import org.eclipse.dltk.core.ScriptModelUtil;
import org.eclipse.dltk.internal.ui.BrowserInformationControl;
import org.eclipse.dltk.internal.ui.actions.CompositeActionGroup;
import org.eclipse.dltk.internal.ui.actions.FoldingActionGroup;
import org.eclipse.dltk.internal.ui.actions.refactoring.RefactorActionGroup;
import org.eclipse.dltk.internal.ui.editor.SourceModuleDocumentProvider.SourceModuleAnnotationModel;
import org.eclipse.dltk.internal.ui.editor.selectionaction.GoToNextPreviousMemberAction;
import org.eclipse.dltk.internal.ui.editor.semantic.highlighting.SemanticHighlightingManager;
import org.eclipse.dltk.internal.ui.editor.semantic.highlighting.SemanticHighlightingReconciler;
import org.eclipse.dltk.internal.ui.text.DLTKWordIterator;
import org.eclipse.dltk.internal.ui.text.DocumentCharacterIterator;
import org.eclipse.dltk.internal.ui.text.HTMLTextPresenter;
import org.eclipse.dltk.internal.ui.text.IScriptReconcilingListener;
import org.eclipse.dltk.internal.ui.text.hover.ScriptExpandHover;
import org.eclipse.dltk.internal.ui.text.hover.SourceViewerInformationControl;
import org.eclipse.dltk.ui.CodeFormatterConstants;
import org.eclipse.dltk.ui.DLTKUILanguageManager;
import org.eclipse.dltk.ui.DLTKUIPlugin;
import org.eclipse.dltk.ui.EclipsePreferencesAdapter;
import org.eclipse.dltk.ui.IContextMenuConstants;
import org.eclipse.dltk.ui.IDLTKUILanguageToolkit;
import org.eclipse.dltk.ui.IWorkingCopyManager;
import org.eclipse.dltk.ui.PreferenceConstants;
import org.eclipse.dltk.ui.PreferencesAdapter;
import org.eclipse.dltk.ui.actions.DLTKActionConstants;
import org.eclipse.dltk.ui.actions.GenerateActionGroup;
import org.eclipse.dltk.ui.actions.IScriptEditorActionDefinitionIds;
import org.eclipse.dltk.ui.actions.OpenEditorActionGroup;
import org.eclipse.dltk.ui.actions.OpenViewActionGroup;
import org.eclipse.dltk.ui.actions.SearchActionGroup;
import org.eclipse.dltk.ui.editor.IScriptAnnotation;
import org.eclipse.dltk.ui.editor.highlighting.ISemanticHighlightingUpdater;
import org.eclipse.dltk.ui.formatter.IScriptFormatterFactory;
import org.eclipse.dltk.ui.formatter.ScriptFormatterManager;
import org.eclipse.dltk.ui.formatter.internal.ScriptFormattingContextProperties;
import org.eclipse.dltk.ui.text.ScriptSourceViewerConfiguration;
import org.eclipse.dltk.ui.text.ScriptTextTools;
import org.eclipse.dltk.ui.text.folding.FoldingProviderManager;
import org.eclipse.dltk.ui.text.folding.IFoldingStructureProvider;
import org.eclipse.dltk.ui.text.folding.IFoldingStructureProviderExtension;
import org.eclipse.dltk.ui.text.templates.ITemplateAccess;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.GroupMarker;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.BadPositionCategoryException;
import org.eclipse.jface.text.DefaultInformationControl;
import org.eclipse.jface.text.DocumentCommand;
import org.eclipse.jface.text.DocumentEvent;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IInformationControlCreator;
import org.eclipse.jface.text.IPositionUpdater;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextHover;
import org.eclipse.jface.text.ITextOperationTarget;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.text.ITextViewerExtension2;
import org.eclipse.jface.text.ITextViewerExtension5;
import org.eclipse.jface.text.IWidgetTokenKeeper;
import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.Region;
import org.eclipse.jface.text.TextSelection;
import org.eclipse.jface.text.contentassist.ContentAssistEvent;
import org.eclipse.jface.text.contentassist.ContentAssistant;
import org.eclipse.jface.text.contentassist.ICompletionListener;
import org.eclipse.jface.text.contentassist.ICompletionProposal;
import org.eclipse.jface.text.contentassist.IContentAssistant;
import org.eclipse.jface.text.contentassist.IContentAssistantExtension2;
import org.eclipse.jface.text.formatter.FormattingContextProperties;
import org.eclipse.jface.text.formatter.IFormattingContext;
import org.eclipse.jface.text.information.InformationPresenter;
import org.eclipse.jface.text.link.ILinkedModeListener;
import org.eclipse.jface.text.link.LinkedModeModel;
import org.eclipse.jface.text.link.LinkedModeUI;
import org.eclipse.jface.text.link.LinkedModeUI.ExitFlags;
import org.eclipse.jface.text.link.LinkedModeUI.IExitPolicy;
import org.eclipse.jface.text.reconciler.IReconciler;
import org.eclipse.jface.text.source.Annotation;
import org.eclipse.jface.text.source.AnnotationRulerColumn;
import org.eclipse.jface.text.source.CompositeRuler;
import org.eclipse.jface.text.source.IAnnotationModel;
import org.eclipse.jface.text.source.ICharacterPairMatcher;
import org.eclipse.jface.text.source.IOverviewRuler;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.jface.text.source.ISourceViewerExtension2;
import org.eclipse.jface.text.source.IVerticalRuler;
import org.eclipse.jface.text.source.IVerticalRulerColumn;
import org.eclipse.jface.text.source.SourceViewerConfiguration;
import org.eclipse.jface.text.source.projection.ProjectionSupport;
import org.eclipse.jface.text.source.projection.ProjectionViewer;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
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.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ST;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.VerifyEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IPageLayout;
import org.eclipse.ui.IPartListener2;
import org.eclipse.ui.IPartService;
import org.eclipse.ui.ISelectionListener;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchPartReference;
import org.eclipse.ui.IWorkbenchPartSite;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.actions.ActionContext;
import org.eclipse.ui.actions.ActionGroup;
import org.eclipse.ui.editors.text.EditorsUI;
import org.eclipse.ui.part.IShowInTargetList;
import org.eclipse.ui.texteditor.AbstractDecoratedTextEditor;
import org.eclipse.ui.texteditor.AbstractDecoratedTextEditorPreferenceConstants;
import org.eclipse.ui.texteditor.ChainedPreferenceStore;
import org.eclipse.ui.texteditor.ContentAssistAction;
import org.eclipse.ui.texteditor.IDocumentProvider;
import org.eclipse.ui.texteditor.ITextEditorActionConstants;
import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds;
import org.eclipse.ui.texteditor.IUpdate;
import org.eclipse.ui.texteditor.SourceViewerDecorationSupport;
import org.eclipse.ui.texteditor.TextNavigationAction;
import org.eclipse.ui.texteditor.TextOperationAction;
import org.eclipse.ui.texteditor.templates.ITemplatesPage;
import org.eclipse.ui.views.contentoutline.ContentOutline;
import org.eclipse.ui.views.contentoutline.IContentOutlinePage;

import com.ibm.icu.text.BreakIterator;

public abstract class ScriptEditor extends AbstractDecoratedTextEditor
		implements IScriptReconcilingListener, IScriptLanguageProvider,
		IScriptEditor {

	/** The editor's save policy */
	protected ISavePolicy fSavePolicy = null;

	/** Preference key for matching brackets */
	protected final static String MATCHING_BRACKETS = PreferenceConstants.EDITOR_MATCHING_BRACKETS;
	/** Preference key for matching brackets color */
	protected final static String MATCHING_BRACKETS_COLOR = PreferenceConstants.EDITOR_MATCHING_BRACKETS_COLOR;

	private ScriptEditorErrorTickUpdater fScriptEditorErrorTickUpdater;

	private OccurrencesFinder occurrencesFinder;

	private static String[] GLOBAL_FOLDING_PROPERTIES = {
			PreferenceConstants.EDITOR_FOLDING_ENABLED,
			PreferenceConstants.EDITOR_COMMENTS_FOLDING_ENABLED,
			PreferenceConstants.EDITOR_FOLDING_LINES_LIMIT,
			PreferenceConstants.EDITOR_COMMENT_FOLDING_JOIN_NEWLINES };

	public ISourceViewer getScriptSourceViewer() {
		return super.getSourceViewer();
	}

	public static class BracketLevel {
		public int fOffset;
		public int fLength;
		public LinkedModeUI fUI;
		public Position fFirstPosition;
		public Position fSecondPosition;
	}

	public class ExitPolicy implements IExitPolicy {

		public final char fExitCharacter;
		public final char fEscapeCharacter;
		public final Stack fStack;
		public final int fSize;

		public ExitPolicy(char exitCharacter, char escapeCharacter,
				Stack stack) {
			fExitCharacter = exitCharacter;
			fEscapeCharacter = escapeCharacter;
			fStack = stack;
			fSize = fStack.size();
		}

		/*
		 * @see
		 * org.eclipse.jdt.internal.ui.text.link.LinkedPositionUI.ExitPolicy
		 * #doExit(org.eclipse.jdt.internal.ui.text.link.LinkedPositionManager,
		 * org.eclipse.swt.events.VerifyEvent, int, int)
		 */
		@Override
		public ExitFlags doExit(LinkedModeModel model, VerifyEvent event,
				int offset, int length) {

			if (fSize == fStack.size() && !isMasked(offset)) {
				if (event.character == fExitCharacter) {
					BracketLevel level = (BracketLevel) fStack.peek();
					if (level.fFirstPosition.offset > offset
							|| level.fSecondPosition.offset < offset)
						return null;
					if (level.fSecondPosition.offset == offset && length == 0)
						// don't enter the character if if its the closing peer
						return new ExitFlags(ILinkedModeListener.UPDATE_CARET,
								false);
				}
				// when entering an anonymous class between the parenthesis', we
				// don't want
				// to jump after the closing parenthesis when return is pressed
				if (event.character == SWT.CR && offset > 0) {
					// ssanders: If completion popup is displayed, Enter
					// dismisses it
					if (((AdaptedSourceViewer) getScriptSourceViewer()).fInCompletionSession)
						return new ExitFlags(ILinkedModeListener.NONE, true);

					IDocument document = getSourceViewer().getDocument();
					try {
						if (document.getChar(offset - 1) == '{')
							return new ExitFlags(ILinkedModeListener.EXIT_ALL,
									true);
					} catch (BadLocationException e) {
					}
				}
			}
			return null;
		}

		private boolean isMasked(int offset) {
			IDocument document = getSourceViewer().getDocument();
			try {
				return fEscapeCharacter == document.getChar(offset - 1);
			} catch (BadLocationException e) {
			}
			return false;
		}
	}

	static class ExclusivePositionUpdater implements IPositionUpdater {

		/** The position category. */
		private final String fCategory;

		/**
		 * Creates a new updater for the given <code>category</code>.
		 *
		 * @param category
		 *            the new category.
		 */
		public ExclusivePositionUpdater(String category) {
			fCategory = category;
		}

		/*
		 * @see
		 * org.eclipse.jface.text.IPositionUpdater#update(org.eclipse.jface.
		 * text.DocumentEvent)
		 */
		@Override
		public void update(DocumentEvent event) {

			int eventOffset = event.getOffset();
			int eventOldLength = event.getLength();
			int eventNewLength = event.getText() == null ? 0
					: event.getText().length();
			int deltaLength = eventNewLength - eventOldLength;

			try {
				Position[] positions = event.getDocument()
						.getPositions(fCategory);

				for (int i = 0; i != positions.length; i++) {

					Position position = positions[i];

					if (position.isDeleted())
						continue;

					int offset = position.getOffset();
					int length = position.getLength();
					int end = offset + length;

					if (offset >= eventOffset + eventOldLength)
						// position comes
						// after change - shift
						position.setOffset(offset + deltaLength);
					else if (end <= eventOffset) {
						// position comes way before change -
						// leave alone
					} else if (offset <= eventOffset
							&& end >= eventOffset + eventOldLength) {
						// event completely internal to the position - adjust
						// length
						position.setLength(length + deltaLength);
					} else if (offset < eventOffset) {
						// event extends over end of position - adjust length
						int newEnd = eventOffset;
						position.setLength(newEnd - offset);
					} else if (end > eventOffset + eventOldLength) {
						// event extends from before position into it - adjust
						// offset
						// and length
						// offset becomes end of event, length adjusted
						// accordingly
						int newOffset = eventOffset + eventNewLength;
						position.setOffset(newOffset);
						position.setLength(end - newOffset);
					} else {
						// event consumes the position - delete it
						position.delete();
					}
				}
			} catch (BadPositionCategoryException e) {
				// ignore and return
			}
		}

		/**
		 * Returns the position category.
		 *
		 * @return the position category
		 */
		public String getCategory() {
			return fCategory;
		}

	}

	/**
	 * Text operation code for requesting common prefix completion.
	 */
	public static final int CONTENTASSIST_COMPLETE_PREFIX = 60;

	interface ITextConverter {
		void customizeDocumentCommand(IDocument document,
				DocumentCommand command);
	}

	class AdaptedSourceViewer extends ScriptSourceViewer
			implements ICompletionListener {
		private List<ITextConverter> fTextConverters;

		private boolean fIgnoreTextConverters = false;
		private boolean fInCompletionSession;

		protected IContentAssistant getContentAssistant() {
			return fContentAssistant;
		}

		public AdaptedSourceViewer(Composite parent,
				IVerticalRuler verticalRuler, IOverviewRuler overviewRuler,
				boolean showAnnotationsOverview, int styles,
				IPreferenceStore store) {
			super(parent, verticalRuler, overviewRuler, showAnnotationsOverview,
					styles, store);
		}

		@Override
		public void configure(SourceViewerConfiguration configuration) {
			super.configure(configuration);

			final IContentAssistant ca = getContentAssistant();
			if (ca instanceof IContentAssistantExtension2) {
				((IContentAssistantExtension2) ca).addCompletionListener(this);
			}
		}

		@Override
		public void unconfigure() {
			final IContentAssistant ca = getContentAssistant();
			if (ca instanceof IContentAssistantExtension2) {
				((IContentAssistantExtension2) ca)
						.removeCompletionListener(this);
			}

			super.unconfigure();
		}

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

			if (getTextWidget() == null)
				return;

			switch (operation) {
			case CONTENTASSIST_PROPOSALS:
				String msg = fContentAssistant.showPossibleCompletions();
				setStatusLineErrorMessage(msg);
				return;
			case QUICK_ASSIST:
				/*
				 * XXX: We can get rid of this once the SourceViewer has a way
				 * to update the status line
				 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=133787
				 */
				msg = fQuickAssistAssistant.showPossibleQuickAssists();
				setStatusLineErrorMessage(msg);
				return;
			case UNDO:
				fIgnoreTextConverters = true;
				super.doOperation(operation);
				fIgnoreTextConverters = false;
				return;
			case REDO:
				fIgnoreTextConverters = true;
				super.doOperation(operation);
				fIgnoreTextConverters = false;
				return;
			}

			super.doOperation(operation);
		}

		public void insertTextConverter(ITextConverter textConverter,
				int index) {
			throw new UnsupportedOperationException();
		}

		public void addTextConverter(ITextConverter textConverter) {
			if (fTextConverters == null) {
				fTextConverters = new ArrayList<>(1);
				fTextConverters.add(textConverter);
			} else if (!fTextConverters.contains(textConverter))
				fTextConverters.add(textConverter);
		}

		public void removeTextConverter(ITextConverter textConverter) {
			if (fTextConverters != null) {
				fTextConverters.remove(textConverter);
				if (fTextConverters.size() == 0)
					fTextConverters = null;
			}
		}

		/*
		 * @see TextViewer#customizeDocumentCommand(DocumentCommand)
		 */
		@Override
		protected void customizeDocumentCommand(DocumentCommand command) {
			super.customizeDocumentCommand(command);
			if (!fIgnoreTextConverters && fTextConverters != null) {
				for (ITextConverter c : fTextConverters)
					c.customizeDocumentCommand(getDocument(), command);
			}
		}

		@Override
		public boolean requestWidgetToken(IWidgetTokenKeeper requester) {
			if (PlatformUI.getWorkbench().getHelpSystem()
					.isContextHelpDisplayed())
				return false;
			return super.requestWidgetToken(requester);
		}

		@Override
		public boolean requestWidgetToken(IWidgetTokenKeeper requester,
				int priority) {
			if (PlatformUI.getWorkbench().getHelpSystem()
					.isContextHelpDisplayed())
				return false;
			return super.requestWidgetToken(requester, priority);
		}

		@Override
		public void assistSessionEnded(ContentAssistEvent event) {
			fInCompletionSession = false;
		}

		@Override
		public void assistSessionStarted(ContentAssistEvent event) {
			fInCompletionSession = true;
		}

		@Override
		public void selectionChanged(ICompletionProposal proposal,
				boolean smartToggle) {
		}

		private IProject getProject() {
			final IModelElement input = getInputModelElement();
			if (input != null) {
				final IScriptProject scriptProject = input.getScriptProject();
				if (scriptProject != null) {
					return scriptProject.getProject();
				}
			}
			return null;
		}

		private ISourceModule getSourceModule() {
			final IModelElement input = getInputModelElement();
			if (input != null) {
				return (ISourceModule) input
						.getAncestor(IModelElement.SOURCE_MODULE);
			}
			return null;
		}

		@Override
		public IFormattingContext createFormattingContext() {
			final IFormattingContext context = super.createFormattingContext();
			context.setProperty(ScriptFormattingContextProperties.MODULE,
					getSourceModule());
			final IProject project = getProject();
			context.setProperty(
					ScriptFormattingContextProperties.CONTEXT_PROJECT, project);
			final IScriptFormatterFactory factory = ScriptFormatterManager
					.getSelected(getLanguageToolkit().getNatureId(), project);
			if (factory != null) {
				context.setProperty(
						ScriptFormattingContextProperties.CONTEXT_FORMATTER_ID,
						factory.getId());
				final Map<String, String> preferences = factory
						.retrievePreferences(
								new PreferencesLookupDelegate(project));
				context.setProperty(
						FormattingContextProperties.CONTEXT_PREFERENCES,
						preferences);
			}
			return context;
		}
	}

	/**
	 * Internal implementation class for a change listener.
	 *
	 *
	 */
	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
		 */
		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);
			}
		}
	}

	/**
	 * Updates the selection in the editor's widget with the selection of the
	 * outline page.
	 */
	class OutlineSelectionChangedListener
			extends AbstractSelectionChangedListener {
		@Override
		public void selectionChanged(SelectionChangedEvent event) {
			doSelectionChanged(event);
		}
	}

	private ScriptOutlinePage fOutlinePage;

	private ProjectionSupport fProjectionSupport;

	/**
	 * This editor's projection model updater
	 */
	private IFoldingStructureProvider fProjectionModelUpdater;

	/**
	 * The action group for folding.
	 */
	private ActionGroup fFoldingGroup;

	/** The information presenter. */
	private InformationPresenter fInformationPresenter;

	private CompositeActionGroup fContextMenuGroup;

	// private SelectionHistory fSelectionHistory;

	private CompositeActionGroup fActionGroups;

	private AbstractSelectionChangedListener fOutlineSelectionChangedListener = new OutlineSelectionChangedListener();

	/**
	 * Updates the script outline page selection and this editor's range
	 * indicator.
	 *
	 *
	 */
	private class EditorSelectionChangedListener
			extends AbstractSelectionChangedListener {
		/*
		 * @see
		 * org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged
		 * (org.eclipse.jface.viewers.SelectionChangedEvent)
		 */
		@Override
		public void selectionChanged(SelectionChangedEvent event) {
			// XXX: see https://bugs.eclipse.org/bugs/show_bug.cgi?id=56161
			ScriptEditor.this.selectionChanged();
		}
	}

	/**
	 * The editor selection changed listener.
	 */
	private EditorSelectionChangedListener fEditorSelectionChangedListener;

	public ScriptEditor() {
		super();
		setDocumentProvider(
				DLTKUIPlugin.getDefault().getSourceModuleDocumentProvider());
		fScriptEditorErrorTickUpdater = new ScriptEditorErrorTickUpdater(this);
	}

	/**
	 * @see org.eclipse.ui.texteditor.StatusTextEditor#handleElementContentReplaced()
	 */
	@Override
	protected void handleElementContentReplaced() {
		super.handleElementContentReplaced();

		IAnnotationModel annotationModel = getScriptSourceViewer()
				.getAnnotationModel();
		if (annotationModel instanceof IPersistableAnnotationModel) {
			try {
				((IPersistableAnnotationModel) annotationModel)
						.reinitialize(getScriptSourceViewer().getDocument());
			} catch (CoreException ex) {
				ex.printStackTrace();
			}
		}
	}

	@Override
	public void dispose() {

		if (fProjectionModelUpdater != null) {
			fProjectionModelUpdater.uninstall();
			fProjectionModelUpdater = null;
		}
		if (occurrencesFinder != null) {
			occurrencesFinder.dispose();
			occurrencesFinder = null;
		}

		// ISourceViewer sourceViewer= getSourceViewer();
		// if (sourceViewer instanceof ITextViewerExtension)
		// ((ITextViewerExtension)
		// sourceViewer).removeVerifyKeyListener(fBracketInserter);

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

		// if (fCorrectionCommands != null) {
		// fCorrectionCommands.deregisterCommands();
		// fCorrectionCommands= null;
		// }
		uninstallSemanticHighlighting();
		super.dispose();
	}

	@Override
	protected void initializeEditor() {
		occurrencesFinder = new OccurrencesFinder(this);
		if (!occurrencesFinder.isValid()) {
			occurrencesFinder = null;
		}
		IPreferenceStore store = createCombinedPreferenceStore(null);
		setPreferenceStore(store);
		ScriptTextTools textTools = getTextTools();
		if (textTools != null) {
			setSourceViewerConfiguration(
					textTools.createSourceViewerConfiguraton(store, this));
		}
	}

	/**
	 * Creates and returns the preference store for this editor with the given
	 * input.
	 *
	 * @param input
	 *            The editor input for which to create the preference store
	 * @return the preference store for this editor
	 */
	private IPreferenceStore createCombinedPreferenceStore(IEditorInput input) {
		final List<IPreferenceStore> stores = new ArrayList<>(8);
		final IScriptProject project = EditorUtility.getScriptProject(input);
		final IDLTKLanguageToolkit toolkit = getLanguageToolkit();
		final String preferenceQualifier = toolkit.getPreferenceQualifier();
		if (project != null) {
			if (preferenceQualifier != null) {
				stores.add(new EclipsePreferencesAdapter(
						new ProjectScope(project.getProject()),
						preferenceQualifier));
			}
			stores.add(new EclipsePreferencesAdapter(
					new ProjectScope(project.getProject()),
					DLTKCore.PLUGIN_ID));
		}
		stores.add(getScriptPreferenceStore());
		if (preferenceQualifier != null) {
			stores.add(new EclipsePreferencesAdapter(InstanceScope.INSTANCE,
					preferenceQualifier));
			stores.add(new EclipsePreferencesAdapter(DefaultScope.INSTANCE,
					preferenceQualifier));
		}
		stores.add(new PreferencesAdapter(
				DLTKCore.getDefault().getPluginPreferences()));
		stores.add(EditorsUI.getPreferenceStore());
		stores.add(PlatformUI.getPreferenceStore());
		return new ChainedPreferenceStore(
				stores.toArray(new IPreferenceStore[stores.size()]));
	}

	public IPreferenceStore getScriptPreferenceStore() {
		IDLTKLanguageToolkit toolkit = getLanguageToolkit();
		if (toolkit != null) {
			IDLTKUILanguageToolkit uiToolkit = DLTKUILanguageManager
					.getLanguageToolkit(toolkit.getNatureId());
			if (uiToolkit != null) {
				return uiToolkit.getPreferenceStore();
			}
		}
		return null;
	}

	public ScriptTextTools getTextTools() {
		return null;
	}

	protected void connectPartitioningToElement(IEditorInput input,
			IDocument document) {
	}

	protected void internalDoSetInput(IEditorInput input) throws CoreException {
		ISourceViewer sourceViewer = getSourceViewer();
		ScriptSourceViewer scriptSourceViewer = null;
		if (sourceViewer instanceof ScriptSourceViewer)
			scriptSourceViewer = (ScriptSourceViewer) sourceViewer;
		IPreferenceStore store = getPreferenceStore();

		if (scriptSourceViewer != null && isFoldingEnabled() && (store == null
				|| !store.getBoolean(PreferenceConstants.EDITOR_SHOW_SEGMENTS)))
			scriptSourceViewer.prepareDelayedProjection();

		// correct connection code here.

		super.doSetInput(input);

		final IDocumentProvider docProvider = getDocumentProvider();
		final IAnnotationModel model = docProvider.getAnnotationModel(input);
		if (model instanceof SourceModuleAnnotationModel) {
			((SourceModuleAnnotationModel) model).problemFactory = DLTKLanguageManager
					.getProblemFactory(getNatureId());
		}
		final IDocument doc = docProvider.getDocument(input);
		connectPartitioningToElement(input, doc);

		if (scriptSourceViewer != null
				&& scriptSourceViewer.getReconciler() == null) {
			IReconciler reconciler = getSourceViewerConfiguration()
					.getReconciler(scriptSourceViewer);
			if (reconciler != null) {
				reconciler.install(scriptSourceViewer);
				scriptSourceViewer.setReconciler(reconciler);
			}
		}
		if (DLTKCore.DEBUG) {
			System.err.println(
					"TODO: Add encoding support and overriding indicator support"); //$NON-NLS-1$
		}
		// if (fEncodingSupport != null)
		// fEncodingSupport.reset();
		// if (isShowingOverrideIndicators())
		// installOverrideIndicator(false);
		setOutlinePageInput(fOutlinePage, input);
	}

	private boolean isFoldingEnabled() {
		return getPreferenceStore()
				.getBoolean(PreferenceConstants.EDITOR_FOLDING_ENABLED);
	}

	@Override
	public boolean isSaveAsAllowed() {
		return true;
	}

	/**
	 * Returns the standard action group of this editor.
	 *
	 * @return returns this editor's standard action group
	 */
	ActionGroup getActionGroup() {
		return fActionGroups;
	}

	/*
	 * @see AbstractTextEditor#editorContextMenuAboutToShow
	 */
	@Override
	public void editorContextMenuAboutToShow(IMenuManager menu) {
		super.editorContextMenuAboutToShow(menu);

		menu.insertAfter(IContextMenuConstants.GROUP_OPEN,
				new GroupMarker(IContextMenuConstants.GROUP_SHOW));

		ActionContext context = new ActionContext(
				getSelectionProvider().getSelection());
		context.setInput(getEditorInput());
		fContextMenuGroup.setContext(context);
		fContextMenuGroup.fillContextMenu(menu);
		fContextMenuGroup.setContext(null);
		// Quick views
		menu.appendToGroup(IContextMenuConstants.GROUP_OPEN,
				getAction(IScriptEditorActionDefinitionIds.SHOW_OUTLINE));
		menu.appendToGroup(IContextMenuConstants.GROUP_OPEN,
				getAction(IScriptEditorActionDefinitionIds.OPEN_HIERARCHY));
	}

	@Override
	protected void createActions() {
		super.createActions();

		ActionGroup oeg = new OpenEditorActionGroup(this);
		ActionGroup ovg = new OpenViewActionGroup(this);
		ActionGroup dsg = new SearchActionGroup(this);

		fActionGroups = new CompositeActionGroup(
				new ActionGroup[] { oeg, ovg, dsg });

		// fSelectionHistory= new SelectionHistory(this);

		fContextMenuGroup = new CompositeActionGroup(
				new ActionGroup[] { oeg, ovg, dsg });
		loadContributedContextActionGroups();

		fFoldingGroup = createFoldingActionGroup();

		// ResourceAction resAction = new TextOperationAction(DLTKEditorMessages
		// .getBundleForConstructedKeys(), "ShowDocumentaion.", this,
		// ISourceViewer.INFORMATION, true);
		//
		// resAction = new InformationDispatchAction(DLTKEditorMessages
		// .getBundleForConstructedKeys(), "ShowDocumentation.",
		// (TextOperationAction) resAction);
		//
		// resAction
		// .setActionDefinitionId(IScriptEditorActionDefinitionIds.
		// SHOW_DOCUMENTATION);
		// setAction("ShowDocumentation", resAction);

		Action action = new GotoMatchingBracketAction(this);
		action.setActionDefinitionId(
				IScriptEditorActionDefinitionIds.GOTO_MATCHING_BRACKET);
		setAction(GotoMatchingBracketAction.GOTO_MATCHING_BRACKET, action);

		Action outlineAction = new TextOperationAction(
				DLTKEditorMessages.getBundleForConstructedKeys(),
				"ShowOutline.", this, //$NON-NLS-1$
				ScriptSourceViewer.SHOW_OUTLINE, true);
		outlineAction.setActionDefinitionId(
				IScriptEditorActionDefinitionIds.SHOW_OUTLINE);
		setAction(IScriptEditorActionDefinitionIds.SHOW_OUTLINE, outlineAction);

		action = new TextOperationAction(
				DLTKEditorMessages.getBundleForConstructedKeys(),
				"OpenHierarchy.", this, ScriptSourceViewer.SHOW_HIERARCHY, //$NON-NLS-1$
				true);
		action.setActionDefinitionId(
				IScriptEditorActionDefinitionIds.OPEN_HIERARCHY);
		setAction(IScriptEditorActionDefinitionIds.OPEN_HIERARCHY, action);

		// ContentAssistProposal
		action = new ContentAssistAction(
				DLTKEditorMessages.getBundleForConstructedKeys(),
				"ContentAssistProposal.", this); //$NON-NLS-1$
		action.setActionDefinitionId(
				ITextEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS);
		setAction("ContentAssistProposal", action); //$NON-NLS-1$
		markAsStateDependentAction("ContentAssistProposal", true); //$NON-NLS-1$

		// ContentAssistContextInformation
		action = new TextOperationAction(
				DLTKEditorMessages.getBundleForConstructedKeys(),
				"ContentAssistContextInformation.", this, //$NON-NLS-1$
				ISourceViewer.CONTENTASSIST_CONTEXT_INFORMATION);
		action.setActionDefinitionId(
				ITextEditorActionDefinitionIds.CONTENT_ASSIST_CONTEXT_INFORMATION);
		setAction("ContentAssistContextInformation", action); //$NON-NLS-1$
		markAsStateDependentAction("ContentAssistContextInformation", true); //$NON-NLS-1$

		// GroupEdit
		ActionGroup rg = new RefactorActionGroup(this,
				ITextEditorActionConstants.GROUP_EDIT);
		fActionGroups.addGroup(rg);
		fContextMenuGroup.addGroup(rg);

		// GoToNextMember
		action = GoToNextPreviousMemberAction.newGoToNextMemberAction(this);
		action.setActionDefinitionId(
				IScriptEditorActionDefinitionIds.GOTO_NEXT_MEMBER);
		setAction(GoToNextPreviousMemberAction.NEXT_MEMBER, action);

		// GoToPreviousMember
		action = GoToNextPreviousMemberAction.newGoToPreviousMemberAction(this);
		action.setActionDefinitionId(
				IScriptEditorActionDefinitionIds.GOTO_PREVIOUS_MEMBER);
		setAction(GoToNextPreviousMemberAction.PREVIOUS_MEMBER, action);

		// Source menu actions
		action = new TextOperationAction(
				DLTKEditorMessages.getBundleForConstructedKeys(), "Comment.", //$NON-NLS-1$
				this, ITextOperationTarget.PREFIX);
		action.setActionDefinitionId(IScriptEditorActionDefinitionIds.COMMENT);
		setAction(DLTKActionConstants.COMMENT, action);
		markAsStateDependentAction(DLTKActionConstants.COMMENT, true);

		action = new TextOperationAction(
				DLTKEditorMessages.getBundleForConstructedKeys(), "Uncomment.", //$NON-NLS-1$
				this, ITextOperationTarget.STRIP_PREFIX);
		action.setActionDefinitionId(
				IScriptEditorActionDefinitionIds.UNCOMMENT);
		setAction(DLTKActionConstants.UNCOMMENT, action);
		markAsStateDependentAction(DLTKActionConstants.UNCOMMENT, true);

		action = new ToggleCommentAction(
				DLTKEditorMessages.getBundleForConstructedKeys(),
				"ToggleComment.", this); //$NON-NLS-1$
		action.setActionDefinitionId(
				IScriptEditorActionDefinitionIds.TOGGLE_COMMENT);
		setAction(DLTKActionConstants.TOGGLE_COMMENT, action);
		markAsStateDependentAction(DLTKActionConstants.TOGGLE_COMMENT, true);

		ISourceViewer sourceViewer = getSourceViewer();
		SourceViewerConfiguration configuration = getSourceViewerConfiguration();
		((ToggleCommentAction) action).configure(sourceViewer, configuration);

		final ActionGroup generateActions = createGenerateActionGroup();
		if (generateActions != null) {
			fActionGroups.addGroup(generateActions);
			fContextMenuGroup.addGroup(generateActions);
		}
	}

	/**
	 * @since 3.0
	 */
	protected ActionGroup createGenerateActionGroup() {
		return new GenerateActionGroup(this,
				ITextEditorActionConstants.GROUP_EDIT);
	}

	private static final String EXTENSION_EDITOR_CONTEXT_ACTION_GROUPS = "editorContextActionGroup"; //$NON-NLS-1$
	private static final String ATTR_NATURE = "nature"; //$NON-NLS-1$
	private static final String ATTR_CLASS = "class"; //$NON-NLS-1$

	private void loadContributedContextActionGroups() {
		final IConfigurationElement[] elements = Platform.getExtensionRegistry()
				.getConfigurationElementsFor(DLTKUIPlugin.PLUGIN_ID,
						EXTENSION_EDITOR_CONTEXT_ACTION_GROUPS);
		final String natureId = getNatureId();
		for (int i = 0; i < elements.length; ++i) {
			final IConfigurationElement element = elements[i];
			final String elementNature = element.getAttribute(ATTR_NATURE);
			if (elementNature == null || elementNature.equals(natureId)) {
				try {
					final Object actionGroup = element
							.createExecutableExtension(ATTR_CLASS);
					if (actionGroup instanceof ActionGroup) {
						fContextMenuGroup.addGroup((ActionGroup) actionGroup);
					} else {
						DLTKUIPlugin.logErrorMessage(
								actionGroup.getClass().getName()
										+ " should extend ActionGroup"); //$NON-NLS-1$
					}
				} catch (CoreException e) {
					DLTKUIPlugin.log(e);
				}
			}
		}
	}

	/**
	 * Creates action group for folding.
	 *
	 * @return
	 * @since 3.0
	 */
	protected ActionGroup createFoldingActionGroup() {
		return new FoldingActionGroup(this, getViewer(),
				getScriptPreferenceStore());
	}

	@Override
	protected IVerticalRulerColumn createAnnotationRulerColumn(
			CompositeRuler ruler) {
		if (!getPreferenceStore()
				.getBoolean(PreferenceConstants.EDITOR_ANNOTATION_ROLL_OVER))
			return super.createAnnotationRulerColumn(ruler);

		AnnotationRulerColumn column = new AnnotationRulerColumn(
				VERTICAL_RULER_WIDTH, getAnnotationAccess());
		column.setHover(new ScriptExpandHover(ruler, getAnnotationAccess(),
				new IDoubleClickListener() {

					@Override
					public void doubleClick(DoubleClickEvent event) {
						// for now: just invoke ruler double click action
						triggerAction(
								ITextEditorActionConstants.RULER_DOUBLE_CLICK);
					}

					private void triggerAction(String actionID) {
						IAction action = getAction(actionID);
						if (action != null) {
							if (action instanceof IUpdate)
								((IUpdate) action).update();
							// hack to propagate line change
							if (action instanceof ISelectionListener) {
								((ISelectionListener) action)
										.selectionChanged(null, null);
							}
							if (action.isEnabled())
								action.run();
						}
					}

				}));

		return column;
	}

	/**
	 * Returns the folding action group, or <code>null</code> if there is none.
	 *
	 * @return the folding action group, or <code>null</code> if there is none
	 *
	 */
	ActionGroup getFoldingActionGroup() {
		return fFoldingGroup;
	}

	public final ISourceViewer getViewer() {
		return getSourceViewer();
	}

	@Override
	protected void doSetInput(IEditorInput input) throws CoreException {
		ISourceViewer sourceViewer = getSourceViewer();
		if (!(sourceViewer instanceof ISourceViewerExtension2)) {
			setPreferenceStore(createCombinedPreferenceStore(input));
			try {
				internalDoSetInput(input);
			} catch (ModelException e) {
				DLTKUIPlugin.log(e);
				this.close(false);
			}
		} else {
			// uninstall & unregister preference store listener
			getSourceViewerDecorationSupport(sourceViewer).uninstall();
			((ISourceViewerExtension2) sourceViewer).unconfigure();
			setPreferenceStore(createCombinedPreferenceStore(input));
			// install & register preference store listener
			sourceViewer.configure(getSourceViewerConfiguration());
			getSourceViewerDecorationSupport(sourceViewer)
					.install(getPreferenceStore());
			try {
				internalDoSetInput(input);
			} catch (ModelException e) {
				DLTKUIPlugin.log(e);
				this.close(false);
			}
		}

		if (fScriptEditorErrorTickUpdater != null)
			fScriptEditorErrorTickUpdater
					.updateEditorImage(getInputModelElement());
	}

	@Override
	protected void setPreferenceStore(IPreferenceStore store) {
		super.setPreferenceStore(store);
		final SourceViewerConfiguration svConfiguration = getSourceViewerConfiguration();
		if (svConfiguration == null
				|| svConfiguration instanceof ScriptSourceViewerConfiguration) {
			final ScriptTextTools textTools = getTextTools();
			if (textTools != null) {
				setSourceViewerConfiguration(
						textTools.createSourceViewerConfiguraton(store, this));
			}
		}
		if (getSourceViewer() instanceof ScriptSourceViewer) {
			((ScriptSourceViewer) getSourceViewer()).setPreferenceStore(store);
		}
		if (occurrencesFinder != null) {
			occurrencesFinder.setPreferenceStore(store);
		}
	}

	private ScriptOutlinePage createOutlinePage() {
		final ScriptOutlinePage page = doCreateOutlinePage();
		fOutlineSelectionChangedListener.install(page);
		setOutlinePageInput(page, getEditorInput());
		return page;
	}

	/**
	 * Creates the outline page used with this editor.
	 *
	 * @return the created script outline page
	 */
	protected ScriptOutlinePage doCreateOutlinePage() {
		return new ScriptOutlinePage(this, getPreferenceStore());
	}

	/**
	 * String identifiying concrete language editor. Used for ex. for fetching
	 * available filters
	 *
	 * @return
	 */
	public abstract String getEditorId();

	/**
	 * Informs the editor that its outliner has been closed.
	 */
	@Override
	public void outlinePageClosed() {
		if (fOutlinePage != null) {
			fOutlineSelectionChangedListener.uninstall(fOutlinePage);
			fOutlinePage = null;
			resetHighlightRange();
		}
	}

	private void setOutlinePageInput(ScriptOutlinePage page,
			IEditorInput input) {
		if (page == null) {
			return;
		}
		IModelElement me = getInputModelElement();
		if (me != null && me.exists()) {
			page.setInput(me);
		} else {
			page.setInput(null);
		}
	}

	/**
	 * The templates page.
	 *
	 * @since 3.0
	 */
	private ScriptTemplatesPage fTemplatesPage;

	/**
	 * Creates the templates page used with this editor.
	 *
	 * @return the created script templates page
	 * @since 3.0
	 */
	protected ScriptTemplatesPage createTemplatesPage() {
		final IDLTKUILanguageToolkit uiToolkit = getUILanguageToolkit();
		if (uiToolkit == null) {
			return null;
		}
		final ITemplateAccess templateAccess = uiToolkit.getEditorTemplates();
		if (templateAccess == null) {
			return null;
		}
		try {
			return new ScriptTemplatesPage(this, templateAccess);
		} catch (Throwable e) {
			return null;
		}
	}

	@SuppressWarnings("unchecked")
	@Override
	public <T> T getAdapter(Class<T> required) {
		if (ITemplatesPage.class.equals(required)) {
			if (fTemplatesPage == null)
				fTemplatesPage = createTemplatesPage();
			return (T) fTemplatesPage;
		}
		if (IContentOutlinePage.class.equals(required)) {
			if (fOutlinePage == null)
				fOutlinePage = createOutlinePage();
			return (T) fOutlinePage;
		}
		if (required == IShowInTargetList.class) {
			return (T) (IShowInTargetList) () -> new String[] {
					DLTKUIPlugin.ID_SCRIPT_EXPLORER, IPageLayout.ID_OUTLINE };
		}
		if (required == OccurrencesFinder.class) {
			return (T) occurrencesFinder;
		}
		if (required == IFoldingStructureProvider.class)
			return (T) fProjectionModelUpdater;
		if (required == IFoldingStructureProviderExtension.class)
			return (T) fProjectionModelUpdater;

		if (fProjectionSupport != null) {
			Object adapter = fProjectionSupport.getAdapter(getSourceViewer(),
					required);
			if (adapter != null)
				return (T) adapter;
		}

		return super.getAdapter(required);
	}

	/**
	 * Returns the mutex for the reconciler. See
	 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=63898 for a description of
	 * the problem.
	 * <p>
	 * XXX remove once the underlying problem
	 * (https://bugs.eclipse.org/bugs/show_bug.cgi?id=66176) is solved.
	 * </p>
	 *
	 * @return the lock reconcilers may use to synchronize on
	 */
	public Object getReconcilerLock() {
		return fReconcilerLock;
	}

	protected void doSelectionChanged(SelectionChangedEvent event) {
		ISourceReference reference = null;
		ISelection selection = event.getSelection();
		Iterator<?> iter = ((IStructuredSelection) selection).iterator();
		while (iter.hasNext()) {
			Object o = iter.next();
			if (o instanceof ISourceReference) {
				reference = (ISourceReference) o;
				break;
			}
		}
		if (!isActivePart() && DLTKUIPlugin.getActivePage() != null)
			DLTKUIPlugin.getActivePage().bringToTop(this);
		setSelection(reference, !isActivePart());
		if (occurrencesFinder != null) {
			occurrencesFinder.updateOccurrenceAnnotations();
		}
	}

	protected boolean isActivePart() {
		IWorkbenchPart part = getActivePart();
		return part != null && part.equals(this);
	}

	private IWorkbenchPart getActivePart() {
		IWorkbenchWindow window = getSite().getWorkbenchWindow();
		IPartService service = window.getPartService();
		IWorkbenchPart part = service.getActivePart();
		return part;
	}

	protected void setSelection(ISourceReference reference,
			boolean moveCursor) {
		if (getSelectionProvider() == null)
			return;
		ISelection selection = getSelectionProvider().getSelection();
		if (selection instanceof TextSelection) {
			TextSelection textSelection = (TextSelection) selection;
			// PR 39995: [navigation] Forward history cleared after going back
			// in navigation history:
			// mark only in navigation history if the cursor is being moved
			// (which it isn't if
			// this is called from a PostSelectionEvent that should only update
			// the magnet)
			if (moveCursor && (textSelection.getOffset() != 0
					|| textSelection.getLength() != 0))
				markInNavigationHistory();
		}
		if (reference != null) {
			StyledText textWidget = null;
			ISourceViewer sourceViewer = getSourceViewer();
			if (sourceViewer != null)
				textWidget = sourceViewer.getTextWidget();
			if (textWidget == null)
				return;
			try {
				ISourceRange range = null;
				range = reference.getSourceRange();
				if (range == null)
					return;
				int offset = range.getOffset();
				int length = range.getLength();
				if (offset < 0 || length < 0)
					return;
				setHighlightRange(offset, length, moveCursor);
				if (!moveCursor)
					return;
				offset = -1;
				length = -1;
				if (reference instanceof IMember) {
					range = ((IMember) reference).getNameRange();
					if (range != null) {
						offset = range.getOffset();
						length = range.getLength();
					}
				} else if (reference instanceof ILocalVariable) {
					range = ((ILocalVariable) reference).getNameRange();
					if (range != null) {
						offset = range.getOffset();
						length = range.getLength();
					}
				} else if (reference instanceof IImportDeclaration
						|| reference instanceof IPackageDeclaration) {
					// range is still getSourceRange()
					offset = range.getOffset();
					length = range.getLength();
				}
				if (offset > -1 && length > 0) {
					try {
						textWidget.setRedraw(false);
						sourceViewer.revealRange(offset, length);
						sourceViewer.setSelectedRange(offset, length);
					} finally {
						textWidget.setRedraw(true);
					}
					markInNavigationHistory();
				}
			} catch (ModelException x) {
			} catch (IllegalArgumentException x) {
			}
		} else if (moveCursor) {
			resetHighlightRange();
			markInNavigationHistory();
		}
	}

	@Override
	protected void doSetSelection(ISelection selection) {
		super.doSetSelection(selection);
		synchronizeOutlinePageSelection();
	}

	@Override
	public void setSelection(IModelElement element) {

		if (element == null || element instanceof ISourceModule) {
			/*
			 * If the element is an ISourceModule this unit is either the input
			 * of this editor or not being displayed. In both cases, nothing
			 * should happened.
			 * (http://dev.eclipse.org/bugs/show_bug.cgi?id=5128)
			 */
			return;
		}

		IModelElement corresponding = getCorrespondingElement(element);
		if (corresponding instanceof ISourceReference) {
			ISourceReference reference = (ISourceReference) corresponding;
			// set highlight range
			setSelection(reference, true);
			// set outliner selection
			if (fOutlinePage != null) {
				fOutlineSelectionChangedListener.uninstall(fOutlinePage);
				fOutlinePage.select(reference);
				fOutlineSelectionChangedListener.install(fOutlinePage);
			}
		}
	}

	/**
	 * Synchronizes the outliner selection with the given element position in
	 * the editor.
	 *
	 * @param element
	 *            thescriptelement to select
	 */
	protected void synchronizeOutlinePage(ISourceReference element) {
		synchronizeOutlinePage(element, true);
	}

	/**
	 * Synchronizes the outliner selection with the given element position in
	 * the editor.
	 *
	 * @param element
	 *            thescriptelement to select
	 * @param checkIfOutlinePageActive
	 *            <code>true</code> if check for active outline page needs to be
	 *            done
	 * @since 2.0
	 */
	@Override
	public void synchronizeOutlinePage(ISourceReference element,
			boolean checkIfOutlinePageActive) {
		if (fOutlinePage != null && element != null
				&& !(checkIfOutlinePageActive && isOutlinePageActive())) {
			fOutlineSelectionChangedListener.uninstall(fOutlinePage);
			fOutlinePage.select(element);
			fOutlineSelectionChangedListener.install(fOutlinePage);
		}
	}

	/**
	 * Synchronizes the outliner selection with the actual cursor position in
	 * the editor.
	 */
	public void synchronizeOutlinePageSelection() {
		synchronizeOutlinePage(computeHighlightRangeSourceReference());
	}

	private boolean isOutlinePageActive() {
		IWorkbenchPart part = getActivePart();
		return part instanceof ContentOutline
				&& ((ContentOutline) part).getCurrentPage() == fOutlinePage;
	}

	/**
	 * {@inheritDoc}
	 * <p>
	 * Overrides the default implementation to handle {@link IJavaAnnotation}.
	 * </p>
	 *
	 * @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
	 */
	@Override
	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 = document.getLength();
		int distance = Integer.MAX_VALUE;

		IAnnotationModel model = getDocumentProvider()
				.getAnnotationModel(getEditorInput());
		Iterator<Annotation> e = new ScriptAnnotationIterator(model, true);
		while (e.hasNext()) {
			Annotation a = e.next();
			if ((a instanceof IScriptAnnotation)
					&& ((IScriptAnnotation) a).hasOverlay()
					|| !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 the annotation overlapping with the given range or
	 * <code>null</code>.
	 *
	 * @param offset
	 *            the region offset
	 * @param length
	 *            the region length
	 * @return the found annotation or <code>null</code>
	 * @since 3.0
	 */
	private Annotation getAnnotation(int offset, int length) {
		IAnnotationModel model = getDocumentProvider()
				.getAnnotationModel(getEditorInput());
		Iterator<Annotation> e = new ScriptAnnotationIterator(model, false);
		while (e.hasNext()) {
			Annotation a = e.next();
			Position p = model.getPosition(a);
			if (p != null && p.overlapsWith(offset, length))
				return a;
		}
		return null;
	}

	/*
	 * @see
	 * org.eclipse.ui.texteditor.AbstractDecoratedTextEditor#gotoAnnotation(
	 * boolean)
	 *
	 * @since 3.2
	 */
	@Override
	public Annotation gotoAnnotation(boolean forward) {
		fSelectionChangedViaGotoAnnotation = true;
		return super.gotoAnnotation(forward);
	}

	/**
	 * Computes and returns the source reference that includes the caret and
	 * serves as provider for the outline page selection and the editor range
	 * indication.
	 *
	 * @return the computed source reference
	 * @since 2.0
	 */
	@Override
	public ISourceReference computeHighlightRangeSourceReference() {
		ISourceViewer sourceViewer = getSourceViewer();
		if (sourceViewer == null)
			return null;
		StyledText styledText = sourceViewer.getTextWidget();
		if (styledText == null)
			return null;
		int caret = 0;
		if (sourceViewer instanceof ITextViewerExtension5) {
			ITextViewerExtension5 extension = (ITextViewerExtension5) sourceViewer;
			caret = extension
					.widgetOffset2ModelOffset(styledText.getCaretOffset());
		} else {
			int offset = sourceViewer.getVisibleRegion().getOffset();
			caret = offset + styledText.getCaretOffset();
		}
		IModelElement element = getElementAt(caret, false);
		if (!(element instanceof ISourceReference))
			return null;
		// if (element.getElementType() == IModelElement.IMPORT_DECLARATION) {
		//
		// IImportDeclaration declaration= (IImportDeclaration) element;
		// IImportContainer container= (IImportContainer)
		// declaration.getParent();
		// ISourceRange srcRange= null;
		//
		// try {
		// srcRange= container.getSourceRange();
		// } catch (ModelException e) {
		// }
		//
		// if (srcRange != null && srcRange.getOffset() == caret)
		// return container;
		// }
		return (ISourceReference) element;
	}

	@Override
	public void createPartControl(Composite parent) {
		super.createPartControl(parent);

		IInformationControlCreator informationControlCreator = shell -> {
			boolean cutDown = false;
			// int style = cutDown ? SWT.NONE : (SWT.V_SCROLL | SWT.H_SCROLL);
			// return new DefaultInformationControl(shell, SWT.RESIZE
			// | SWT.TOOL, style, new HTMLTextPresenter(cutDown));
			if (BrowserInformationControl.isAvailable(shell))
				return new BrowserInformationControl(shell,
						JFaceResources.DIALOG_FONT, true);
			else
				return new DefaultInformationControl(shell,
						new HTMLTextPresenter(cutDown));
		};

		fInformationPresenter = new InformationPresenter(
				informationControlCreator);
		fInformationPresenter.setSizeConstraints(60, 10, true, true);
		fInformationPresenter.install(getSourceViewer());
		fInformationPresenter
				.setDocumentPartitioning(IDocument.DEFAULT_CONTENT_TYPE);

		fEditorSelectionChangedListener = new EditorSelectionChangedListener();
		fEditorSelectionChangedListener.install(getSelectionProvider());
		if (true)
			installSemanticHighlighting();
		if (!isEditable()) {
			/*
			 * Manually call semantic highlighting for read only editor, since
			 * usually it's done from reconciler, but
			 * ScriptSourceViewerConfiguration.getReconciler(ISourceViewer)
			 * doesn't create reconciler for read only editor.
			 */
			updateSemanticHighlighting();
		}
		if (occurrencesFinder != null) {
			occurrencesFinder.install();
		}
	}

	/**
	 * React to changed selection.
	 *
	 *
	 */
	protected void selectionChanged() {
		if (getSelectionProvider() == null)
			return;
		ISourceReference element = computeHighlightRangeSourceReference();
		if (getPreferenceStore().getBoolean(
				PreferenceConstants.EDITOR_SYNC_OUTLINE_ON_CURSOR_MOVE))
			synchronizeOutlinePage(element);
		setSelection(element, false);
		if (!fSelectionChangedViaGotoAnnotation)
			updateStatusLine();
		fSelectionChangedViaGotoAnnotation = false;
	}

	protected void updateStatusLine() {
		ITextSelection selection = (ITextSelection) getSelectionProvider()
				.getSelection();
		Annotation annotation = getAnnotation(selection.getOffset(),
				selection.getLength());
		setStatusLineErrorMessage(null);
		setStatusLineMessage(null);
		if (annotation != null) {
			updateMarkerViews(annotation);
			if (annotation instanceof IScriptAnnotation
					&& ((IScriptAnnotation) annotation).isProblem())
				setStatusLineMessage(annotation.getText());
		}
	}

	/**
	 * Returns the model element wrapped by this editors input.
	 *
	 * @return the model element wrapped by this editors input.
	 *
	 */
	public IModelElement getInputModelElement() {
		return EditorUtility.getEditorInputModelElement(this, false);
	}

	/**
	 * Returns thescriptelement of this editor's input corresponding to the
	 * given IModelElement.
	 *
	 * @param element
	 *            thescriptelement
	 * @return the corresponding model element
	 */
	protected IModelElement getCorrespondingElement(IModelElement element) {
		return element;
	}

	/**
	 * Returns the most narrow model element including the given offset.
	 *
	 * @param offset
	 *            the offset inside of the requested element
	 * @return the most narrow model element
	 */
	@Override
	public IModelElement getElementAt(int offset) {
		return getElementAt(offset, true);
	}

	/**
	 * Returns the most narrow element including the given offset. If
	 * <code>reconcile</code> is <code>true</code> the editor's input element is
	 * reconciled in advance. If it is <code>false</code> this method only
	 * returns a result if the editor's input element does not need to be
	 * reconciled.
	 *
	 * @param offset
	 *            the offset included by the retrieved element
	 * @param reconcile
	 *            <code>true</code> if working copy should be reconciled
	 * @return the most narrow element which includes the given offset
	 */
	public IModelElement getElementAt(int offset, boolean reconcile) {
		ISourceModule unit = (ISourceModule) getInputModelElement();
		if (unit != null) {
			try {
				if (reconcile) {
					ScriptModelUtil.reconcile(unit);
					return unit.getElementAt(offset);
				} else if (unit.isConsistent())
					return unit.getElementAt(offset);
			} catch (ModelException x) {
				if (!x.isDoesNotExist())
					// DLTKUIPlugin.log(x.getStatus());
					System.err.println(x.getStatus());
				// nothing found, be tolerant and go on
			}
		}
		return null;
	}

	/**
	 * The folding runner.
	 *
	 *
	 */
	private ToggleFoldingRunner fFoldingRunner;

	/**
	 * Tells whether the selection changed event is caused by a call to
	 * {@link #gotoAnnotation(boolean)}.
	 *
	 */
	private boolean fSelectionChangedViaGotoAnnotation;

	/**
	 * Runner that will toggle folding either instantly (if the editor is
	 * visible) or the next time it becomes visible. If a runner is started when
	 * there is already one registered, the registered one is canceled as
	 * toggling folding twice is a no-op.
	 * <p>
	 * The access to the fFoldingRunner field is not thread-safe, it is assumed
	 * that <code>runWhenNextVisible</code> is only called from the UI thread.
	 * </p>
	 *
	 *
	 */
	protected final class ToggleFoldingRunner implements IPartListener2 {
		public ToggleFoldingRunner() {
		}

		/**
		 * The workbench page we registered the part listener with, or
		 * <code>null</code>.
		 */
		private IWorkbenchPage fPage;

		/**
		 * Does the actual toggling of projection.
		 */
		private void toggleFolding() {
			ISourceViewer sourceViewer = getSourceViewer();
			if (sourceViewer instanceof ProjectionViewer) {
				ProjectionViewer pv = (ProjectionViewer) sourceViewer;
				if (pv.isProjectionMode() != isFoldingEnabled()) {
					if (pv.canDoOperation(ProjectionViewer.TOGGLE))
						pv.doOperation(ProjectionViewer.TOGGLE);
				}
			}
		}

		/**
		 * Makes sure that the editor's folding state is correct the next time
		 * it becomes visible. If it already is visible, it toggles the folding
		 * state. If not, it either registers a part listener to toggle folding
		 * when the editor becomes visible, or cancels an already registered
		 * runner.
		 */
		public void runWhenNextVisible() {
			// if there is one already: toggling twice is the identity
			if (fFoldingRunner != null) {
				fFoldingRunner.cancel();
				return;
			}
			IWorkbenchPartSite site = getSite();
			if (site != null) {
				IWorkbenchPage page = site.getPage();
				if (!page.isPartVisible(ScriptEditor.this)) {
					// if we're not visible - defer until visible
					fPage = page;
					fFoldingRunner = this;
					page.addPartListener(this);
					return;
				}
			}
			// we're visible - run now
			toggleFolding();
		}

		/**
		 * Remove the listener and clear the field.
		 */
		private void cancel() {
			if (fPage != null) {
				fPage.removePartListener(this);
				fPage = null;
			}
			if (fFoldingRunner == this)
				fFoldingRunner = null;
		}

		/*
		 * @seeorg.eclipse.ui.IPartListener2#partVisible(org.eclipse.ui.
		 * IWorkbenchPartReference)
		 */
		@Override
		public void partVisible(IWorkbenchPartReference partRef) {
			if (ScriptEditor.this.equals(partRef.getPart(false))) {
				cancel();
				toggleFolding();
			}
		}

		/*
		 * @seeorg.eclipse.ui.IPartListener2#partClosed(org.eclipse.ui.
		 * IWorkbenchPartReference)
		 */
		@Override
		public void partClosed(IWorkbenchPartReference partRef) {
			if (ScriptEditor.this.equals(partRef.getPart(false))) {
				cancel();
			}
		}

		@Override
		public void partActivated(IWorkbenchPartReference partRef) {
		}

		@Override
		public void partBroughtToTop(IWorkbenchPartReference partRef) {
		}

		@Override
		public void partDeactivated(IWorkbenchPartReference partRef) {
		}

		@Override
		public void partOpened(IWorkbenchPartReference partRef) {
		}

		@Override
		public void partHidden(IWorkbenchPartReference partRef) {
		}

		@Override
		public void partInputChanged(IWorkbenchPartReference partRef) {
		}
	}

	/**
	 * Creates folding structure provider to use in this editor. Default
	 * implementation queries the
	 * <code>org.eclipse.dltk.ui.folding/structureProvider</code> extension
	 * point.
	 *
	 * @return folding structure provider or <code>null</code>.
	 */
	protected IFoldingStructureProvider createFoldingStructureProvider() {
		return getFoldingStructureProvider();
	}

	/**
	 * Returns folding structure provider.
	 *
	 * @return
	 */
	@Deprecated
	protected IFoldingStructureProvider getFoldingStructureProvider() {
		return FoldingProviderManager.getStructureProvider(getNatureId());
	}

	private boolean isEditorHoverProperty(String property) {
		return PreferenceConstants.EDITOR_TEXT_HOVER_MODIFIERS.equals(property);
	}

	/*
	 * Update the hovering behavior depending on the preferences.
	 */
	private void updateHoverBehavior() {
		SourceViewerConfiguration configuration = getSourceViewerConfiguration();
		String[] types = configuration
				.getConfiguredContentTypes(getSourceViewer());

		for (int i = 0; i < types.length; i++) {

			String t = types[i];

			ISourceViewer sourceViewer = getSourceViewer();
			if (sourceViewer instanceof ITextViewerExtension2) {
				// Remove existing hovers
				((ITextViewerExtension2) sourceViewer).removeTextHovers(t);

				int[] stateMasks = configuration
						.getConfiguredTextHoverStateMasks(getSourceViewer(), t);

				if (stateMasks != null) {
					for (int j = 0; j < stateMasks.length; j++) {
						int stateMask = stateMasks[j];
						ITextHover textHover = configuration
								.getTextHover(sourceViewer, t, stateMask);
						((ITextViewerExtension2) sourceViewer)
								.setTextHover(textHover, t, stateMask);
					}
				} else {
					ITextHover textHover = configuration
							.getTextHover(sourceViewer, t);
					((ITextViewerExtension2) sourceViewer).setTextHover(
							textHover, t,
							ITextViewerExtension2.DEFAULT_HOVER_STATE_MASK);
				}
			} else
				sourceViewer.setTextHover(
						configuration.getTextHover(sourceViewer, t), t);
		}
	}

	@Override
	protected void handlePreferenceStoreChanged(PropertyChangeEvent event) {
		String property = event.getProperty();
		try {

			ISourceViewer sourceViewer = getSourceViewer();
			if (sourceViewer == null) {
				return;
			}
			boolean newBooleanValue = false;
			Object newValue = event.getNewValue();

			if (isEditorHoverProperty(property))
				updateHoverBehavior();

			if (newValue != null)
				newBooleanValue = Boolean.valueOf(newValue.toString())
						.booleanValue();
			if (PreferenceConstants.EDITOR_SYNC_OUTLINE_ON_CURSOR_MOVE
					.equals(property)) {
				if (newBooleanValue)
					selectionChanged();
				return;
			}

			if (occurrencesFinder != null && occurrencesFinder
					.handlePreferenceStoreChanged(property, newBooleanValue)) {
				return;
			}

			if (CodeFormatterConstants.FORMATTER_TAB_SIZE.equals(property)
					|| CodeFormatterConstants.FORMATTER_INDENTATION_SIZE
							.equals(property)
					|| CodeFormatterConstants.FORMATTER_TAB_CHAR
							.equals(property)) {
				if (CodeFormatterConstants.FORMATTER_TAB_CHAR
						.equals(property)) {
					if (isTabsToSpacesConversionEnabled())
						installTabsToSpacesConverter();
					else
						uninstallTabsToSpacesConverter();
				}
				updateIndentPrefixes();
				StyledText textWidget = sourceViewer.getTextWidget();
				int tabWidth = getSourceViewerConfiguration()
						.getTabWidth(sourceViewer);
				if (textWidget.getTabs() != tabWidth)
					textWidget.setTabs(tabWidth);
				return;
			}
			if (PreferenceConstants.EDITOR_SMART_TAB.equals(property)) {
				if (getPreferenceStore()
						.getBoolean(PreferenceConstants.EDITOR_SMART_TAB)) {
					setActionActivationCode(DLTKActionConstants.INDENT_ON_TAB,
							SWT.TAB, -1, SWT.NONE);
				} else {
					removeActionActivationCode(
							DLTKActionConstants.INDENT_ON_TAB);
				}
			}

			if (isFoldingPropertyEvent(property)
					&& sourceViewer instanceof ProjectionViewer) {
				handleFoldingPropertyEvent(property);
			}

			final ScriptSourceViewerConfiguration ssvc = (ScriptSourceViewerConfiguration) getSourceViewerConfiguration();
			final IContentAssistant c = ((AdaptedSourceViewer) sourceViewer)
					.getContentAssistant();
			if (c instanceof ContentAssistant) {
				ssvc.changeContentAssistantConfiguration((ContentAssistant) c,
						event);
			}
			ssvc.handlePropertyChangeEvent(event);
		} finally {
			super.handlePreferenceStoreChanged(event);
		}
		if (AbstractDecoratedTextEditorPreferenceConstants.SHOW_RANGE_INDICATOR
				.equals(property)) {
			// superclass already installed the range indicator
			Object newValue = event.getNewValue();
			ISourceViewer viewer = getSourceViewer();
			if (newValue != null && viewer != null) {
				if (Boolean.valueOf(newValue.toString()).booleanValue()) {
					// adjust the highlightrange in order to get the magnet
					// right after changing the selection
					Point selection = viewer.getSelectedRange();
					adjustHighlightRange(selection.x, selection.y);
				}
			}
		}
	}

	@Override
	protected boolean affectsTextPresentation(PropertyChangeEvent event) {
		return ((ScriptSourceViewerConfiguration) getSourceViewerConfiguration())
				.affectsTextPresentation(event)
				|| super.affectsTextPresentation(event);
	}

	protected void handleFoldingPropertyEvent(String property) {
		// NOTE: 'initially fold' preferences do not require handling
		if (PreferenceConstants.EDITOR_FOLDING_ENABLED.equals(property)) {
			ToggleFoldingRunner runner = new ToggleFoldingRunner();
			runner.runWhenNextVisible();
		} else {
			fProjectionModelUpdater.initialize(false);
		}
	}

	protected final boolean isFoldingPropertyEvent(String property) {
		if (isHandledPropertyEvent(property, GLOBAL_FOLDING_PROPERTIES)) {
			return true;
		}

		if (isHandledPropertyEvent(property, getFoldingEventPreferenceKeys())) {
			return true;
		}

		return false;
	}

	/**
	 * Returns a string array containing the language specific folding
	 * preference keys that should be handed when a property change event is
	 * fired.
	 *
	 * <p>
	 * Default implementation returns an empty array. Subclasses should override
	 * this method to return folding keys that are language specific.
	 * </p>
	 */
	protected String[] getFoldingEventPreferenceKeys() {
		return CharOperation.NO_STRINGS;
	}

	/**
	 * Text navigation action to navigate to the next sub-word.
	 *
	 *
	 */
	protected abstract class NextSubWordAction extends TextNavigationAction {
		protected DLTKWordIterator fIterator = new DLTKWordIterator();

		/**
		 * Creates a new next sub-word action.
		 *
		 * @param code
		 *            Action code for the default operation. Must be an action
		 *            code from
		 * @see org.eclipse.swt.custom.ST.
		 */
		protected NextSubWordAction(int code) {
			super(getSourceViewer().getTextWidget(), code);
		}

		/*
		 * @see org.eclipse.jface.action.IAction#run()
		 */
		@Override
		public void run() {
			// Check whether we are in ascriptcode partition and the preference
			// is enabled
			final IPreferenceStore store = getPreferenceStore();
			if (!store.getBoolean(
					PreferenceConstants.EDITOR_SUB_WORD_NAVIGATION)) {
				super.run();
				return;
			}
			final ISourceViewer viewer = getSourceViewer();
			final IDocument document = viewer.getDocument();
			fIterator.setText((CharacterIterator) new DocumentCharacterIterator(
					document));
			int position = widgetOffset2ModelOffset(viewer,
					viewer.getTextWidget().getCaretOffset());
			if (position == -1)
				return;
			int next = findNextPosition(position);
			if (next != BreakIterator.DONE) {
				setCaretPosition(next);
				getTextWidget().showSelection();
				fireSelectionChanged();
			}
		}

		/**
		 * Finds the next position after the given position.
		 *
		 * @param position
		 *            the current position
		 * @return the next position
		 */
		protected int findNextPosition(int position) {
			ISourceViewer viewer = getSourceViewer();
			int widget = -1;
			while (position != BreakIterator.DONE && widget == -1) { // TODO:
				// optimize
				position = fIterator.following(position);
				if (position != BreakIterator.DONE)
					widget = modelOffset2WidgetOffset(viewer, position);
			}
			return position;
		}

		/**
		 * Sets the caret position to the sub-word boundary given with
		 * <code>position</code>.
		 *
		 * @param position
		 *            Position where the action should move the caret
		 */
		protected abstract void setCaretPosition(int position);
	}

	/**
	 * Text navigation action to navigate to the next sub-word.
	 */
	protected class NavigateNextSubWordAction extends NextSubWordAction {
		/**
		 * Creates a new navigate next sub-word action.
		 */
		public NavigateNextSubWordAction() {
			super(ST.WORD_NEXT);
		}

		@Override
		protected void setCaretPosition(final int position) {
			getTextWidget().setCaretOffset(
					modelOffset2WidgetOffset(getSourceViewer(), position));
		}
	}

	/**
	 * Text operation action to delete the next sub-word.
	 */
	protected class DeleteNextSubWordAction extends NextSubWordAction
			implements IUpdate {
		/**
		 * Creates a new delete next sub-word action.
		 */
		public DeleteNextSubWordAction() {
			super(ST.DELETE_WORD_NEXT);
		}

		@Override
		protected void setCaretPosition(final int position) {
			if (!validateEditorInputState())
				return;
			final ISourceViewer viewer = getSourceViewer();
			final int caret, length;
			Point selection = viewer.getSelectedRange();
			if (selection.y != 0) {
				caret = selection.x;
				length = selection.y;
			} else {
				caret = widgetOffset2ModelOffset(viewer,
						viewer.getTextWidget().getCaretOffset());
				length = position - caret;
			}
			try {
				viewer.getDocument().replace(caret, length, ""); //$NON-NLS-1$
			} catch (BadLocationException exception) {
				// Should not happen
			}
		}

		@Override
		protected int findNextPosition(int position) {
			return fIterator.following(position);
		}

		/*
		 * @see org.eclipse.ui.texteditor.IUpdate#update()
		 */
		@Override
		public void update() {
			setEnabled(isEditorInputModifiable());
		}
	}

	/**
	 * Text operation action to select the next sub-word.
	 *
	 *
	 */
	protected class SelectNextSubWordAction extends NextSubWordAction {
		/**
		 * Creates a new select next sub-word action.
		 */
		public SelectNextSubWordAction() {
			super(ST.SELECT_WORD_NEXT);
		}

		@Override
		protected void setCaretPosition(final int position) {
			final ISourceViewer viewer = getSourceViewer();
			final StyledText text = viewer.getTextWidget();
			if (text != null && !text.isDisposed()) {
				final Point selection = text.getSelection();
				final int caret = text.getCaretOffset();
				final int offset = modelOffset2WidgetOffset(viewer, position);
				if (caret == selection.x)
					text.setSelectionRange(selection.y, offset - selection.y);
				else
					text.setSelectionRange(selection.x, offset - selection.x);
			}
		}
	}

	/**
	 * Text navigation action to navigate to the previous sub-word.
	 *
	 *
	 */
	protected abstract class PreviousSubWordAction
			extends TextNavigationAction {
		protected DLTKWordIterator fIterator = new DLTKWordIterator();

		/**
		 * Creates a new previous sub-word action.
		 *
		 * @param code
		 *            Action code for the default operation. Must be an action
		 *            code from
		 * @see org.eclipse.swt.custom.ST.
		 */
		protected PreviousSubWordAction(final int code) {
			super(getSourceViewer().getTextWidget(), code);
		}

		/*
		 * @see org.eclipse.jface.action.IAction#run()
		 */
		@Override
		public void run() {
			// Check whether we are in ascriptcode partition and the preference
			// is enabled
			final IPreferenceStore store = getPreferenceStore();
			if (!store.getBoolean(
					PreferenceConstants.EDITOR_SUB_WORD_NAVIGATION)) {
				super.run();
				return;
			}
			final ISourceViewer viewer = getSourceViewer();
			final IDocument document = viewer.getDocument();
			fIterator.setText((CharacterIterator) new DocumentCharacterIterator(
					document));
			int position = widgetOffset2ModelOffset(viewer,
					viewer.getTextWidget().getCaretOffset());
			if (position == -1)
				return;
			int previous = findPreviousPosition(position);
			if (previous != BreakIterator.DONE) {
				setCaretPosition(previous);
				getTextWidget().showSelection();
				fireSelectionChanged();
			}
		}

		/**
		 * Finds the previous position before the given position.
		 *
		 * @param position
		 *            the current position
		 * @return the previous position
		 */
		protected int findPreviousPosition(int position) {
			ISourceViewer viewer = getSourceViewer();
			int widget = -1;
			while (position != BreakIterator.DONE && widget == -1) { // TODO:
				// optimize
				position = fIterator.preceding(position);
				if (position != BreakIterator.DONE)
					widget = modelOffset2WidgetOffset(viewer, position);
			}
			return position;
		}

		/**
		 * Sets the caret position to the sub-word boundary given with
		 * <code>position</code>.
		 *
		 * @param position
		 *            Position where the action should move the caret
		 */
		protected abstract void setCaretPosition(int position);
	}

	/**
	 * Text navigation action to navigate to the previous sub-word.
	 */
	protected class NavigatePreviousSubWordAction
			extends PreviousSubWordAction {
		/**
		 * Creates a new navigate previous sub-word action.
		 */
		public NavigatePreviousSubWordAction() {
			super(ST.WORD_PREVIOUS);
		}

		@Override
		protected void setCaretPosition(final int position) {
			getTextWidget().setCaretOffset(
					modelOffset2WidgetOffset(getSourceViewer(), position));
		}
	}

	/**
	 * Text operation action to delete the previous sub-word.
	 */
	protected class DeletePreviousSubWordAction extends PreviousSubWordAction
			implements IUpdate {
		/**
		 * Creates a new delete previous sub-word action.
		 */
		public DeletePreviousSubWordAction() {
			super(ST.DELETE_WORD_PREVIOUS);
		}

		@Override
		protected void setCaretPosition(int position) {
			if (!validateEditorInputState())
				return;
			final int length;
			final ISourceViewer viewer = getSourceViewer();
			Point selection = viewer.getSelectedRange();
			if (selection.y != 0) {
				position = selection.x;
				length = selection.y;
			} else {
				length = widgetOffset2ModelOffset(viewer,
						viewer.getTextWidget().getCaretOffset()) - position;
			}
			try {
				viewer.getDocument().replace(position, length, ""); //$NON-NLS-1$
			} catch (BadLocationException exception) {
				// Should not happen
			}
		}

		@Override
		protected int findPreviousPosition(int position) {
			return fIterator.preceding(position);
		}

		@Override
		public void update() {
			setEnabled(isEditorInputModifiable());
		}
	}

	/**
	 * Text operation action to select the previous sub-word.
	 */
	protected class SelectPreviousSubWordAction extends PreviousSubWordAction {
		/**
		 * Creates a new select previous sub-word action.
		 */
		public SelectPreviousSubWordAction() {
			super(ST.SELECT_WORD_PREVIOUS);
		}

		@Override
		protected void setCaretPosition(final int position) {
			final ISourceViewer viewer = getSourceViewer();
			final StyledText text = viewer.getTextWidget();
			if (text != null && !text.isDisposed()) {
				final Point selection = text.getSelection();
				final int caret = text.getCaretOffset();
				final int offset = modelOffset2WidgetOffset(viewer, position);
				if (caret == selection.x)
					text.setSelectionRange(selection.y, offset - selection.y);
				else
					text.setSelectionRange(selection.x, offset - selection.x);
			}
		}
	}

	/*
	 * @see AbstractTextEditor#createNavigationActions()
	 */
	@Override
	protected void createNavigationActions() {
		super.createNavigationActions();
		final StyledText textWidget = getSourceViewer().getTextWidget();

		IAction action = new NavigatePreviousSubWordAction();
		action.setActionDefinitionId(
				ITextEditorActionDefinitionIds.WORD_PREVIOUS);
		setAction(ITextEditorActionDefinitionIds.WORD_PREVIOUS, action);
		textWidget.setKeyBinding(SWT.CTRL | SWT.ARROW_LEFT, SWT.NULL);

		action = new NavigateNextSubWordAction();
		action.setActionDefinitionId(ITextEditorActionDefinitionIds.WORD_NEXT);
		setAction(ITextEditorActionDefinitionIds.WORD_NEXT, action);
		textWidget.setKeyBinding(SWT.CTRL | SWT.ARROW_RIGHT, SWT.NULL);

		action = new SelectPreviousSubWordAction();
		action.setActionDefinitionId(
				ITextEditorActionDefinitionIds.SELECT_WORD_PREVIOUS);
		setAction(ITextEditorActionDefinitionIds.SELECT_WORD_PREVIOUS, action);
		textWidget.setKeyBinding(SWT.CTRL | SWT.SHIFT | SWT.ARROW_LEFT,
				SWT.NULL);

		action = new SelectNextSubWordAction();
		action.setActionDefinitionId(
				ITextEditorActionDefinitionIds.SELECT_WORD_NEXT);
		setAction(ITextEditorActionDefinitionIds.SELECT_WORD_NEXT, action);
		textWidget.setKeyBinding(SWT.CTRL | SWT.SHIFT | SWT.ARROW_RIGHT,
				SWT.NULL);

		action = new DeletePreviousSubWordAction();
		action.setActionDefinitionId(
				ITextEditorActionDefinitionIds.DELETE_PREVIOUS_WORD);
		setAction(ITextEditorActionDefinitionIds.DELETE_PREVIOUS_WORD, action);
		textWidget.setKeyBinding(SWT.CTRL | SWT.BS, SWT.NULL);
		markAsStateDependentAction(
				ITextEditorActionDefinitionIds.DELETE_PREVIOUS_WORD, true);

		action = new DeleteNextSubWordAction();
		action.setActionDefinitionId(
				ITextEditorActionDefinitionIds.DELETE_NEXT_WORD);
		setAction(ITextEditorActionDefinitionIds.DELETE_NEXT_WORD, action);
		textWidget.setKeyBinding(SWT.CTRL | SWT.DEL, SWT.NULL);
		markAsStateDependentAction(
				ITextEditorActionDefinitionIds.DELETE_NEXT_WORD, true);
	}

	@Override
	protected final ISourceViewer createSourceViewer(Composite parent,
			IVerticalRuler verticalRuler, int styles) {

		IPreferenceStore store = getPreferenceStore();
		ISourceViewer viewer = createScriptSourceViewer(parent, verticalRuler,
				getOverviewRuler(), isOverviewRulerVisible(), styles, store);

		if (DLTKCore.DEBUG) {
			System.err.println("Create help contexts"); //$NON-NLS-1$
		}
		// ScriptUIHelp.setHelp(this, viewer.getTextWidget(),
		// IScriptHelpContextIds.JAVA_EDITOR);

		ScriptSourceViewer scriptSourceViewer = null;
		if (viewer instanceof ScriptSourceViewer)
			scriptSourceViewer = (ScriptSourceViewer) viewer;

		/*
		 * This is a performance optimization to reduce the computation of the
		 * text presentation triggered by {@link #setVisibleDocument(IDocument)}
		 */
		if (scriptSourceViewer != null && isFoldingEnabled() && (store == null
				|| !store.getBoolean(PreferenceConstants.EDITOR_SHOW_SEGMENTS)))
			scriptSourceViewer.prepareDelayedProjection();

		ProjectionViewer projectionViewer = (ProjectionViewer) viewer;
		fProjectionSupport = new ProjectionSupport(projectionViewer,
				getAnnotationAccess(), getSharedColors());
		fProjectionSupport.addSummarizableAnnotationType(
				"org.eclipse.ui.workbench.texteditor.error"); //$NON-NLS-1$
		fProjectionSupport.addSummarizableAnnotationType(
				"org.eclipse.ui.workbench.texteditor.warning"); //$NON-NLS-1$
		final IDLTKLanguageToolkit toolkit = this.getLanguageToolkit();
		fProjectionSupport.setHoverControlCreator(shell -> {
			int shellStyle = SWT.TOOL | SWT.NO_TRIM | getOrientation();
			String statusFieldText = EditorsUI.getTooltipAffordanceString();
			return new SourceViewerInformationControl(shell, shellStyle,
					SWT.NONE, statusFieldText, toolkit);
		});
		fProjectionSupport.setInformationPresenterControlCreator(shell -> {
			int shellStyle = SWT.RESIZE | SWT.TOOL | getOrientation();
			int style = SWT.V_SCROLL | SWT.H_SCROLL;
			return new SourceViewerInformationControl(shell, shellStyle, style,
					toolkit);
		});

		fProjectionSupport.install();

		fProjectionModelUpdater = createFoldingStructureProvider();
		if (fProjectionModelUpdater != null)
			fProjectionModelUpdater.install(this, projectionViewer,
					getPreferenceStore());

		// ensure source viewer decoration support has been created and
		// configured
		getSourceViewerDecorationSupport(viewer);

		return viewer;
	}

	protected ISourceViewer createScriptSourceViewer(Composite parent,
			IVerticalRuler verticalRuler, IOverviewRuler overviewRuler,
			boolean isOverviewRulerVisible, int styles,
			IPreferenceStore store) {
		return new AdaptedSourceViewer(parent, verticalRuler,
				getOverviewRuler(), isOverviewRulerVisible(), styles, store);
	}

	/**
	 * Resets the foldings structure according to the folding preferences.
	 */
	public void resetProjection() {
		if (fProjectionModelUpdater != null) {
			fProjectionModelUpdater.initialize();
		}
	}

	/**
	 * Collapses all foldable members if supported by the folding structure
	 * provider.
	 *
	 *
	 */
	public void collapseMembers() {
		if (fProjectionModelUpdater instanceof IFoldingStructureProviderExtension) {
			IFoldingStructureProviderExtension extension = (IFoldingStructureProviderExtension) fProjectionModelUpdater;
			extension.collapseMembers();
		}
	}

	/**
	 * Collapses all foldable comments if supported by the folding structure
	 * provider.
	 *
	 *
	 */
	public void collapseComments() {
		if (fProjectionModelUpdater instanceof IFoldingStructureProviderExtension) {
			IFoldingStructureProviderExtension extension = (IFoldingStructureProviderExtension) fProjectionModelUpdater;
			extension.collapseComments();
		}
	}

	/*
	 * @see AbstractTextEditor#rulerContextMenuAboutToShow(IMenuManager)
	 */
	@Override
	protected void rulerContextMenuAboutToShow(IMenuManager menu) {
		super.rulerContextMenuAboutToShow(menu);
		IMenuManager foldingMenu = new MenuManager(
				DLTKEditorMessages.Editor_FoldingMenu_name, "projection"); //$NON-NLS-1$
		menu.appendToGroup(ITextEditorActionConstants.GROUP_RULERS,
				foldingMenu);

		IAction action = getAction("FoldingToggle"); //$NON-NLS-1$
		if (action != null) {
			foldingMenu.add(action);
		}
		action = getAction("FoldingExpandAll"); //$NON-NLS-1$
		if (action != null) {
			foldingMenu.add(action);
		}
		action = getAction("FoldingCollapseAll"); //$NON-NLS-1$
		if (action != null) {
			foldingMenu.add(action);
		}
		action = getAction("FoldingRestore"); //$NON-NLS-1$
		if (action != null) {
			foldingMenu.add(action);
		}
		action = getAction("FoldingCollapseMembers"); //$NON-NLS-1$
		if (action != null) {
			foldingMenu.add(action);
		}
		action = getAction("FoldingCollapseComments"); //$NON-NLS-1$
		if (action != null) {
			foldingMenu.add(action);
		}
	}

	/*
	 * @see org.eclipse.ui.texteditor.AbstractTextEditor#performRevert()
	 */
	@Override
	protected void performRevert() {
		ProjectionViewer projectionViewer = (ProjectionViewer) getSourceViewer();
		projectionViewer.setRedraw(false);
		try {

			boolean projectionMode = projectionViewer.isProjectionMode();
			if (projectionMode) {
				projectionViewer.disableProjection();
				if (fProjectionModelUpdater != null)
					fProjectionModelUpdater.uninstall();
			}

			super.performRevert();

			if (projectionMode) {
				if (fProjectionModelUpdater != null)
					fProjectionModelUpdater.install(this, projectionViewer,
							getPreferenceStore());
				projectionViewer.enableProjection();
			}

		} finally {
			projectionViewer.setRedraw(true);
		}
	}

	protected String getNatureId() {
		return getLanguageToolkit().getNatureId();
	}

	@Override
	public abstract IDLTKLanguageToolkit getLanguageToolkit();

	protected IDLTKUILanguageToolkit getUILanguageToolkit() {
		return DLTKUILanguageManager.getLanguageToolkit(getNatureId());
	}

	/**
	 * Return identifier of call hierarchy. Used by call hierarchy actions.
	 *
	 * @return
	 */
	public String getCallHierarchyID() {
		return null;
	}

	/*
	 * @see AbstractTextEditor#performSave(boolean, IProgressMonitor)
	 */
	@Override
	protected void performSave(boolean overwrite,
			IProgressMonitor progressMonitor) {
		IDocumentProvider p = getDocumentProvider();
		if (p instanceof ISourceModuleDocumentProvider) {
			ISourceModuleDocumentProvider cp = (ISourceModuleDocumentProvider) p;
			cp.setSavePolicy(fSavePolicy);
		}
		try {
			super.performSave(overwrite, progressMonitor);
		} finally {
			if (p instanceof ISourceModuleDocumentProvider) {
				ISourceModuleDocumentProvider cp = (ISourceModuleDocumentProvider) p;
				cp.setSavePolicy(null);
			}
		}
	}

	/*
	 * @see AbstractTextEditor#doSave(IProgressMonitor)
	 */
	@Override
	public void doSave(IProgressMonitor progressMonitor) {

		IDocumentProvider p = getDocumentProvider();
		if (p == null) {
			// editor has been closed
			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 {

				/*
				 * 1GF5YOX: ITPJUI:ALL - Save of delete file claims it's still
				 * there Missing resources.
				 */
				Shell shell = getSite().getShell();
				MessageDialog.openError(shell,
						DLTKEditorMessages.SourceModuleEditor_error_saving_title1,
						DLTKEditorMessages.SourceModuleEditor_error_saving_message1);
			}

		} else {

			setStatusLineErrorMessage(null);

			updateState(getEditorInput());
			validateState(getEditorInput());

			IWorkingCopyManager manager = DLTKUIPlugin.getDefault()
					.getWorkingCopyManager();
			ISourceModule unit = manager.getWorkingCopy(getEditorInput());

			if (unit != null) {
				// synchronized (unit) {
				performSave(false, progressMonitor);
				// }
			} else
				performSave(false, progressMonitor);
		}
	}

	/**
	 * Returns the signed current selection. The length will be negative if the
	 * resulting selection is right-to-left (RtoL).
	 * <p>
	 * The selection offset is model based.
	 * </p>
	 *
	 * @param sourceViewer
	 *            the source viewer
	 * @return a region denoting the current signed selection, for a resulting
	 *         RtoL selections length is < 0
	 */
	protected IRegion getSignedSelection(ISourceViewer sourceViewer) {
		StyledText text = sourceViewer.getTextWidget();
		Point selection = text.getSelectionRange();

		if (text.getCaretOffset() == selection.x) {
			selection.x = selection.x + selection.y;
			selection.y = -selection.y;
		}

		selection.x = widgetOffset2ModelOffset(sourceViewer, selection.x);

		return new Region(selection.x, selection.y);
	}

	protected final static char[] BRACKETS = { '{', '}', '(', ')', '[', ']' };

	protected static boolean isBracket(char character) {
		for (int i = 0; i != BRACKETS.length; ++i)
			if (character == BRACKETS[i])
				return true;
		return false;
	}

	protected static boolean isSurroundedByBrackets(IDocument document,
			int offset) {
		if (offset == 0 || offset == document.getLength())
			return false;

		try {
			return isBracket(document.getChar(offset - 1))
					&& isBracket(document.getChar(offset));

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

	private ICharacterPairMatcher fBracketMatcher;

	/**
	 * Returns the bracket matcher for this editor, delegates to
	 * {@link #createBracketMatcher()} to actually create it.
	 *
	 * @return the bracket matcher or <code>null</code>
	 */
	protected final ICharacterPairMatcher getBracketMatcher() {
		if (fBracketMatcher == null) {
			fBracketMatcher = createBracketMatcher();
		}
		return fBracketMatcher;
	}

	/**
	 * Override in your editor class to create bracket matcher for your
	 * language.
	 *
	 * @return
	 */
	protected ICharacterPairMatcher createBracketMatcher() {
		return null;
	}

	@Override
	protected void configureSourceViewerDecorationSupport(
			SourceViewerDecorationSupport support) {
		configureBracketMatcher(support);
		super.configureSourceViewerDecorationSupport(support);
	}

	protected void configureBracketMatcher(
			SourceViewerDecorationSupport support) {
		final ICharacterPairMatcher bracketMatcher = getBracketMatcher();
		if (bracketMatcher != null) {
			support.setCharacterPairMatcher(bracketMatcher);
			support.setMatchingCharacterPainterPreferenceKeys(MATCHING_BRACKETS,
					MATCHING_BRACKETS_COLOR);
		}
	}

	/**
	 * Jumps to the matching bracket.
	 */
	public void gotoMatchingBracket() {
		final ICharacterPairMatcher bracketMatcher = getBracketMatcher();
		if (bracketMatcher == null) {
			return;
		}
		ISourceViewer sourceViewer = getSourceViewer();
		IDocument document = sourceViewer.getDocument();
		if (document == null)
			return;

		IRegion selection = getSignedSelection(sourceViewer);

		int selectionLength = Math.abs(selection.getLength());
		if (selectionLength > 1) {
			setStatusLineErrorMessage(
					DLTKEditorMessages.ScriptEditor_nobracketSelected);
			sourceViewer.getTextWidget().getDisplay().beep();
			return;
		}

		// #26314
		int sourceCaretOffset = selection.getOffset() + selection.getLength();
		if (isSurroundedByBrackets(document, sourceCaretOffset))
			sourceCaretOffset -= selection.getLength();

		IRegion region = bracketMatcher.match(document, sourceCaretOffset);
		if (region == null) {
			setStatusLineErrorMessage(
					DLTKEditorMessages.ScriptEditor_noMatchingBracketFound);
			sourceViewer.getTextWidget().getDisplay().beep();
			return;
		}

		int offset = region.getOffset();
		int length = region.getLength();

		if (length < 1)
			return;

		int anchor = bracketMatcher.getAnchor();
		// http://dev.eclipse.org/bugs/show_bug.cgi?id=34195
		int targetOffset = (ICharacterPairMatcher.RIGHT == anchor) ? offset + 1
				: offset + length;

		boolean visible = false;
		if (sourceViewer instanceof ITextViewerExtension5) {
			ITextViewerExtension5 extension = (ITextViewerExtension5) sourceViewer;
			visible = (extension.modelOffset2WidgetOffset(targetOffset) > -1);
		} else {
			IRegion visibleRegion = sourceViewer.getVisibleRegion();
			// http://dev.eclipse.org/bugs/show_bug.cgi?id=34195
			visible = (targetOffset >= visibleRegion.getOffset()
					&& targetOffset <= visibleRegion.getOffset()
							+ visibleRegion.getLength());
		}

		if (!visible) {
			setStatusLineErrorMessage(
					DLTKEditorMessages.ScriptEditor_matchingBracketIsOutsideSelectedElement);
			sourceViewer.getTextWidget().getDisplay().beep();
			return;
		}

		if (selection.getLength() < 0)
			targetOffset -= selection.getLength();

		sourceViewer.setSelectedRange(targetOffset, selection.getLength());
		sourceViewer.revealRange(targetOffset, selection.getLength());
	}

	public void updatedTitleImage(Image image) {
		setTitleImage(image);
	}

	private ListenerList<IScriptReconcilingListener> fReconcilingListeners = new ListenerList<>(
			ListenerList.IDENTITY);

	/**
	 * Mutex for the reconciler. See
	 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=63898 for a description of
	 * the problem.
	 * <p>
	 * XXX remove once the underlying problem
	 * (https://bugs.eclipse.org/bugs/show_bug.cgi?id=66176) is solved.
	 * </p>
	 */
	private final Object fReconcilerLock = new Object();

	@Override
	public void aboutToBeReconciled() {

		// Notify AST provider
		// JavaPlugin.getDefault().getASTProvider().aboutToBeReconciled(
		// getInputJavaElement());

		// Notify listeners
		for (IScriptReconcilingListener listener : fReconcilingListeners)
			listener.aboutToBeReconciled();
	}

	/*
	 * @see
	 * org.eclipse.jdt.internal.ui.text.java.IJavaReconcilingListener#reconciled
	 * (CompilationUnit, boolean, IProgressMonitor)
	 *
	 * @since 3.0
	 */
	@Override
	public void reconciled(ISourceModule ast, boolean forced,
			IProgressMonitor progressMonitor) {

		// see: https://bugs.eclipse.org/bugs/show_bug.cgi?id=58245
		// JavaPlugin javaPlugin= JavaPlugin.getDefault();
		// if (javaPlugin == null)
		// return;
		//
		// // Always notify AST provider
		// javaPlugin.getASTProvider().reconciled(ast, getInputJavaElement(),
		// progressMonitor);

		// Notify listeners
		for (IScriptReconcilingListener listener : fReconcilingListeners)
			listener.reconciled(ast, forced, progressMonitor);

		// Update Outline page selection
		if (!forced && !progressMonitor.isCanceled()) {
			Shell shell = getSite().getShell();
			if (shell != null && !shell.isDisposed()) {
				shell.getDisplay().asyncExec(() -> selectionChanged());
			}
		}
	}

	public void addReconcileListener(
			IScriptReconcilingListener semanticHighlightingReconciler) {
		fReconcilingListeners.add(semanticHighlightingReconciler);
	}

	public void removeReconcileListener(
			IScriptReconcilingListener semanticHighlightingReconciler) {
		fReconcilingListeners.remove(semanticHighlightingReconciler);
	}

	private SemanticHighlightingManager fSemanticManager;

	private void installSemanticHighlighting() {
		ScriptTextTools textTools = getTextTools();
		if (fSemanticManager == null && textTools != null) {
			final ISemanticHighlightingUpdater updater = textTools
					.getSemanticPositionUpdater(getNatureId());
			if (updater != null) {
				fSemanticManager = new SemanticHighlightingManager(updater);
				fSemanticManager.install(this,
						(ScriptSourceViewer) getSourceViewer(),
						textTools.getColorManager(), getPreferenceStore());
			}
		}
	}

	private void updateSemanticHighlighting() {
		final IModelElement element = getInputModelElement();
		if (!(element instanceof ISourceModule)) {
			return;
		}
		Job job = new Job(
				DLTKEditorMessages.ScriptEditor_InitializeSemanticHighlighting) {
			@Override
			protected IStatus run(IProgressMonitor monitor) {
				if (fSemanticManager != null) {
					SemanticHighlightingReconciler reconciler = fSemanticManager
							.getReconciler();
					if (reconciler != null)
						reconciler.reconciled((ISourceModule) element, false,
								monitor);
				}
				return Status.OK_STATUS;
			}
		};
		job.setPriority(Job.DECORATE);
		job.setSystem(true);
		job.schedule();
	}

	/**
	 * Uninstall Semantic Highlighting.
	 *
	 * @since 3.0
	 */
	private void uninstallSemanticHighlighting() {
		if (fSemanticManager != null) {
			fSemanticManager.uninstall();
			fSemanticManager = null;
		}
	}

	@Override
	public int getOrientation() {
		return SWT.LEFT_TO_RIGHT;
	}

	@Override
	protected String[] collectContextMenuPreferencePages() {
		final List<String> result = new ArrayList<>();
		final IDLTKUILanguageToolkit uiToolkit = getUILanguageToolkit();
		addPages(result, uiToolkit.getEditorPreferencePages());
		addPages(result, super.collectContextMenuPreferencePages());
		return result.toArray(new String[result.size()]);
	}

	private void addPages(final List<String> result, final String[] pages) {
		if (pages != null) {
			for (int i = 0; i < pages.length; ++i) {
				if (!result.contains(pages[i])) {
					result.add(pages[i]);
				}
			}
		}
	}

	/*
	 * @see AbstractDecoratedTextEditor#isTabsToSpacesConversionEnabled()
	 */
	@Override
	protected boolean isTabsToSpacesConversionEnabled() {
		return getPreferenceStore() != null
				&& CodeFormatterConstants.SPACE.equals(getPreferenceStore()
						.getString(CodeFormatterConstants.FORMATTER_TAB_CHAR));
	}

	private boolean isHandledPropertyEvent(String property, String[] handled) {
		for (int i = 0; i < handled.length; i++) {
			if (handled[i].equals(property)) {
				return true;
			}
		}

		return false;
	}

	protected String getSymbolicFontName() {
		return getFontPropertyPreferenceKey();
	}

	/*
	 * Increase visibility for this package - called from {@link
	 * OccurrencesFinder}
	 */
	@Override
	protected IProgressMonitor getProgressMonitor() {
		return super.getProgressMonitor();
	}

}
