/*******************************************************************************
 * Copyright (c) 2005, 2016 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     QNX Software System
 *     Anton Leherbauer (Wind River Systems)
 *     Markus Schorn (Wind River Systems)
 *     Sergey Prigogin (Google)
 *     Axel Mueller - [289339] Surround with
 *     Tomasz Wesolowski - [320561] Override indicators
 *     Serge Beauchamp (Freescale Semiconductor) - Bug 417909
 *******************************************************************************/
package org.eclipse.cdt.internal.ui.editor;

import java.text.CharacterIterator;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Deque;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.Set;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.ProjectScope;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.ListenerList;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.content.IContentType;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.core.runtime.preferences.IPreferencesService;
import org.eclipse.help.IContext;
import org.eclipse.help.IContextProvider;
import org.eclipse.jface.action.GroupMarker;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IStatusLineManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.dialogs.MessageDialogWithToggle;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.preference.PreferenceDialog;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.BadPositionCategoryException;
import org.eclipse.jface.text.DefaultLineTracker;
import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.DocumentEvent;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IDocumentExtension;
import org.eclipse.jface.text.IDocumentExtension4;
import org.eclipse.jface.text.IDocumentListener;
import org.eclipse.jface.text.IInformationControl;
import org.eclipse.jface.text.IInformationControlCreator;
import org.eclipse.jface.text.IPositionUpdater;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ISelectionValidator;
import org.eclipse.jface.text.ISynchronizable;
import org.eclipse.jface.text.ITextHover;
import org.eclipse.jface.text.ITextInputListener;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.ITextViewerExtension;
import org.eclipse.jface.text.ITextViewerExtension2;
import org.eclipse.jface.text.ITextViewerExtension5;
import org.eclipse.jface.text.ITextViewerExtension7;
import org.eclipse.jface.text.ITypedRegion;
import org.eclipse.jface.text.IWidgetTokenKeeper;
import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.Region;
import org.eclipse.jface.text.TextUtilities;
import org.eclipse.jface.text.contentassist.ContentAssistant;
import org.eclipse.jface.text.contentassist.IContentAssistant;
import org.eclipse.jface.text.formatter.FormattingContext;
import org.eclipse.jface.text.formatter.FormattingContextProperties;
import org.eclipse.jface.text.formatter.IFormattingContext;
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.link.LinkedPosition;
import org.eclipse.jface.text.link.LinkedPositionGroup;
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.IAnnotationModelExtension;
import org.eclipse.jface.text.source.IAnnotationModelExtension2;
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.ProjectionAnnotationModel;
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.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.window.Window;
import org.eclipse.search.ui.actions.TextSearchGroup;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.custom.ST;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.custom.VerifyKeyListener;
import org.eclipse.swt.events.HelpEvent;
import org.eclipse.swt.events.HelpListener;
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.IActionBars;
import org.eclipse.ui.IEditorActionBarContributor;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.IPageLayout;
import org.eclipse.ui.IPartService;
import org.eclipse.ui.ISelectionListener;
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.dialogs.PreferencesUtil;
import org.eclipse.ui.editors.text.EditorsUI;
import org.eclipse.ui.editors.text.TextEditor;
import org.eclipse.ui.help.IWorkbenchHelpSystem;
import org.eclipse.ui.ide.IGotoMarker;
import org.eclipse.ui.navigator.ICommonMenuConstants;
import org.eclipse.ui.part.EditorActionBarContributor;
import org.eclipse.ui.part.IShowInSource;
import org.eclipse.ui.part.IShowInTargetList;
import org.eclipse.ui.part.ShowInContext;
import org.eclipse.ui.texteditor.AbstractDecoratedTextEditorPreferenceConstants;
import org.eclipse.ui.texteditor.AbstractMarkerAnnotationModel;
import org.eclipse.ui.texteditor.AnnotationPreference;
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.MarkerAnnotation;
import org.eclipse.ui.texteditor.MarkerUtilities;
import org.eclipse.ui.texteditor.SourceViewerDecorationSupport;
import org.eclipse.ui.texteditor.TextNavigationAction;
import org.eclipse.ui.texteditor.TextOperationAction;
import org.eclipse.ui.texteditor.link.EditorLinkedModeUI;
import org.eclipse.ui.texteditor.templates.ITemplatesPage;
import org.eclipse.ui.views.contentoutline.IContentOutlinePage;

import com.ibm.icu.text.BreakIterator;

import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.CCorePreferenceConstants;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNodeSelector;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.gnu.cpp.GPPLanguage;
import org.eclipse.cdt.core.formatter.DefaultCodeFormatterConstants;
import org.eclipse.cdt.core.model.CModelException;
import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.core.model.ILanguage;
import org.eclipse.cdt.core.model.ISourceRange;
import org.eclipse.cdt.core.model.ISourceReference;
import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.core.model.ITranslationUnitHolder;
import org.eclipse.cdt.core.model.IWorkingCopy;
import org.eclipse.cdt.ui.CUIPlugin;
import org.eclipse.cdt.ui.ICEditor;
import org.eclipse.cdt.ui.ICModelBasedEditor;
import org.eclipse.cdt.ui.IWorkingCopyManager;
import org.eclipse.cdt.ui.PreferenceConstants;
import org.eclipse.cdt.ui.actions.GenerateActionGroup;
import org.eclipse.cdt.ui.actions.OpenViewActionGroup;
import org.eclipse.cdt.ui.refactoring.actions.CRefactoringActionGroup;
import org.eclipse.cdt.ui.text.CSourceViewerConfiguration;
import org.eclipse.cdt.ui.text.ICPartitions;
import org.eclipse.cdt.ui.text.folding.ICFoldingStructureProvider;

import org.eclipse.cdt.internal.core.model.ASTCache.ASTRunnable;
import org.eclipse.cdt.internal.corext.util.CodeFormatterUtil;

import org.eclipse.cdt.internal.ui.CPluginImages;
import org.eclipse.cdt.internal.ui.ICHelpContextIds;
import org.eclipse.cdt.internal.ui.IContextMenuConstants;
import org.eclipse.cdt.internal.ui.actions.AddBlockCommentAction;
import org.eclipse.cdt.internal.ui.actions.AlignConstAction;
import org.eclipse.cdt.internal.ui.actions.FindWordAction;
import org.eclipse.cdt.internal.ui.actions.FoldingActionGroup;
import org.eclipse.cdt.internal.ui.actions.GoToNextPreviousMemberAction;
import org.eclipse.cdt.internal.ui.actions.GotoNextBookmarkAction;
import org.eclipse.cdt.internal.ui.actions.IndentAction;
import org.eclipse.cdt.internal.ui.actions.RemoveBlockCommentAction;
import org.eclipse.cdt.internal.ui.actions.StructureSelectEnclosingAction;
import org.eclipse.cdt.internal.ui.actions.StructureSelectHistoryAction;
import org.eclipse.cdt.internal.ui.actions.StructureSelectNextAction;
import org.eclipse.cdt.internal.ui.actions.StructureSelectPreviousAction;
import org.eclipse.cdt.internal.ui.actions.StructureSelectionAction;
import org.eclipse.cdt.internal.ui.actions.SurroundWithActionGroup;
import org.eclipse.cdt.internal.ui.dialogs.FormattingScopeDialog;
import org.eclipse.cdt.internal.ui.search.IOccurrencesFinder;
import org.eclipse.cdt.internal.ui.search.IOccurrencesFinder.OccurrenceLocation;
import org.eclipse.cdt.internal.ui.search.OccurrencesFinder;
import org.eclipse.cdt.internal.ui.search.actions.SelectionSearchGroup;
import org.eclipse.cdt.internal.ui.text.CHeuristicScanner;
import org.eclipse.cdt.internal.ui.text.CPairMatcher;
import org.eclipse.cdt.internal.ui.text.CSourceViewerScalableConfiguration;
import org.eclipse.cdt.internal.ui.text.CTextTools;
import org.eclipse.cdt.internal.ui.text.CWordFinder;
import org.eclipse.cdt.internal.ui.text.CWordIterator;
import org.eclipse.cdt.internal.ui.text.DocumentCharacterIterator;
import org.eclipse.cdt.internal.ui.text.ICReconcilingListener;
import org.eclipse.cdt.internal.ui.text.Symbols;
import org.eclipse.cdt.internal.ui.text.TabsToSpacesConverter;
import org.eclipse.cdt.internal.ui.text.c.hover.CExpandHover;
import org.eclipse.cdt.internal.ui.text.c.hover.SourceViewerInformationControl;
import org.eclipse.cdt.internal.ui.text.contentassist.ContentAssistPreference;
import org.eclipse.cdt.internal.ui.util.CUIHelp;
import org.eclipse.cdt.internal.ui.util.EditorUtility;
import org.eclipse.cdt.internal.ui.viewsupport.ISelectionListenerWithAST;
import org.eclipse.cdt.internal.ui.viewsupport.SelectionListenerWithASTManager;

/**
 * C/C++ source editor.
 */
public class CEditor extends TextEditor implements ICEditor, ISelectionChangedListener, ICReconcilingListener, 
		ICModelBasedEditor {
	/** Marker used for synchronization from Problems View to the editor on double-click. */
	private IMarker fSyncProblemsViewMarker;

	/**
	 * A slightly modified implementation of IGotomarker compared to AbstractDecoratedTextEditor.
	 * 
	 * @since 5.0
	 */
	private final class GotoMarkerAdapter implements IGotoMarker {
		@Override
		public void gotoMarker(IMarker marker) {
			if (fIsUpdatingMarkerViews)
				return;

			if (getSourceViewer() == null)
				return;

			int start= MarkerUtilities.getCharStart(marker);
			int end= MarkerUtilities.getCharEnd(marker);
			
			boolean selectLine= start < 0 || end < 0;

			// Look up the current range of the marker when the document has been edited.
			IAnnotationModel model= getDocumentProvider().getAnnotationModel(getEditorInput());
			if (model instanceof AbstractMarkerAnnotationModel) {
				AbstractMarkerAnnotationModel markerModel= (AbstractMarkerAnnotationModel) model;
				Position pos= markerModel.getMarkerPosition(marker);
				if (pos != null && !pos.isDeleted()) {
					// Use position instead of marker values
					start= pos.getOffset();
					end= pos.getOffset() + pos.getLength();
					// Use position as is
					selectLine= false;
				}

				if (pos != null && pos.isDeleted()) {
					// Do nothing if position has been deleted
					return;
				}
			}

			IDocument document= getDocumentProvider().getDocument(getEditorInput());

			if (selectLine) {
				int line;
				try {
					if (start >= 0) {
						IRegion lineInfo= document.getLineInformationOfOffset(start);
						start= lineInfo.getOffset();
						end= start + lineInfo.getLength();
					} else {
						line= MarkerUtilities.getLineNumber(marker);
						// Marker line numbers are 1-based
						-- line;
						IRegion lineInfo= document.getLineInformation(line);
						start= lineInfo.getOffset();
						end= start + lineInfo.getLength();
					}
				} catch (BadLocationException e) {
					return;
				}
			}

			int length= document.getLength();
			if (end - 1 < length && start < length) {
				fSyncProblemsViewMarker = marker;
				selectAndReveal(start, end - start);
			}
		}
	}

	class AdaptedSourceViewer extends CSourceViewer {

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

		@Override
		public IContentAssistant getContentAssistant() {
			return fContentAssistant;
		}

		@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:
					/*
					 * TODO: 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;
			}

			super.doOperation(operation);
		}

		@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);
		}

		// This method is called only when the Platform version is below 4.5.
		// TODO(sprigogin): Remove this override once compatibility with Platform 4.4 is no longer
		// required.
		@Override
		protected IFormattingContext createFormattingContext() {
			Point selectedRange = getSelectedRange();
			return createFormattingContext(selectedRange.x, selectedRange.y, false);
		}

		@Override
		protected IFormattingContext createFormattingContext(int selectionOffset, int selectionLength) {
			return createFormattingContext(selectionOffset, selectionLength, true);
		}

		private IFormattingContext createFormattingContext(int selectionOffset, int selectionLength,
				boolean formattingScopeForEmptySelectionSupported) {
			IFormattingContext context= new FormattingContext();

			Map<String, Object> preferences;
			ICElement inputCElement= getInputCElement();
			ICProject cProject= inputCElement != null ? inputCElement.getCProject() : null;
			if (cProject == null) {
				preferences= new HashMap<String, Object>(CCorePlugin.getOptions());
			} else {
				preferences= new HashMap<String, Object>(cProject.getOptions(true));
			}

			if (inputCElement instanceof ITranslationUnit) {
				ITranslationUnit tu= (ITranslationUnit) inputCElement;
				ILanguage language;
				try {
					language= tu.getLanguage();
				} catch (CoreException e) {
					// Use fallback CPP
					language= GPPLanguage.getDefault();
				}
				preferences.put(DefaultCodeFormatterConstants.FORMATTER_TRANSLATION_UNIT, tu);
		        preferences.put(DefaultCodeFormatterConstants.FORMATTER_LANGUAGE, language);
				preferences.put(DefaultCodeFormatterConstants.FORMATTER_CURRENT_FILE, tu.getResource());
				boolean formatWholeDocument = false;
				if (formattingScopeForEmptySelectionSupported && selectionLength == 0) {
					// The selection is empty. Determine how it should be interpreted.
					IPreferencesService preferenceService = Platform.getPreferencesService();
					boolean showDialog = preferenceService.getBoolean(CUIPlugin.PLUGIN_ID,
							PreferenceConstants.FORMATTING_CONFIRM_SCOPE_FOR_EMPTY_SELECTION, true, null);
					if (showDialog) {
						if (!confirmFormattingScope()) {
							// The user clicked Cancel. Abort the formatting operation.
							context.dispose();
							return null;
						}
					}
					String scope = preferenceService.getString(CUIPlugin.PLUGIN_ID,
							PreferenceConstants.FORMATTING_SCOPE_FOR_EMPTY_SELECTION,
							PreferenceConstants.FORMATTING_SCOPE_DOCUMENT, null);
					if (PreferenceConstants.FORMATTING_SCOPE_DOCUMENT.equals(scope)) {
						formatWholeDocument = true;
					} else {
						preferences.put(DefaultCodeFormatterConstants.FORMATTER_STATEMENT_SCOPE, Boolean.TRUE);
					}
				}
				if (!formatWholeDocument) {
					context.setProperty(FormattingContextProperties.CONTEXT_REGION,
							new Region(selectionOffset, selectionLength));
				}
			}

			if (cProject == null) {
				// custom formatter specified?
				String customFormatterId= getPreferenceStore().getString(CCorePreferenceConstants.CODE_FORMATTER);
				if (customFormatterId != null) {
					preferences.put(CCorePreferenceConstants.CODE_FORMATTER, customFormatterId);
				}
			}
			context.setProperty(FormattingContextProperties.CONTEXT_PREFERENCES, preferences);

			return context;
		}

		private boolean confirmFormattingScope() {
			int redrawCount = 0;
			while (!redraws()) {
				redrawCount++;
				setRedraw(true);
			}
			try {
				Dialog dialog = new FormattingScopeDialog(getSite().getShell());
				return dialog.open() == Window.OK;
			} finally {
				while (--redrawCount >= 0) {
					setRedraw(false);
				}
			}
		}
	}

	private static class ExitPolicy implements IExitPolicy {
		final char fExitCharacter;
		final char fEscapeCharacter;
		final Deque<BracketLevel> fStack;
		final int fSize;
		ISourceViewer sourceViewer;

		public ExitPolicy(char exitCharacter, char escapeCharacter, Deque<BracketLevel> stack, ISourceViewer sViewer) {
			fExitCharacter = exitCharacter;
			fEscapeCharacter = escapeCharacter;
			fStack = stack;
			fSize = fStack.size();
			sourceViewer = sViewer;
		}

		@Override
		public ExitFlags doExit(LinkedModeModel model, VerifyEvent event, int offset, int length) {
			if (fSize == fStack.size() && !isMasked(offset)) {
				if (event.character == fExitCharacter) {
					BracketLevel level = 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) {
					IDocument document = sourceViewer.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 = sourceViewer.getDocument();
			try {
				return fEscapeCharacter == document.getChar(offset - 1);
			} catch (BadLocationException e) {
			}
			return false;
		}
	}

	private static class BracketLevel {
		LinkedModeUI fUI;
		Position fFirstPosition;
		Position fSecondPosition;
	}

	/**
	 * Position updater that takes any changes at the borders of a position to not belong to the position.
	 *
	 * @since 4.0
	 */
	private static class ExclusivePositionUpdater implements IPositionUpdater {
		/** The position category. */
		private final String fCategory;

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

		@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;
//		}
	}

	public static class BracketInserter implements VerifyKeyListener, ILinkedModeListener {
		private boolean fCloseBrackets = true;
		private boolean fCloseStrings = true;
		private boolean fCloseAngularBrackets = true;
		private boolean fCloseBraces = true;
		private final String CATEGORY = toString();
		private final IPositionUpdater fUpdater = new ExclusivePositionUpdater(CATEGORY);
		private final Deque<BracketLevel> fBracketLevelStack = new ArrayDeque<>();
		private ISourceViewer sourceViewer;
		private boolean isGenericEditor;
		private TextEditor fEditor;

		public BracketInserter(TextEditor editor, boolean isGenericEditor) {
			fEditor = editor;
			this.isGenericEditor = isGenericEditor;
		}

		public void setSourceViewer(ISourceViewer sViewer) {
			sourceViewer = sViewer;
		}

		public void setCloseBracketsEnabled(boolean enabled) {
			fCloseBrackets = enabled;
		}

		public void setCloseStringsEnabled(boolean enabled) {
			fCloseStrings = enabled;
		}

		public void setCloseAngularBracketsEnabled(boolean enabled) {
			fCloseAngularBrackets = enabled;
		}

		public void setCloseBracesEnabled(boolean enabled) {
			fCloseBraces = enabled;
		}

		private boolean isAngularIntroducer(String identifier) {
			return identifier.length() > 0 && (Character.isUpperCase(identifier.charAt(0))
					|| angularIntroducers.contains(identifier)
					|| identifier.endsWith("_ptr") //$NON-NLS-1$
					|| identifier.endsWith("_cast")); //$NON-NLS-1$
		}

		@Override
		public void verifyKey(VerifyEvent event) {
			// Early pruning to minimize overhead for normal typing.
			if (!event.doit)
				return;

//			Need to check that it is Generic Editor or CEditor before checking "Smart Insert" mode
//			because Generic Editor doesn't have a "Smart Insert" mode.
			if(!isGenericEditor)
				if (fEditor.getInsertMode() != SMART_INSERT)
						return;
			switch (event.character) {
				case '(':
				case '<':
				case '[':
				case '{':
				case '\'':
				case '\"':
					break;
				default:
					return;
			}

			IDocument document = sourceViewer.getDocument();

			final Point selection = sourceViewer.getSelectedRange();
			final int offset = selection.x;
			final int length = selection.y;
			try {
				IRegion startLine = document.getLineInformationOfOffset(offset);
				IRegion endLine = document.getLineInformationOfOffset(offset + length);
				if (startLine != endLine && fEditor.isBlockSelectionModeEnabled()) {
					return;
				}

				ITypedRegion partition = TextUtilities.getPartition(document, ICPartitions.C_PARTITIONING, offset, true);
				if (!IDocument.DEFAULT_CONTENT_TYPE.equals(partition.getType())
						&& !ICPartitions.C_PREPROCESSOR.equals(partition.getType())) {
					return;
				}

				CHeuristicScanner scanner = new CHeuristicScanner(document, ICPartitions.C_PARTITIONING, partition.getType());
				int nextToken = scanner.nextToken(offset + length, endLine.getOffset() + endLine.getLength());
				String next = nextToken == Symbols.TokenEOF ? null : document.get(offset, scanner.getPosition() - offset).trim();
				int prevToken = scanner.previousToken(offset - 1, startLine.getOffset());
				int prevTokenOffset = scanner.getPosition() + 1;
				String previous = prevToken == Symbols.TokenEOF ? null : document.get(prevTokenOffset, offset - prevTokenOffset).trim();

				switch (event.character) {
					case '(':
						if (!fCloseBrackets
								|| nextToken == Symbols.TokenLPAREN
								|| nextToken == Symbols.TokenIDENT
								|| next != null && next.length() > 1) {
							return;
						}
						break;

					case '<':
						if (!(fCloseAngularBrackets && fCloseBrackets)
								|| nextToken == Symbols.TokenLESSTHAN
								|| prevToken != Symbols.TokenIDENT
								|| !isAngularIntroducer(previous)) {
							return;
						}
						break;

					case '[':
						if (!fCloseBrackets
								|| nextToken == Symbols.TokenIDENT
								|| next != null && next.length() > 1) {
							return;
						}
						break;

					case '{':
						// An opening brace inside parentheses probably starts an initializer list -
						// close it.
						if (!fCloseBraces
								|| nextToken == Symbols.TokenIDENT
								|| next != null && next.length() > 1
								|| !isInsideParentheses(scanner, offset - 1)) {
							return;
						}
						break;

					case '\'':
					case '"':
						if (!fCloseStrings
								|| nextToken == Symbols.TokenIDENT
								|| next != null && (next.length() > 1 || next.charAt(0) == event.character)
								|| isInsideStringInPreprocessorDirective(partition, document, offset)) {
							return;
						}
						break;

					default:
						return;
				}

				if (!fEditor.validateEditorInputState())
					return;

				final char character = event.character;
				final char closingCharacter = getPeerCharacter(character);
				final StringBuilder buffer = new StringBuilder(3);
				buffer.append(character);
				buffer.append(closingCharacter);

				document.replace(offset, length, buffer.toString());

				BracketLevel level = new BracketLevel();
				fBracketLevelStack.push(level);

				LinkedPositionGroup group = new LinkedPositionGroup();
				group.addPosition(new LinkedPosition(document, offset + 1, 0, LinkedPositionGroup.NO_STOP));

				LinkedModeModel model = new LinkedModeModel();
				model.addLinkingListener(this);
				model.addGroup(group);
				model.forceInstall();

				// Set up position tracking for our magic peers.
				if (fBracketLevelStack.size() == 1) {
					document.addPositionCategory(CATEGORY);
					document.addPositionUpdater(fUpdater);
				}
				level.fFirstPosition = new Position(offset, 1);
				level.fSecondPosition = new Position(offset + 1, 1);
				document.addPosition(CATEGORY, level.fFirstPosition);
				document.addPosition(CATEGORY, level.fSecondPosition);

				level.fUI = new EditorLinkedModeUI(model, sourceViewer);
				level.fUI.setSimpleMode(true);
				level.fUI.setExitPolicy(new ExitPolicy(closingCharacter, getEscapeCharacter(closingCharacter), fBracketLevelStack, sourceViewer));
				level.fUI.setExitPosition(sourceViewer, offset + 2, 0, Integer.MAX_VALUE);
				level.fUI.setCyclingMode(LinkedModeUI.CYCLE_NEVER);
				level.fUI.enter();

				IRegion newSelection = level.fUI.getSelectedRegion();
				sourceViewer.setSelectedRange(newSelection.getOffset(), newSelection.getLength());

				event.doit = false;
			} catch (BadLocationException | BadPositionCategoryException e) {
				CUIPlugin.log(e);
			}
		}

		private boolean isInsideParentheses(CHeuristicScanner scanner, int offset) {
			int depth = 0;
			// Limit the scanning distance to 100 tokens.
			for (int i = 0; i < 100; i++) {
				int token = scanner.previousToken(offset, 0);
				if (token == Symbols.TokenLPAREN) {
					if (--depth < 0)
						return true;
				} else if (token == Symbols.TokenRPAREN) {
					++depth;
				} else if (token == Symbols.TokenEOF) {
					return false;
				}
				offset = scanner.getPosition();
			}
			return false;
		}

		private boolean isInsideStringInPreprocessorDirective(ITypedRegion partition, IDocument document, int offset) throws BadLocationException {
			if (ICPartitions.C_PREPROCESSOR.equals(partition.getType()) && offset < document.getLength()) {
				// Use temporary document to test whether offset is inside non-default partition.
				String directive = document.get(partition.getOffset(), offset - partition.getOffset() + 1);
				int hashIdx = directive.indexOf('#');
				if (hashIdx >= 0) {
					IDocument tmp = new Document(directive.substring(hashIdx + 1));
					new CDocumentSetupParticipant().setup(tmp);
					String type = TextUtilities.getContentType(tmp, ICPartitions.C_PARTITIONING, offset - (partition.getOffset() + hashIdx + 1), true);
					if (!type.equals(IDocument.DEFAULT_CONTENT_TYPE)) {
						return true;
					}
				}
			}
			return false;
		}

		@Override
		public void left(LinkedModeModel environment, int flags) {
			final BracketLevel level = fBracketLevelStack.pop();

			if (flags != ILinkedModeListener.EXTERNAL_MODIFICATION)
				return;

			// remove brackets
			final IDocument document = sourceViewer.getDocument();
			if (document instanceof IDocumentExtension) {
				IDocumentExtension extension = (IDocumentExtension) document;
				extension.registerPostNotificationReplace(null, new IDocumentExtension.IReplace() {
					@Override
					public void perform(IDocument d, IDocumentListener owner) {
						if ((level.fFirstPosition.isDeleted || level.fFirstPosition.length == 0)
								&& !level.fSecondPosition.isDeleted
								&& level.fSecondPosition.offset == level.fFirstPosition.offset) {
							try {
								document.replace(level.fSecondPosition.offset,
												 level.fSecondPosition.length,
												 null);
							} catch (BadLocationException e) {
								CUIPlugin.log(e);
							}
						}

						if (fBracketLevelStack.size() == 0) {
							document.removePositionUpdater(fUpdater);
							try {
								document.removePositionCategory(CATEGORY);
							} catch (BadPositionCategoryException e) {
								CUIPlugin.log(e);
							}
						}
					}
				});
			}
		}

		@Override
		public void suspend(LinkedModeModel environment) {
		}

		@Override
		public void resume(LinkedModeModel environment, int flags) {
		}
	}

	/**
	 * Updates the C outline page selection and this editor's range indicator.
	 *
	 * @since 3.0
	 */
	private class EditorSelectionChangedListener extends AbstractSelectionChangedListener {
		@Override
		public void selectionChanged(SelectionChangedEvent event) {
			// TODO: see https://bugs.eclipse.org/bugs/show_bug.cgi?id=56161
			CEditor.this.selectionChanged();
		}
	}

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

		/**
		 * 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);
		}

		@Override
		public void run() {
			// Check whether sub word navigation is enabled.
			final IPreferenceStore store = getPreferenceStore();
			if (!store.getBoolean(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);
			try {
				if (isBlockSelectionModeEnabled() && document.getLineOfOffset(next) != document.getLineOfOffset(position)) {
					super.run(); // may navigate into virtual white space
				} else if (next != BreakIterator.DONE) {
					setCaretPosition(next);
					getTextWidget().showSelection();
					fireSelectionChanged();
				}
			} catch (BadLocationException x) {
				// ignore
			}
		}

		/**
		 * 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}.
		 *
		 * @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.
	 *
	 * @since 4.0
	 */
	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.
	 *
	 * @since 4.0
	 */
	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();
			StyledText text= viewer.getTextWidget();
			Point widgetSelection= text.getSelection();
			if (isBlockSelectionModeEnabled() && widgetSelection.y != widgetSelection.x) {
				final int caret= text.getCaretOffset();
				final int offset= modelOffset2WidgetOffset(viewer, position);

				if (caret == widgetSelection.x)
					text.setSelectionRange(widgetSelection.y, offset - widgetSelection.y);
				else
					text.setSelectionRange(widgetSelection.x, offset - widgetSelection.x);
				text.invokeAction(ST.DELETE_NEXT);
			} else {
				Point selection= viewer.getSelectedRange();
				final int caret, length;
				if (selection.y != 0) {
					caret= selection.x;
					length= selection.y;
				} else {
					caret= widgetOffset2ModelOffset(viewer, text.getCaretOffset());
					length= position - caret;
				}

				try {
					viewer.getDocument().replace(caret, length, ""); //$NON-NLS-1$
				} catch (BadLocationException e) {
					// Should not happen
				}
			}
		}

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

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

	/**
	 * Text operation action to select the next sub-word.
	 *
	 * @since 4.0
	 */
	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.
	 *
	 * @since 4.0
	 */
	protected abstract class PreviousSubWordAction extends TextNavigationAction {
		protected CWordIterator fIterator = new CWordIterator();

		/**
		 * 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);
		}

		@Override
		public void run() {
			// Check whether sub word navigation is enabled.
			final IPreferenceStore store = getPreferenceStore();
			if (!store.getBoolean(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);
			try {
				if (isBlockSelectionModeEnabled() && document.getLineOfOffset(previous) != document.getLineOfOffset(position)) {
					super.run(); // may navigate into virtual white space
				} else if (previous != BreakIterator.DONE) {
					setCaretPosition(previous);
					getTextWidget().showSelection();
					fireSelectionChanged();
				}
			} catch (BadLocationException e) {
				// ignore - getLineOfOffset failed
			}
		}

		/**
		 * 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}.
		 *
		 * @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.
	 *
	 * @since 4.0
	 */
	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.
	 *
	 * @since 4.0
	 */
	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();
			StyledText text= viewer.getTextWidget();
			Point widgetSelection= text.getSelection();
			if (isBlockSelectionModeEnabled() && widgetSelection.y != widgetSelection.x) {
				final int caret= text.getCaretOffset();
				final int offset= modelOffset2WidgetOffset(viewer, position);

				if (caret == widgetSelection.x)
					text.setSelectionRange(widgetSelection.y, offset - widgetSelection.y);
				else
					text.setSelectionRange(widgetSelection.x, offset - widgetSelection.x);
				text.invokeAction(ST.DELETE_PREVIOUS);
			} else {
				Point selection= viewer.getSelectedRange();
				if (selection.y != 0) {
					position= selection.x;
					length= selection.y;
				} else {
					length= widgetOffset2ModelOffset(viewer, text.getCaretOffset()) - position;
				}

				try {
					viewer.getDocument().replace(position, length, ""); //$NON-NLS-1$
				} catch (BadLocationException e) {
					// 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.
	 *
	 * @since 4.0
	 */
	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);
				}
			}
		}
	}

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

	/**
	 * Time when last error message got set.
	 * 
	 * @since 5.3
	 */
	private long fErrorMessageTime;

	/**
	 * Timeout for the error message.
	 * 
	 * @since 5.3
	 */
	private static final long ERROR_MESSAGE_TIMEOUT= 1000;

	/** The outline page */
	protected CContentOutlinePage fOutlinePage;

	/** Search actions **/
	private ActionGroup fSelectionSearchGroup;
	private ActionGroup fTextSearchGroup;
	private CRefactoringActionGroup fRefactoringActionGroup;
	private ActionGroup fOpenInViewGroup;

	/** Generate action group filling the "Source" submenu */
	private GenerateActionGroup fGenerateActionGroup;
	
	/** Generate action group filling the "Surround with" submenu */
	private SurroundWithActionGroup fSurroundWithActionGroup;

	/** Pairs of brackets, used to match. */
    protected static final char[] BRACKETS = { '{', '}', '(', ')', '[', ']', '<', '>' };

	/** Matches the brackets. */
    protected CPairMatcher fBracketMatcher = new CPairMatcher(BRACKETS);

	/** The bracket inserter. */
	private final BracketInserter fBracketInserter = new BracketInserter(this, false);

	/** Listener to annotation model changes that updates the error tick in the tab image */
	private CEditorErrorTickUpdater fCEditorErrorTickUpdater;

	/** Preference key for sub-word navigation, aka smart caret positioning */
	public static final String SUB_WORD_NAVIGATION = "subWordNavigation"; //$NON-NLS-1$
	/** Preference key for matching brackets */
	public static final String MATCHING_BRACKETS = "matchingBrackets"; //$NON-NLS-1$
	/** Preference key for matching brackets color */
	public static final String MATCHING_BRACKETS_COLOR = "matchingBracketsColor"; //$NON-NLS-1$
	/** Preference key for inactive code painter enablement */
	public static final String INACTIVE_CODE_ENABLE = "inactiveCodeEnable"; //$NON-NLS-1$
	/** Preference key for inactive code painter color */
	public static final String INACTIVE_CODE_COLOR = "inactiveCodeColor"; //$NON-NLS-1$
	/** Preference key for automatically closing strings */
	private static final String CLOSE_STRINGS = PreferenceConstants.EDITOR_CLOSE_STRINGS;
	/** Preference key for automatically closing brackets and parenthesis */
	private static final String CLOSE_BRACKETS = PreferenceConstants.EDITOR_CLOSE_BRACKETS;
	/** Preference key for automatically closing angular brackets */
	private static final String CLOSE_ANGULAR_BRACKETS = PreferenceConstants.EDITOR_CLOSE_ANGULAR_BRACKETS;
	/** Preference key for automatically closing curly braces */
	private static final String CLOSE_BRACES = PreferenceConstants.EDITOR_CLOSE_BRACES;

    /** Preference key for compiler task tags */
    private static final String TODO_TASK_TAGS = CCorePreferenceConstants.TODO_TASK_TAGS;

	/**
	 * This editor's projection support
	 */
	protected ProjectionSupport fProjectionSupport;
	/**
	 * This editor's projection model updater
	 */
	private ICFoldingStructureProvider fProjectionModelUpdater;

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

	/**
	 * AST reconciling listeners.
	 * @since 4.0
	 */
	private final ListenerList<ICReconcilingListener> fReconcilingListeners=
			new ListenerList<ICReconcilingListener>(ListenerList.IDENTITY);

	/**
	 * Semantic highlighting manager
	 * @since 4.0
	 */
	private SemanticHighlightingManager fSemanticManager;

	/**
	 * True if editor is opening a large file.
	 * @since 5.0
	 */
	private boolean fEnableScalablilityMode;

	/** Flag indicating whether the reconciler is currently running. */
	private volatile boolean fIsReconciling;

	private CTemplatesPage fTemplatesPage;

	private SelectionHistory fSelectionHistory;

	private final IndexUpdateRequestor fIndexUpdateRequestor = new IndexUpdateRequestor();

	private final ListenerList<IPostSaveListener> fPostSaveListeners;

	private static final Set<String> angularIntroducers = new HashSet<>();
	static {
		angularIntroducers.add("template"); //$NON-NLS-1$
		angularIntroducers.add("vector"); //$NON-NLS-1$
		angularIntroducers.add("deque"); //$NON-NLS-1$
		angularIntroducers.add("list"); //$NON-NLS-1$
		angularIntroducers.add("slist"); //$NON-NLS-1$
		angularIntroducers.add("map"); //$NON-NLS-1$
		angularIntroducers.add("set"); //$NON-NLS-1$
		angularIntroducers.add("multimap"); //$NON-NLS-1$
		angularIntroducers.add("multiset"); //$NON-NLS-1$
		angularIntroducers.add("hash_map"); //$NON-NLS-1$
		angularIntroducers.add("hash_set"); //$NON-NLS-1$
		angularIntroducers.add("hash_multimap"); //$NON-NLS-1$
		angularIntroducers.add("hash_multiset"); //$NON-NLS-1$
		angularIntroducers.add("unordered_map"); //$NON-NLS-1$
		angularIntroducers.add("unordered_set"); //$NON-NLS-1$
		angularIntroducers.add("unordered_multimap"); //$NON-NLS-1$
		angularIntroducers.add("unordered_multiset"); //$NON-NLS-1$
		angularIntroducers.add("pair"); //$NON-NLS-1$
		angularIntroducers.add("tuple"); //$NON-NLS-1$
		angularIntroducers.add("include"); //$NON-NLS-1$
	}

	/**
	 * Default constructor.
	 */
	public CEditor() {
		setDocumentProvider(CUIPlugin.getDefault().getDocumentProvider());

		setEditorContextMenuId("#CEditorContext"); //$NON-NLS-1$
		setRulerContextMenuId("#CEditorRulerContext"); //$NON-NLS-1$
		setOutlinerContextMenuId("#CEditorOutlinerContext"); //$NON-NLS-1$

		fCEditorErrorTickUpdater = new CEditorErrorTickUpdater(this);
		fPostSaveListeners = new ListenerList<IPostSaveListener>();
	}

	@Override
	protected void initializeEditor() {
	}

	@Override
	protected void doSetInput(IEditorInput input) throws CoreException {
		ISourceViewer sourceViewer= getSourceViewer();
		if (!(sourceViewer instanceof ISourceViewerExtension2)) {
			setPreferenceStore(createCombinedPreferenceStore(input));
			internalDoSetInput(input);
			updateScalabilityMode(input);
			return;
		}

		getDocumentProvider().connect(input);
		try {
			// Uninstall & unregister preference store listener
			getSourceViewerDecorationSupport(sourceViewer).uninstall();
			((ISourceViewerExtension2) sourceViewer).unconfigure();

			setPreferenceStore(createCombinedPreferenceStore(input));
			updateScalabilityMode(input);

			// Install & register preference store listener
			sourceViewer.configure(getSourceViewerConfiguration());
			getSourceViewerDecorationSupport(sourceViewer).install(getPreferenceStore());

			internalDoSetInput(input);
		} finally {
			getDocumentProvider().disconnect(input);
		}
	}

	private void internalDoSetInput(IEditorInput input) throws CoreException {
		ISourceViewer sourceViewer= getSourceViewer();
		CSourceViewer cSourceViewer= null;
		if (sourceViewer instanceof CSourceViewer) {
			cSourceViewer= (CSourceViewer) sourceViewer;
		}

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

		super.doSetInput(input);

		setOutlinePageInput(fOutlinePage, input);

		if (fProjectionModelUpdater != null) {
			fProjectionModelUpdater.initialize();
		}
		if (fCEditorErrorTickUpdater != null) {
			fCEditorErrorTickUpdater.updateEditorImage(getInputCElement());
		}
		ICElement element= getInputCElement();
		if (element instanceof ITranslationUnit) {
			ITranslationUnit tu = (ITranslationUnit) element;
			fIndexUpdateRequestor.updateIndexInclusion(tu);
			fBracketMatcher.configure(tu.getLanguage());
		} else {
			fIndexUpdateRequestor.updateIndexInclusion(null);
			fBracketMatcher.configure(null);
		}
	}

	private void updateScalabilityMode(IEditorInput input) {
		int lines = getDocumentProvider().getDocument(input).getNumberOfLines();
		boolean wasEnabled = fEnableScalablilityMode;
		fEnableScalablilityMode = lines > getPreferenceStore().getInt(PreferenceConstants.SCALABILITY_NUMBER_OF_LINES);
		if (fEnableScalablilityMode && !wasEnabled) {
			// Alert users that scalability mode should be turned on
			if (getPreferenceStore().getBoolean(PreferenceConstants.SCALABILITY_ALERT)) {
				MessageDialogWithToggle dialog = new MessageDialogWithToggle(
						getSite().getShell(),
						CEditorMessages.Scalability_info,  
						null,
						CEditorMessages.Scalability_message,  
						MessageDialog.INFORMATION,
						new String[] {IDialogConstants.YES_LABEL, IDialogConstants.NO_LABEL}, 0,
						CEditorMessages.Scalability_reappear,  
						false) {
					{
						setShellStyle(SWT.DIALOG_TRIM | SWT.MODELESS | SWT.ON_TOP | getDefaultOrientation());
					}
					@Override
					protected void buttonPressed(int buttonId) {
						PreferenceConstants.getPreferenceStore().setValue(PreferenceConstants.SCALABILITY_ALERT, !getToggleState());
						super.buttonPressed(buttonId);
						if (buttonId == IDialogConstants.YES_ID) {
							PreferenceDialog dialog = PreferencesUtil.createPreferenceDialogOn(getSite().getShell(),
									"org.eclipse.cdt.ui.preferences.CScalabilityPreferences", null, null); //$NON-NLS-1$
							dialog.open();
						}
					}
				};
				dialog.setBlockOnOpen(false);
				dialog.open();
			}
		}
	}

	@Override
	protected void setPreferenceStore(IPreferenceStore store) {
		super.setPreferenceStore(store);
		SourceViewerConfiguration sourceViewerConfiguration= getSourceViewerConfiguration();
		if (!(sourceViewerConfiguration instanceof CSourceViewerConfiguration)) {
			CTextTools textTools= CUIPlugin.getDefault().getTextTools();
			setSourceViewerConfiguration(new CSourceViewerScalableConfiguration(textTools.getColorManager(), store, this, ICPartitions.C_PARTITIONING));
		}

		if (getSourceViewer() instanceof CSourceViewer)
			((CSourceViewer) getSourceViewer()).setPreferenceStore(store);

		fMarkOccurrenceAnnotations= store.getBoolean(PreferenceConstants.EDITOR_MARK_OCCURRENCES);
		fMarkOverloadedOperatorOccurrences= store.getBoolean(PreferenceConstants.EDITOR_MARK_OVERLOADED_OPERATOR_OCCURRENCES);
		fStickyOccurrenceAnnotations= store.getBoolean(PreferenceConstants.EDITOR_STICKY_OCCURRENCES);
	}

	/**
	 * Update the title image.
     * @param image Title image.
	 */
	public void updatedTitleImage(Image image) {
		setTitleImage(image);
	}

	/**
	 * Returns the working copy wrapped by this editors input.
	 *
	 * @return the working copy wrapped by this editors input.
	 * @since 3.0
	 */
	public IWorkingCopy getInputCElement () {
		return CUIPlugin.getDefault().getWorkingCopyManager().getWorkingCopy(getEditorInput());
	}

	@Override
	public ITranslationUnit getTranslationUnit() {
		return getInputCElement();
	}

	/**
     * @see org.eclipse.ui.ISaveablePart#isSaveAsAllowed()
	 */
    @Override
	public boolean isSaveAsAllowed() {
		return true;
	}

	/**
	 * Returns the outline page of the C/C++ editor.
     * @return Outline page.
	 */
	public CContentOutlinePage getOutlinePage() {
		if (fOutlinePage == null) {
			fOutlinePage = new CContentOutlinePage(this);
			fOutlinePage.addSelectionChangedListener(this);
		}
		setOutlinePageInputIfNotSame(fOutlinePage, getEditorInput());
		return fOutlinePage;
	}

	@Override
	@SuppressWarnings("unchecked")
	public <T> T getAdapter(Class<T> adapterClass) {
		if (adapterClass.isAssignableFrom(IContentOutlinePage.class)) {
			return (T) getOutlinePage();
		} else if (adapterClass.isAssignableFrom(IShowInTargetList.class)) {
			return (T) new IShowInTargetList() {
				@Override
				@SuppressWarnings("deprecation")
				public String[] getShowInTargetIds() {
					return new String[] { IPageLayout.ID_PROJECT_EXPLORER, IPageLayout.ID_OUTLINE, IPageLayout.ID_RES_NAV };
				}
			};
		} else if (adapterClass.isAssignableFrom(IShowInSource.class)) {
			ICElement ce= getElementAt(getSourceViewer().getSelectedRange().x, false);
			if (ce instanceof ITranslationUnit) {
				ce = null;
			}
			final ISelection selection= ce != null ? new StructuredSelection(ce) : null;
			return (T) new IShowInSource() {
				@Override
				public ShowInContext getShowInContext() {
					return new ShowInContext(getEditorInput(), selection);
				}
			};
		} else if (adapterClass.isAssignableFrom(ProjectionAnnotationModel.class)) {
			if (fProjectionSupport != null) {
				T adapter = fProjectionSupport.getAdapter(getSourceViewer(), adapterClass);
				if (adapter != null)
					return adapter;
			}
		} else if (adapterClass.isAssignableFrom(IContextProvider.class)) {
			return (T) new CUIHelp.CUIHelpContextProvider(this);
		} else if (adapterClass.isAssignableFrom(IGotoMarker.class)) {
			return (T) new GotoMarkerAdapter();
		} else if (adapterClass.isAssignableFrom(ITemplatesPage.class)) {
			if (fTemplatesPage == null) {
				fTemplatesPage = new CTemplatesPage(this);
			}
			return (T) fTemplatesPage;
		} else if (adapterClass.isAssignableFrom(ITranslationUnitHolder.class))
			return (T) this;
		return super.getAdapter(adapterClass);
	}
	
	/**
	 * Handles a property change event describing a change
	 * of the editor's preference store and updates the preference
	 * related editor properties.
	 *
	 * @param event the property change event
	 */
	@Override
	protected void handlePreferenceStoreChanged(PropertyChangeEvent event) {
		String property = event.getProperty();

		if (AbstractDecoratedTextEditorPreferenceConstants.EDITOR_TAB_WIDTH.equals(property)) {
			/*
			 * Ignore tab setting since we rely on the formatter preferences.
			 * We do this outside the try-finally block to avoid that EDITOR_TAB_WIDTH
			 * is handled by the base-class (AbstractDecoratedTextEditor).
			 */
			return;
		}
		if (AbstractDecoratedTextEditorPreferenceConstants.EDITOR_SPACES_FOR_TABS.equals(property)) {
			// Ignore spaces-for-tab setting since we rely on the formatter preferences.
			return;
		}

		try {
			final AdaptedSourceViewer asv = (AdaptedSourceViewer) getSourceViewer();

			if (asv != null) {
				boolean newBooleanValue= false;
				Object newValue= event.getNewValue();
				if (newValue != null)
					newBooleanValue= Boolean.valueOf(newValue.toString()).booleanValue();

				if (CLOSE_BRACKETS.equals(property)) {
					fBracketInserter.setCloseBracketsEnabled(newBooleanValue);
					return;
				}

				if (CLOSE_ANGULAR_BRACKETS.equals(property)) {
					fBracketInserter.setCloseAngularBracketsEnabled(newBooleanValue);
					return;
				}

				if (CLOSE_BRACES.equals(property)) {
					fBracketInserter.setCloseBracesEnabled(newBooleanValue);
					return;
				}

				if (CLOSE_STRINGS.equals(property)) {
					fBracketInserter.setCloseStringsEnabled(newBooleanValue);
					return;
				}

				if (PreferenceConstants.EDITOR_TEXT_HOVER_MODIFIERS.equals(property))
					updateHoverBehavior();

				((CSourceViewerConfiguration) getSourceViewerConfiguration()).handlePropertyChangeEvent(event);

				if (PreferenceConstants.EDITOR_SMART_TAB.equals(property)) {
					if (newBooleanValue) {
						setActionActivationCode("IndentOnTab", '\t', -1, SWT.NONE); //$NON-NLS-1$
					} else {
						removeActionActivationCode("IndentOnTab"); //$NON-NLS-1$
					}
					return;
				}

				if (TODO_TASK_TAGS.equals(event.getProperty())) {
					ISourceViewer sourceViewer = getSourceViewer();
					if (sourceViewer != null && affectsTextPresentation(event))
						sourceViewer.invalidateTextPresentation();
					return;
				}
				
				if (affectsOverrideIndicatorAnnotations(event)) {
					if (isShowingOverrideIndicators()) {
						if (fOverrideIndicatorManager == null)
							installOverrideIndicator(true);
					} else {
						if (fOverrideIndicatorManager != null)
							uninstallOverrideIndicator();
					}
					return;
				}

				if (PreferenceConstants.EDITOR_FOLDING_PROVIDER.equals(property)) {
					if (fProjectionModelUpdater != null) {
						fProjectionModelUpdater.uninstall();
					}
					// either freshly enabled or provider changed
					fProjectionModelUpdater = CUIPlugin.getDefault().getFoldingStructureProviderRegistry().getCurrentFoldingProvider();
					if (fProjectionModelUpdater != null) {
						fProjectionModelUpdater.install(this, asv);
					}
					return;
				}

				if (DefaultCodeFormatterConstants.FORMATTER_TAB_SIZE.equals(property)
						|| DefaultCodeFormatterConstants.FORMATTER_INDENTATION_SIZE.equals(property)
						|| DefaultCodeFormatterConstants.FORMATTER_TAB_CHAR.equals(property)) {
					StyledText textWidget= asv.getTextWidget();
					int tabWidth= getSourceViewerConfiguration().getTabWidth(asv);
					if (textWidget.getTabs() != tabWidth)
						textWidget.setTabs(tabWidth);
					uninstallTabsToSpacesConverter();
					if (isTabsToSpacesConversionEnabled()) {
						installTabsToSpacesConverter();
					} else {
						updateIndentationMode();
					}
					return;
				}

				if (PreferenceConstants.EDITOR_MARK_OCCURRENCES.equals(property)) {
					if (newBooleanValue != fMarkOccurrenceAnnotations) {
						fMarkOccurrenceAnnotations= newBooleanValue;
						if (!fMarkOccurrenceAnnotations)
							uninstallOccurrencesFinder();
						else
							installOccurrencesFinder(true);
					}
					return;
				}
				if (PreferenceConstants.EDITOR_STICKY_OCCURRENCES.equals(property)) {
					fStickyOccurrenceAnnotations= newBooleanValue;
					return;
				}
				if (PreferenceConstants.EDITOR_MARK_OVERLOADED_OPERATOR_OCCURRENCES.equals(property)) {
					fMarkOverloadedOperatorOccurrences= newBooleanValue;
					return;
				}

				if (SemanticHighlightings.affectsEnablement(getPreferenceStore(), event)
						|| (isEnableScalablilityMode() && PreferenceConstants.SCALABILITY_SEMANTIC_HIGHLIGHT.equals(property))) {
					if (isSemanticHighlightingEnabled()) {
						installSemanticHighlighting();
						fSemanticManager.refresh();
					} else {
						uninstallSemanticHighlighting();
					}
					return;
				}
				
				// For Scalability
				if (isEnableScalablilityMode()) {
					if (PreferenceConstants.SCALABILITY_RECONCILER.equals(property) ||
							PreferenceConstants.SCALABILITY_SYNTAX_COLOR.equals(property)) {
						BusyIndicator.showWhile(getSite().getShell().getDisplay(), new Runnable() {
							@Override
							public void run() {
								setOutlinePageInput(fOutlinePage, getEditorInput());
								asv.unconfigure();
								asv.configure(getSourceViewerConfiguration());
							}});
						return;
					}
				}
				
				IContentAssistant c = asv.getContentAssistant();
				if (c instanceof ContentAssistant) {
					ContentAssistPreference.changeConfiguration((ContentAssistant) c, getPreferenceStore(), event);
				}
			}
		} finally {
			super.handlePreferenceStoreChanged(event);
		}
	}

	@Override
	protected void initializeViewerColors(ISourceViewer viewer) {
		// is handled by CSourceViewer
	}

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

		for (String t : types) {

			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 stateMask : stateMasks) {
						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);
			}
		}
	}

	/**
	 * Reacts to changed selection in the editor.
	 *
	 * @since 3.0
	 */
	protected void selectionChanged() {
		if (getSelectionProvider() == null)
			return;
		ISourceReference element= computeHighlightRangeSourceReference();
		updateStatusLine();
		synchronizeOutlinePage();
		setSelection(element, false);
	}

	/**
	 * 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 4.0
	 */
	protected 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.getSelection().x);
		} else {
			int offset= sourceViewer.getVisibleRegion().getOffset();
			caret= offset + styledText.getSelection().x;
		}

		ICElement element= getElementAt(caret, false);

		if (!(element instanceof ISourceReference))
			return null;

		return (ISourceReference) element;
	}

	/**
	 * Returns the most narrow element including the given offset.  If {@code reconcile}
	 * is {@code true} the editor's input element is reconciled in advance. If it is
	 * {@code false} 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} if working copy should be reconciled
	 * @return the most narrow element which includes the given offset
	 */
	protected ICElement getElementAt(int offset, boolean reconcile) {
		IWorkingCopy unit= getInputCElement();

		if (unit != null) {
			try {
				if (reconcile) {
					synchronized (unit) {
						unit.reconcile();
					}
					return unit.getElementAtOffset(offset);
				} else if (unit.isStructureKnown() && unit.isConsistent() && !fIsReconciling) {
					return unit.getElementAtOffset(offset);
				}
			} catch (CModelException e) {
				CUIPlugin.log(e.getStatus());
				// Nothing found, be tolerant and go on.
			}
		}

		return null;
	}

	/**
	 * Synchronizes the outline view selection with the given element position in the editor.
	 *
	 * @since 4.0
	 */
	protected void synchronizeOutlinePage() {
		if (fOutlinePage != null && fOutlinePage.isLinkingEnabled()) {
			fOutlinePage.removeSelectionChangedListener(this);
			fOutlinePage.synchronizeSelectionWithEditor();
			fOutlinePage.addSelectionChangedListener(this);
		}
	}

	/**
	 * React to changed selection in the outline view.
	 */
	@Override
	public void selectionChanged(SelectionChangedEvent event) {
		ISelection sel = event.getSelection();
		if (sel instanceof IStructuredSelection) {
			IStructuredSelection selection = (IStructuredSelection) sel;
			Object obj = selection.getFirstElement();
			if (obj instanceof ISourceReference) {
				try {
					ISourceRange range = ((ISourceReference) obj).getSourceRange();
					if (range != null) {
						setSelection(range, !isActivePart());
					}
				} catch (CModelException e) {
                    // Selection change not applied.
				}
			}
		}
	}

	/**
     * Sets selection for C element.
     *
     * @param element Element to select.
	 */
    public void setSelection(ICElement element) {
		if (element instanceof ISourceReference && !(element instanceof ITranslationUnit)) {
			ISourceReference reference = (ISourceReference) element;
			// set hightlight range
			setSelection(reference, true);
		}
	}

    /**
     * Sets selection for source reference.
     *
     * @param element Source reference to set.
     * @param moveCursor Should cursor be moved.
     */
    public void setSelection(ISourceReference element, boolean moveCursor) {
		if (element != null) {
			StyledText  textWidget = null;

			ISourceViewer sourceViewer = getSourceViewer();
			if (sourceViewer != null)
				textWidget = sourceViewer.getTextWidget();

			if (textWidget == null)
				return;

			try {
				setSelection(element.getSourceRange(), moveCursor);
			} catch (CModelException e) {
                // Selection not applied.
			}
		}
	}

	/**
	 * Sets the current editor selection to the source range. Optionally
	 * sets the current editor position.
	 *
	 * @param element the source range to be shown in the editor, can be null.
	 * @param moveCursor if true the editor is scrolled to show the range.
	 */
	public void setSelection(ISourceRange element, boolean moveCursor) {
		if (getSelectionProvider() == null)
			return;

		ISelection selection= getSelectionProvider().getSelection();
		if (selection instanceof ITextSelection) {
			ITextSelection textSelection= (ITextSelection) 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 (element != null) {
			StyledText textWidget= null;
			
			ISourceViewer sourceViewer= getSourceViewer();
			if (sourceViewer == null)
				return;
			
			textWidget= sourceViewer.getTextWidget();
			if (textWidget == null)
				return;

			try {
				IRegion alternateRegion = null;
				int start = element.getStartPos();
				int length = element.getLength();
	
				// Sanity check sometimes the parser may throw wrong numbers.
				if (start < 0 || length < 0) {
					start = 0;
					length = 0;
				}
	
				// 0 length and start and non-zero start line says we know
				// the line for some reason, but not the offset.
				if (length == 0 && start == 0 && element.getStartLine() > 0) {
					// We have the information in term of lines, we can work it out.
					// Binary elements return the first executable statement so we have to subtract -1
					start = getDocumentProvider().getDocument(getEditorInput()).getLineOffset(element.getStartLine() - 1);
					if (element.getEndLine() > 0) {
						length = getDocumentProvider().getDocument(getEditorInput()).getLineOffset(element.getEndLine()) - start;
					} else {
						length = start;
					}
					// create an alternate region for the keyword highlight.
					alternateRegion = getDocumentProvider().getDocument(getEditorInput()).getLineInformation(element.getStartLine() - 1);
					if (start == length || length < 0) {
						if (alternateRegion != null) {
							start = alternateRegion.getOffset();
							length = alternateRegion.getLength();
						}
					}
				}
				setHighlightRange(start, length, moveCursor);
	
				if (moveCursor) {
					start = element.getIdStartPos();
					length = element.getIdLength();
					if (start == 0 && length == 0 && alternateRegion != null) {
						start = alternateRegion.getOffset();
						length = alternateRegion.getLength();
					}
					if (start > -1 && length > 0) {
						try  {
							textWidget.setRedraw(false);
							sourceViewer.revealRange(start, length);
							sourceViewer.setSelectedRange(start, length);
						} finally {
							textWidget.setRedraw(true);
						}
						markInNavigationHistory();
					}
					updateStatusField(ITextEditorActionConstants.STATUS_CATEGORY_INPUT_POSITION);
				}
			} catch (IllegalArgumentException | BadLocationException e) {
	            // No information to the user
			}
		} else if (moveCursor) {
			resetHighlightRange();
			markInNavigationHistory();
		}
	}

	/**
     * Checks is the editor active part.
     * @return {@code true} if editor is the active part of the workbench.
	 */
    private boolean isActivePart() {
		IWorkbenchWindow window = getSite().getWorkbenchWindow();
		IPartService service = window.getPartService();
		return (this == service.getActivePart());
	}

	@Override
	protected void installTabsToSpacesConverter() {
		ISourceViewer sourceViewer= getSourceViewer();
		SourceViewerConfiguration config= getSourceViewerConfiguration();
		if (config != null && sourceViewer instanceof ITextViewerExtension7) {
			int tabWidth= config.getTabWidth(sourceViewer);
			TabsToSpacesConverter tabToSpacesConverter= new TabsToSpacesConverter();
			tabToSpacesConverter.setNumberOfSpacesPerTab(tabWidth);
			IDocumentProvider provider= getDocumentProvider();
			if (provider instanceof CDocumentProvider) {
				CDocumentProvider cProvider= (CDocumentProvider) provider;
				tabToSpacesConverter.setLineTracker(cProvider.createLineTracker(getEditorInput()));
			} else {
				tabToSpacesConverter.setLineTracker(new DefaultLineTracker());
			}
			((ITextViewerExtension7) sourceViewer).setTabsToSpacesConverter(tabToSpacesConverter);
			updateIndentationMode();
		}
	}

	private void updateIndentationMode() {
		ISourceViewer sourceViewer= getSourceViewer();
		if (sourceViewer instanceof CSourceViewer) {
			CSourceViewer cSourceVieer= (CSourceViewer) sourceViewer;
			ICElement element= getInputCElement();
			ICProject project= element == null ? null : element.getCProject();
			final int indentWidth= CodeFormatterUtil.getIndentWidth(project);
			final boolean useSpaces= isTabsToSpacesConversionEnabled();
			cSourceVieer.configureIndentation(indentWidth, useSpaces);
		}
		super.updateIndentPrefixes();
	}

	@Override
	protected boolean isTabsToSpacesConversionEnabled() {
		ICElement element= getInputCElement();
		ICProject project= element == null ? null : element.getCProject();
		String option;
		if (project == null)
			option= CCorePlugin.getOption(DefaultCodeFormatterConstants.FORMATTER_TAB_CHAR);
		else
			option= project.getOption(DefaultCodeFormatterConstants.FORMATTER_TAB_CHAR, true);
		return CCorePlugin.SPACE.equals(option);
	}

	protected void uninstallProjectionModelUpdater() {
		if (fProjectionModelUpdater != null) {
			fProjectionModelUpdater.uninstall();
			fProjectionModelUpdater = null;
		}
	}
	
    /**
     * @see org.eclipse.ui.IWorkbenchPart#dispose()
     */
    @Override
	public void dispose() {
    	fIndexUpdateRequestor.updateIndexInclusion(null);

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

		uninstallProjectionModelUpdater();

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

		// Cancel possible running computation
		fMarkOccurrenceAnnotations= false;
		uninstallOccurrencesFinder();
		uninstallOverrideIndicator();

    	uninstallSemanticHighlighting();

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

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

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

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

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

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

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

		if (fGenerateActionGroup != null) {
			fGenerateActionGroup.dispose();
			fGenerateActionGroup= null;
		}
		
		if (fSurroundWithActionGroup != null) {
			fSurroundWithActionGroup.dispose();
			fSurroundWithActionGroup= null;
		}
		
		if (fEditorSelectionChangedListener != null)  {
			fEditorSelectionChangedListener.uninstall(getSelectionProvider());
			fEditorSelectionChangedListener = null;
		}
		
		if (fSelectionHistory != null) {
			fSelectionHistory.dispose();
			fSelectionHistory = null;
		}

		super.dispose();
	}

	@Override
	protected boolean canHandleMove(IEditorInput originalElement, IEditorInput movedElement) {
		String oldLanguage = ""; //$NON-NLS-1$
		IFile originalFile = getEditorInputFile(originalElement);
		
		if (originalFile != null) {
			// If the project of the original input cannot be accessed, the project is being
			// renamed - accept the move. See http://bugs.eclipse.org/434852
			if (originalFile.getProject() != null && !originalFile.getProject().isAccessible()) {
				return true;
			}
			IContentType type = CCorePlugin.getContentType(originalFile.getProject(), originalFile.getName());
			if (type != null) {
				oldLanguage = type.getId();
			}
			if (oldLanguage == null) {
				return false;
			}
		}

		String newLanguage = ""; //$NON-NLS-1$
		IFile movedFile = getEditorInputFile(movedElement);
		if (movedFile != null) {
			IContentType type = CCorePlugin.getContentType(movedFile.getProject(), movedFile.getName());
			if (type != null) {
				newLanguage = type.getId();
			}
			if (newLanguage == null) {
				return false;
			}
		}
		return oldLanguage.equals(newLanguage);
	}

	private IFile getEditorInputFile(IEditorInput editorInput) {
		if (editorInput instanceof IFileEditorInput) {
			return ((IFileEditorInput) editorInput).getFile();
		}
		return null;
	}
	
	@Override
	protected void createActions() {
		super.createActions();

		fFoldingGroup = new FoldingActionGroup(this, getSourceViewer());

		// Default text editing menu items
		IAction action= new GotoMatchingBracketAction(this);
		action.setActionDefinitionId(ICEditorActionDefinitionIds.GOTO_MATCHING_BRACKET);
		setAction(GotoMatchingBracketAction.GOTO_MATCHING_BRACKET, action);
		
		final ResourceBundle bundle = ConstructedCEditorMessages.getResourceBundle();
		action = new GotoNextBookmarkAction(bundle, "GotoNextBookmark.", this); //$NON-NLS-1$
		action.setActionDefinitionId(ICEditorActionDefinitionIds.GOTO_NEXT_BOOKMARK);
		setAction(GotoNextBookmarkAction.NEXT_BOOKMARK, action);

		action = new FindWordAction(bundle, "FindWord.", this, getSourceViewer()); //$NON-NLS-1$
		action.setActionDefinitionId(ICEditorActionDefinitionIds.FIND_WORD);
		setAction(FindWordAction.FIND_WORD, action);
		markAsStateDependentAction(FindWordAction.FIND_WORD, true);
		markAsSelectionDependentAction(FindWordAction.FIND_WORD, true);

		action = new ToggleCommentAction(bundle, "ToggleComment.", this); //$NON-NLS-1$
		action.setActionDefinitionId(ICEditorActionDefinitionIds.TOGGLE_COMMENT);
		setAction("ToggleComment", action); //$NON-NLS-1$
		markAsStateDependentAction("ToggleComment", true); //$NON-NLS-1$
		configureToggleCommentAction();

		action = new AddBlockCommentAction(bundle, "AddBlockComment.", this);  //$NON-NLS-1$
		action.setActionDefinitionId(ICEditorActionDefinitionIds.ADD_BLOCK_COMMENT);
		setAction("AddBlockComment", action); //$NON-NLS-1$
		markAsStateDependentAction("AddBlockComment", true); //$NON-NLS-1$
		markAsSelectionDependentAction("AddBlockComment", true); //$NON-NLS-1$
		//WorkbenchHelp.setHelp(action, ICHelpContextIds.ADD_BLOCK_COMMENT_ACTION);

		action = new RemoveBlockCommentAction(bundle, "RemoveBlockComment.", this);  //$NON-NLS-1$
		action.setActionDefinitionId(ICEditorActionDefinitionIds.REMOVE_BLOCK_COMMENT);
		setAction("RemoveBlockComment", action); //$NON-NLS-1$
		markAsStateDependentAction("RemoveBlockComment", true); //$NON-NLS-1$
		markAsSelectionDependentAction("RemoveBlockComment", true); //$NON-NLS-1$
		//WorkbenchHelp.setHelp(action, ICHelpContextIds.REMOVE_BLOCK_COMMENT_ACTION);

		action = new IndentAction(bundle, "Indent.", this, false); //$NON-NLS-1$
		action.setActionDefinitionId(ICEditorActionDefinitionIds.INDENT);
		setAction("Indent", action); //$NON-NLS-1$
		markAsStateDependentAction("Indent", true); //$NON-NLS-1$
		markAsSelectionDependentAction("Indent", true); //$NON-NLS-1$
//		PlatformUI.getWorkbench().getHelpSystem().setHelp(action, ICHelpContextIds.INDENT_ACTION);

		action = new AlignConstAction(bundle, "AlignConst.", this); //$NON-NLS-1$
		action.setActionDefinitionId(ICEditorActionDefinitionIds.ALIGN_CONST);
		setAction("AlignConst", action); //$NON-NLS-1$
		markAsStateDependentAction("AlignConst", true); //$NON-NLS-1$
		markAsSelectionDependentAction("AlignConst", true); //$NON-NLS-1$

		action = new IndentAction(bundle, "Indent.", this, true); //$NON-NLS-1$
		setAction("IndentOnTab", action); //$NON-NLS-1$
		markAsStateDependentAction("IndentOnTab", true); //$NON-NLS-1$
		markAsSelectionDependentAction("IndentOnTab", true); //$NON-NLS-1$

		if (getPreferenceStore().getBoolean(PreferenceConstants.EDITOR_SMART_TAB)) {
			setActionActivationCode("IndentOnTab", '\t', -1, SWT.NONE); //$NON-NLS-1$
		}

		action = new TextOperationAction(bundle, "Format.", this, ISourceViewer.FORMAT); //$NON-NLS-1$
		action.setActionDefinitionId(ICEditorActionDefinitionIds.FORMAT);
		setAction("Format", action); //$NON-NLS-1$
		markAsStateDependentAction("Format", true); //$NON-NLS-1$

		action = new SortLinesAction(this);
		action.setActionDefinitionId(ICEditorActionDefinitionIds.SORT_LINES);
		setAction("SortLines", action); //$NON-NLS-1$
		markAsStateDependentAction("SortLines", true); //$NON-NLS-1$
		markAsSelectionDependentAction("SortLines", true); //$NON-NLS-1$

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

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

        action = new TextOperationAction(bundle, "OpenOutline.", this, CSourceViewer.SHOW_OUTLINE, true); //$NON-NLS-1$
        action.setActionDefinitionId(ICEditorActionDefinitionIds.OPEN_OUTLINE);
        setAction("OpenOutline", action); //$NON-NLS-1$*/

        action = new TextOperationAction(bundle, "OpenHierarchy.", this, CSourceViewer.SHOW_HIERARCHY, true); //$NON-NLS-1$
        action.setActionDefinitionId(ICEditorActionDefinitionIds.OPEN_QUICK_TYPE_HIERARCHY);
        setAction("OpenHierarchy", action); //$NON-NLS-1$*/

        action = new GoToNextPreviousMemberAction(bundle, "GotoNextMember.", this, true); //$NON-NLS-1$
        action.setActionDefinitionId(ICEditorActionDefinitionIds.GOTO_NEXT_MEMBER);
        setAction(GoToNextPreviousMemberAction.PREVIOUS_MEMBER, action);

        action = new GoToNextPreviousMemberAction(bundle, "GotoPreviousMember.", this, false); //$NON-NLS-1$
        action.setActionDefinitionId(ICEditorActionDefinitionIds.GOTO_PREVIOUS_MEMBER);
        setAction(GoToNextPreviousMemberAction.NEXT_MEMBER, action);

        action= new ToggleSourceAndHeaderAction(bundle, "ToggleSourceHeader.", this); //$NON-NLS-1$
        action.setActionDefinitionId(ICEditorActionDefinitionIds.TOGGLE_SOURCE_HEADER);
        setAction("ToggleSourceHeader", action); //$NON-NLS-1$

        action = new TextOperationAction(bundle, "OpenMacroExplorer.", this, CSourceViewer.SHOW_MACRO_EXPLORER, true); //$NON-NLS-1$
        action.setActionDefinitionId(ICEditorActionDefinitionIds.OPEN_QUICK_MACRO_EXPLORER);
        setAction("OpenMacroExplorer", action); //$NON-NLS-1$*/
        
        fSelectionHistory = new SelectionHistory(this);
        
        action = new StructureSelectEnclosingAction(bundle, this, fSelectionHistory);
        action.setActionDefinitionId(ICEditorActionDefinitionIds.SELECT_ENCLOSING);
        setAction(StructureSelectionAction.ENCLOSING, action);
        
        action = new StructureSelectNextAction(bundle, this, fSelectionHistory);
        action.setActionDefinitionId(ICEditorActionDefinitionIds.SELECT_NEXT);
        setAction(StructureSelectionAction.NEXT, action);
        
        action = new StructureSelectPreviousAction(bundle, this, fSelectionHistory);
        action.setActionDefinitionId(ICEditorActionDefinitionIds.SELECT_PREVIOUS);
        setAction(StructureSelectionAction.PREVIOUS, action);
        
        action = new StructureSelectHistoryAction(bundle, this, fSelectionHistory);
        action.setActionDefinitionId(ICEditorActionDefinitionIds.SELECT_LAST);
        setAction(StructureSelectionAction.HISTORY, action);
        
		// add annotation actions for roll-over expand hover
		action= new CSelectMarkerRulerAction(bundle, "Editor.RulerAnnotationSelection.", this); //$NON-NLS-1$
		setAction("AnnotationAction", action); //$NON-NLS-1$
        
        
        // Assorted action groupings
		fSelectionSearchGroup = createSelectionSearchGroup();
		fTextSearchGroup= new TextSearchGroup(this);
		fRefactoringActionGroup= new CRefactoringActionGroup(this, ITextEditorActionConstants.GROUP_EDIT);
		fOpenInViewGroup= createOpenViewActionGroup();
		fGenerateActionGroup= new GenerateActionGroup(this, ITextEditorActionConstants.GROUP_EDIT);
		fSurroundWithActionGroup = new SurroundWithActionGroup(this, ITextEditorActionConstants.GROUP_EDIT);
		
		action = getAction(ITextEditorActionConstants.SHIFT_RIGHT);
		if (action != null) {
			action.setId(ITextEditorActionConstants.SHIFT_RIGHT);
			CPluginImages.setImageDescriptors(action, CPluginImages.T_LCL, CPluginImages.IMG_MENU_SHIFT_RIGHT);
		}
		action = getAction(ITextEditorActionConstants.SHIFT_LEFT);
		if (action != null) {
			action.setId(ITextEditorActionConstants.SHIFT_LEFT);
			CPluginImages.setImageDescriptors(action, CPluginImages.T_LCL, CPluginImages.IMG_MENU_SHIFT_LEFT);
		}
	}

	protected ActionGroup createSelectionSearchGroup() {
		return new SelectionSearchGroup(this);
	}
	
	protected ActionGroup createOpenViewActionGroup() {
		return new OpenViewActionGroup(this);
	}

	@Override
	public void editorContextMenuAboutToShow(IMenuManager menu) {
		// marker for contributions to the top
		menu.add(new GroupMarker(ICommonMenuConstants.GROUP_TOP));
		// separator for debug related actions (similar to ruler context menu)
		menu.add(new Separator(IContextMenuConstants.GROUP_DEBUG));
		menu.add(new GroupMarker(IContextMenuConstants.GROUP_DEBUG+".end")); //$NON-NLS-1$

		super.editorContextMenuAboutToShow(menu);

		// remove shift actions added by base class
		menu.remove(ITextEditorActionConstants.SHIFT_LEFT);
		menu.remove(ITextEditorActionConstants.SHIFT_RIGHT);

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

		final boolean hasCElement= getInputCElement() != null;
		if (hasCElement) {
			addAction(menu, IContextMenuConstants.GROUP_OPEN, "OpenDeclarations"); //$NON-NLS-1$
	        addAction(menu, IContextMenuConstants.GROUP_OPEN, "OpenDefinition"); //$NON-NLS-1$
			addAction(menu, IContextMenuConstants.GROUP_OPEN, "OpenTypeHierarchy"); //$NON-NLS-1$
			addAction(menu, IContextMenuConstants.GROUP_OPEN, "OpenCallHierarchy"); //$NON-NLS-1$

			addAction(menu, IContextMenuConstants.GROUP_OPEN, "OpenOutline"); //$NON-NLS-1$
			addAction(menu, IContextMenuConstants.GROUP_OPEN, "OpenHierarchy"); //$NON-NLS-1$
			addAction(menu, IContextMenuConstants.GROUP_OPEN, "OpenMacroExplorer"); //$NON-NLS-1$
			addAction(menu, IContextMenuConstants.GROUP_OPEN, "ToggleSourceHeader"); //$NON-NLS-1$
		}

		ActionContext context= new ActionContext(getSelectionProvider().getSelection());
		fGenerateActionGroup.setContext(context);
		fGenerateActionGroup.fillContextMenu(menu);
		fGenerateActionGroup.setContext(null);

		fSurroundWithActionGroup.setContext(context);
		fSurroundWithActionGroup.fillContextMenu(menu);
		fSurroundWithActionGroup.setContext(null);
		
		if (hasCElement) {
			fSelectionSearchGroup.fillContextMenu(menu);
		}
		fTextSearchGroup.fillContextMenu(menu);

		if (hasCElement) {
			fRefactoringActionGroup.fillContextMenu(menu);
			fOpenInViewGroup.fillContextMenu(menu);
		}
	}

	@Override
	protected void rulerContextMenuAboutToShow(IMenuManager menu) {
		super.rulerContextMenuAboutToShow(menu);
		IMenuManager foldingMenu= new MenuManager(CEditorMessages.CEditor_menu_folding, "projection");  //$NON-NLS-1$
		menu.appendToGroup(ITextEditorActionConstants.GROUP_RULERS, foldingMenu);

		IAction action= getAction("FoldingToggle"); //$NON-NLS-1$
		foldingMenu.add(action);
		action= getAction("FoldingExpandAll"); //$NON-NLS-1$
		foldingMenu.add(action);
		action= getAction("FoldingCollapseAll"); //$NON-NLS-1$
		foldingMenu.add(action);
		action= getAction("FoldingRestore"); //$NON-NLS-1$
		foldingMenu.add(action);
	}

	/**
     * Sets an input for the outline page.
	 * @param page Page to set the input.
	 * @param input Input to set.
	 */
	public static void setOutlinePageInput(CContentOutlinePage page, IEditorInput input) {
		if (page != null) {
			IWorkingCopyManager manager = CUIPlugin.getDefault().getWorkingCopyManager();
			page.setInput(manager.getWorkingCopy(input));
		}
	}

	private static void setOutlinePageInputIfNotSame(CContentOutlinePage page, IEditorInput input) {
		if (page != null) {
			IWorkingCopyManager manager = CUIPlugin.getDefault().getWorkingCopyManager();
			IWorkingCopy workingCopy = manager.getWorkingCopy(input);
			if (workingCopy != page.getRoot()) {
				page.setInput(workingCopy);
			}
		}
	}

	/**
     * Determines if folding is enabled.
	 * @return {@code true} if folding is enabled, {@code false} otherwise.
	 */
	protected boolean isFoldingEnabled() {
		return CUIPlugin.getDefault().getPreferenceStore().getBoolean(PreferenceConstants.EDITOR_FOLDING_ENABLED);
	}

	@Override
	public int getOrientation() {
		// C/C++ editors are always left to right by default
		return SWT.LEFT_TO_RIGHT;
	}

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

		// bug 291008 - register custom help listener
		final IWorkbenchHelpSystem helpSystem = PlatformUI.getWorkbench().getHelpSystem();
		parent.addHelpListener(new HelpListener() {
			@Override
			public void helpRequested(HelpEvent e) {
				IContextProvider provider = CEditor.this.getAdapter(IContextProvider.class);
				if (provider != null) {
					IContext context = provider.getContext(CEditor.this);
					if (context != null) {
						helpSystem.displayHelp(context);
						return;
					}
				}
				helpSystem.displayHelp(ICHelpContextIds.CEDITOR_VIEW);
			}});
		
		fEditorSelectionChangedListener = new EditorSelectionChangedListener();
		fEditorSelectionChangedListener.install(getSelectionProvider());

		if (isSemanticHighlightingEnabled())
			installSemanticHighlighting();

		IPreferenceStore preferenceStore = getPreferenceStore();
		boolean closeBrackets = preferenceStore.getBoolean(CLOSE_BRACKETS);
		boolean closeAngularBrackets = preferenceStore.getBoolean(CLOSE_ANGULAR_BRACKETS);
		boolean closeBraces = preferenceStore.getBoolean(CLOSE_BRACES);
		boolean closeStrings = preferenceStore.getBoolean(CLOSE_STRINGS);

		fBracketInserter.setCloseBracketsEnabled(closeBrackets);
		fBracketInserter.setCloseAngularBracketsEnabled(closeAngularBrackets);
		fBracketInserter.setCloseAngularBracketsEnabled(closeBraces);
		fBracketInserter.setCloseStringsEnabled(closeStrings);

		ISourceViewer sourceViewer = getSourceViewer();
		if (sourceViewer instanceof ITextViewerExtension) {
			fBracketInserter.setSourceViewer(sourceViewer);
			((ITextViewerExtension) sourceViewer).prependVerifyKeyListener(fBracketInserter);
		}

		if (isMarkingOccurrences())
			installOccurrencesFinder(false);

		if(isShowingOverrideIndicators())
			installOverrideIndicator(false);
	}

	@Override
	protected SourceViewerDecorationSupport getSourceViewerDecorationSupport(ISourceViewer viewer) {
		if (fSourceViewerDecorationSupport == null) {
			fSourceViewerDecorationSupport= new CSourceViewerDecorationSupport(this, viewer, getOverviewRuler(), getAnnotationAccess(), getSharedColors());
			configureSourceViewerDecorationSupport(fSourceViewerDecorationSupport);
		}
		return fSourceViewerDecorationSupport;
	}

	@Override
	protected void configureSourceViewerDecorationSupport(SourceViewerDecorationSupport support) {
		super.configureSourceViewerDecorationSupport(support);
		// Enhance the stock source viewer decorator with a bracket matcher
		support.setCharacterPairMatcher(fBracketMatcher);
		support.setMatchingCharacterPainterPreferenceKeys(MATCHING_BRACKETS, MATCHING_BRACKETS_COLOR);
		((CSourceViewerDecorationSupport) support).setInactiveCodePainterPreferenceKeys(INACTIVE_CODE_ENABLE, INACTIVE_CODE_COLOR);

		// The base class will have already called setMarginPainterPreferenceKeys. We override it
		// here with more specific values for the C/C++ editor. Note that this needs to go after
		// the call to super since the last invocation wins.
		support.setMarginPainterPreferenceKeys(
				AbstractDecoratedTextEditorPreferenceConstants.EDITOR_PRINT_MARGIN,
				AbstractDecoratedTextEditorPreferenceConstants.EDITOR_PRINT_MARGIN_COLOR,
				DefaultCodeFormatterConstants.FORMATTER_LINE_SPLIT);
	}

	/**
	 * Returns the lock object for the given annotation model.
	 *
	 * @param annotationModel the annotation model
	 * @return the annotation model's lock object
	 * @since 5.0
	 */
	private Object getLockObject(IAnnotationModel annotationModel) {
		if (annotationModel instanceof ISynchronizable) {
			Object lock= ((ISynchronizable) annotationModel).getLockObject();
			if (lock != null)
				return lock;
		}
		return annotationModel;
	}

	/**
	 * Jumps to the matching bracket.
	 */
	public void gotoMatchingBracket() {
		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(CEditorMessages.GotoMatchingBracket_error_invalidSelection);	
			sourceViewer.getTextWidget().getDisplay().beep();
			return;
		}

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

		IRegion region = fBracketMatcher.match(document, sourceCaretOffset);
		if (region == null) {
			setStatusLineErrorMessage(CEditorMessages.GotoMatchingBracket_error_noMatchingBracket);	
			sourceViewer.getTextWidget().getDisplay().beep();
			return;
		}

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

		if (length < 1)
			return;

		int anchor = fBracketMatcher.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(CEditorMessages.GotoMatchingBracket_error_bracketOutsideSelectedElement);	
			sourceViewer.getTextWidget().getDisplay().beep();
			return;
		}

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

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

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

	/**
	 * Returns the annotation overlapping with the given range or {@code null}.
	 *
	 * @param offset the region offset
	 * @param length the region length
	 * @param marker associated marker or {@code null} of not available
	 * @return the found annotation or {@code null}
	 */
	private Annotation getAnnotation(int offset, int length, IMarker marker) {
		IAnnotationModel model= getDocumentProvider().getAnnotationModel(getEditorInput());
		if (model == null)
			return null;
		
		Iterator<Annotation> parent;
		if (model instanceof IAnnotationModelExtension2) {
			parent= ((IAnnotationModelExtension2) model).getAnnotationIterator(offset, length, true, true);
		} else {
			parent= model.getAnnotationIterator();
		}

		Iterator<Annotation> e= new CAnnotationIterator(parent, false);
		Annotation annotation = null;
		while (e.hasNext()) {
			Annotation a = e.next();
			if (!isNavigationTarget(a))
				continue;
			
			Position p = model.getPosition(a);
			if (p != null && p.overlapsWith(offset, length)) {
				if (annotation == null) {
					annotation = a;
					if (marker == null)
						break;
				}
				if (a instanceof MarkerAnnotation) {
					if (((MarkerAnnotation) a).getMarker().equals(marker)) {
						annotation = a;
						break;
					}
				}
			}
		}
		
		return annotation;
	}

	/**
	 * Returns the dektop's StatusLineManager
	 */
	@Override
	protected IStatusLineManager getStatusLineManager() {
		IEditorActionBarContributor contributor = getEditorSite().getActionBarContributor();
		if (contributor instanceof EditorActionBarContributor) {
			return ((EditorActionBarContributor) contributor).getActionBars().getStatusLineManager();
		}
		return null;
	}

	/**
	 * Configures the toggle comment action
	 *
	 * @since 4.0.0
	 */
	private void configureToggleCommentAction() {
		IAction action = getAction("ToggleComment"); //$NON-NLS-1$
		if (action instanceof ToggleCommentAction) {
			ISourceViewer sourceViewer = getSourceViewer();
			SourceViewerConfiguration configuration = getSourceViewerConfiguration();
			((ToggleCommentAction) action).configure(sourceViewer, configuration);
		}
	}

	@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);
	}

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

	@Override
	protected ISourceViewer createSourceViewer(Composite parent, IVerticalRuler ruler, int styles) {
		IPreferenceStore store= getPreferenceStore();
		ISourceViewer sourceViewer =
				new AdaptedSourceViewer(parent, ruler, getOverviewRuler(), isOverviewRulerVisible(), styles, store);

		CSourceViewer cSourceViewer= null;
		if (sourceViewer instanceof CSourceViewer) {
			cSourceViewer= (CSourceViewer) sourceViewer;
		}

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

		ProjectionViewer projectionViewer = (ProjectionViewer) sourceViewer;

		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$
		fProjectionSupport.addSummarizableAnnotationType("org.eclipse.search.results"); //$NON-NLS-1$
		fProjectionSupport.setHoverControlCreator(new IInformationControlCreator() {
			@Override
			public IInformationControl createInformationControl(Shell shell) {
				return new SourceViewerInformationControl(shell, false, getOrientation(), null);
			}
		});
		fProjectionSupport.install();

		fProjectionModelUpdater = CUIPlugin.getDefault().getFoldingStructureProviderRegistry().getCurrentFoldingProvider();
		if (fProjectionModelUpdater != null)
			fProjectionModelUpdater.install(this, projectionViewer);

		if (isFoldingEnabled())
			projectionViewer.doOperation(ProjectionViewer.TOGGLE);

		getSourceViewerDecorationSupport(sourceViewer);

		return sourceViewer;
	}

	/** Outliner context menu Id */
	protected String fOutlinerContextMenuId;

	/**
	 * Holds the current occurrence annotations.
	 * @since 5.0
	 */
	private Annotation[] fOccurrenceAnnotations= null;
	/**
	 * Tells whether all occurrences of the element at the
	 * current caret location are automatically marked in
	 * this editor.
	 * @since 5.0
	 */
	private boolean fMarkOccurrenceAnnotations;
	/**
	 * Tells whether the occurrence annotations are sticky
	 * i.e. whether they stay even if there's no valid Java
	 * element at the current caret position.
	 * Only valid if {@link #fMarkOccurrenceAnnotations} is {@code true}.
	 * @since 5.0
	 */
	private boolean fStickyOccurrenceAnnotations;
	/**
	 * Tells whether to mark overloaded operator occurrences in this editor.
	 * Only valid if {@link #fMarkOccurrenceAnnotations} is {@code true}.
	 * @since 5.3
	 */
	private boolean fMarkOverloadedOperatorOccurrences;
	/**
	 * The selection used when forcing occurrence marking
	 * through code.
	 * @since 5.0
	 */
	private ISelection fForcedMarkOccurrencesSelection;
	/**
	 * The document modification stamp at the time when the last
	 * occurrence marking took place.
	 * @since 5.0
	 */
	private long fMarkOccurrenceModificationStamp= IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP;
	/**
	 * The region of the word under the caret used to when
	 * computing the current occurrence markings.
	 * @since 5.0
	 */
	private IRegion fMarkOccurrenceTargetRegion;

	private OccurrencesAnnotationUpdaterJob fOccurrencesAnnotationUpdaterJob;
	private OccurrencesFinderJobCanceler fOccurrencesFinderJobCanceler;
	private ISelectionListenerWithAST fPostSelectionListenerWithAST;

	private OverrideIndicatorManager fOverrideIndicatorManager;

	/**
	 * Sets the outliner's context menu ID.
	 */
	protected void setOutlinerContextMenuId(String menuId) {
		fOutlinerContextMenuId = menuId;
	}

	@Override
	protected void initializeKeyBindingScopes() {
		setKeyBindingScopes(new String [] { "org.eclipse.cdt.ui.cEditorScope" }); //$NON-NLS-1$
	}

	@Override
	protected boolean affectsTextPresentation(PropertyChangeEvent event) {
		SourceViewerConfiguration configuration = getSourceViewerConfiguration();
		if (configuration instanceof CSourceViewerConfiguration) {
			return ((CSourceViewerConfiguration) configuration).affectsTextPresentation(event);
		}
		return false;
	}

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

	@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);
				projectionViewer.enableProjection();
			}

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

    /**
     * Sets the given message as error message to this editor's status line.
     *
     * @param message message to be set
     */
    @Override
	public void setStatusLineErrorMessage(String message) {
		long now= System.currentTimeMillis();
		if (message != null || now - fErrorMessageTime > ERROR_MESSAGE_TIMEOUT) {
			super.setStatusLineErrorMessage(message);
			fErrorMessageTime= message != null ? now : 0;
		}
    }

	/**
	 * Sets the given message as message to this editor's status line.
	 *
	 * @param message message to be set
	 * @since 3.0
	 */
	@Override
	protected void setStatusLineMessage(String message) {
		if (System.currentTimeMillis() - fErrorMessageTime > ERROR_MESSAGE_TIMEOUT)
			super.setStatusLineMessage(message);
	}

	/**
	 * 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);
	}

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

	private 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 static char getEscapeCharacter(char character) {
		switch (character) {
			case '"':
			case '\'':
				return '\\';
			default:
				return 0;
		}
	}

	private static char getPeerCharacter(char character) {
		switch (character) {
			case '(':
				return ')';

			case ')':
				return '(';

			case '<':
				return '>';

			case '>':
				return '<';

			case '[':
				return ']';

			case ']':
				return '[';

			case '{':
				return '}';

			case '}':
				return '{';

			case '"':
				return character;

			case '\'':
				return character;

			default:
				throw new IllegalArgumentException();
		}
	}

	@Override
	protected String[] collectContextMenuPreferencePages() {
		// Add C/C++ Editor relevant pages
		String[] parentPrefPageIds = super.collectContextMenuPreferencePages();
		String[] prefPageIds = new String[parentPrefPageIds.length + 13];
		int nIds = 0;
		prefPageIds[nIds++] = "org.eclipse.cdt.ui.preferences.CEditorPreferencePage"; //$NON-NLS-1$
		prefPageIds[nIds++] = "org.eclipse.cdt.ui.preferences.CodeAssistPreferencePage"; //$NON-NLS-1$
		prefPageIds[nIds++] = "org.eclipse.cdt.ui.preferences.CodeAssistPreferenceAdvanced"; //$NON-NLS-1$
		prefPageIds[nIds++] = "org.eclipse.cdt.ui.preferences.HoverPreferencePage"; //$NON-NLS-1$
		prefPageIds[nIds++] = "org.eclipse.cdt.ui.preferences.FoldingPreferencePage"; //$NON-NLS-1$
		prefPageIds[nIds++] = "org.eclipse.cdt.ui.preferences.MarkOccurrencesPreferencePage"; //$NON-NLS-1$
		prefPageIds[nIds++] = "org.eclipse.cdt.ui.preferences.CodeColoringPreferencePage"; //$NON-NLS-1$
		prefPageIds[nIds++] = "org.eclipse.cdt.ui.preferences.TemplatePreferencePage"; //$NON-NLS-1$
		prefPageIds[nIds++] = "org.eclipse.cdt.ui.preferences.SmartTypingPreferencePage"; //$NON-NLS-1$
		prefPageIds[nIds++] = "org.eclipse.cdt.ui.preferences.CodeFormatterPreferencePage"; //$NON-NLS-1$
		prefPageIds[nIds++] = "org.eclipse.cdt.ui.preferences.CScalabilityPreferences"; //$NON-NLS-1$
		prefPageIds[nIds++] = "org.eclipse.cdt.ui.preferences.SaveActionsPreferencePage"; //$NON-NLS-1$
		prefPageIds[nIds++] = "org.eclipse.cdt.codan.ui.preferences.CodanPreferencePage"; //$NON-NLS-1$
		System.arraycopy(parentPrefPageIds, 0, prefPageIds, nIds, parentPrefPageIds.length);
		return prefPageIds;
	}

	@Override
	public void aboutToBeReconciled() {
		fIsReconciling= true;

		// Notify AST provider
		CUIPlugin.getDefault().getASTProvider().aboutToBeReconciled(getInputCElement());

		// Notify listeners
		Object[] listeners = fReconcilingListeners.getListeners();
		for (int i = 0, length= listeners.length; i < length; ++i) {
			((ICReconcilingListener) listeners[i]).aboutToBeReconciled();
		}
	}

	@Override
	public void reconciled(IASTTranslationUnit ast, boolean force, IProgressMonitor progressMonitor) {
		fIsReconciling= false;

		CUIPlugin cuiPlugin= CUIPlugin.getDefault();
		if (cuiPlugin == null)
			return;

		// Always notify AST provider
		cuiPlugin.getASTProvider().reconciled(ast, getInputCElement(), progressMonitor);

		// Notify listeners
		Object[] listeners = fReconcilingListeners.getListeners();
		for (int i = 0, length= listeners.length; i < length; ++i) {
			((ICReconcilingListener) listeners[i]).reconciled(ast, force, progressMonitor);
		}
	}

	/**
	 * Adds the given listener.
	 * Has no effect if an identical listener was not already registered.
	 *
	 * @param listener	The reconcile listener to be added
	 * @since 4.0
	 */
	final public void addReconcileListener(ICReconcilingListener listener) {
		fReconcilingListeners.add(listener);
	}

	/**
	 * Removes the given listener.
	 * Has no effect if an identical listener was not already registered.
	 *
	 * @param listener	the reconcile listener to be removed
	 * @since 4.0
	 */
	final public void removeReconcileListener(ICReconcilingListener listener) {
		fReconcilingListeners.remove(listener);
	}

	/**
	 * @return {@code true} if Semantic Highlighting is enabled.
	 *
	 * @since 4.0
	 */
	protected boolean isSemanticHighlightingEnabled() {
		return SemanticHighlightings.isEnabled(getPreferenceStore()) && !(isEnableScalablilityMode() && getPreferenceStore().getBoolean(PreferenceConstants.SCALABILITY_SEMANTIC_HIGHLIGHT));
	}

	/**
	 * Install Semantic Highlighting.
	 *
	 * @since 4.0
	 */
	private void installSemanticHighlighting() {
		if (fSemanticManager == null) {
			fSemanticManager= new SemanticHighlightingManager();
			fSemanticManager.install(this, (CSourceViewer) getSourceViewer(), CUIPlugin.getDefault().getTextTools().getColorManager(), getPreferenceStore());
		}
	}

	/**
	 * Uninstalls semantic highlighting.
	 *
	 * @since 4.0
	 */
	private void uninstallSemanticHighlighting() {
		if (fSemanticManager != null) {
			fSemanticManager.uninstall();
			fSemanticManager= null;
		}
	}

	/**
	 * Called whenever the editor is activated and allows for registering
	 * action handlers.
	 */
	public void fillActionBars(IActionBars actionBars) {
		fOpenInViewGroup.fillActionBars(actionBars);
		fRefactoringActionGroup.fillActionBars(actionBars);
		fGenerateActionGroup.fillActionBars(actionBars);
		fFoldingGroup.updateActionBars();
		fSurroundWithActionGroup.fillActionBars(actionBars);
	}

	@Override
	protected void updateStateDependentActions() {
		super.updateStateDependentActions();
		fGenerateActionGroup.editorStateChanged();
	}

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

	/**
	 * Updates occurrence annotations.
	 *
	 * @since 5.0
	 */
	class OccurrencesAnnotationUpdaterJob extends Job {
		private final IDocument fDocument;
		private final ISelection fSelection;
		private final ISelectionValidator fPostSelectionValidator;
		private boolean fCanceled;
		private final OccurrenceLocation[] fLocations;

		public OccurrencesAnnotationUpdaterJob(IDocument document, OccurrenceLocation[] locations, ISelection selection, ISelectionValidator validator) {
			super(CEditorMessages.CEditor_markOccurrences_job_name); 
			fDocument= document;
			fSelection= selection;
			fLocations= locations;
			fPostSelectionValidator= validator;
		}

		// cannot use cancel() because it is declared final
		void doCancel() {
			fCanceled= true;
			cancel();
		}

		private boolean isCanceled(IProgressMonitor progressMonitor) {
			return fCanceled || progressMonitor.isCanceled()
				||  fPostSelectionValidator != null && !(fPostSelectionValidator.isValid(fSelection) || fForcedMarkOccurrencesSelection == fSelection)
				|| LinkedModeModel.hasInstalledModel(fDocument);
		}

		@Override
		public IStatus run(IProgressMonitor progressMonitor) {
			if (isCanceled(progressMonitor))
				return Status.CANCEL_STATUS;

			ITextViewer textViewer= getViewer();
			if (textViewer == null)
				return Status.CANCEL_STATUS;

			IDocument document= textViewer.getDocument();
			if (document == null)
				return Status.CANCEL_STATUS;

			IDocumentProvider documentProvider= getDocumentProvider();
			if (documentProvider == null)
				return Status.CANCEL_STATUS;

			IAnnotationModel annotationModel= documentProvider.getAnnotationModel(getEditorInput());
			if (annotationModel == null)
				return Status.CANCEL_STATUS;

			// Add occurrence annotations
			int length= fLocations.length;
			Map<Annotation, Position> annotationMap= new HashMap<>(length);
			for (int i= 0; i < length; i++) {
				if (isCanceled(progressMonitor))
					return Status.CANCEL_STATUS;

				OccurrenceLocation location= fLocations[i];
				Position position= new Position(location.getOffset(), location.getLength());

				String description= location.getDescription();
				String annotationType= (location.getFlags() == IOccurrencesFinder.F_WRITE_OCCURRENCE) ? "org.eclipse.cdt.ui.occurrences.write" : "org.eclipse.cdt.ui.occurrences"; //$NON-NLS-1$ //$NON-NLS-2$

				annotationMap.put(new Annotation(annotationType, false, description), position);
			}

			if (isCanceled(progressMonitor))
				return Status.CANCEL_STATUS;

			synchronized (getLockObject(annotationModel)) {
				if (annotationModel instanceof IAnnotationModelExtension) {
					((IAnnotationModelExtension) annotationModel).replaceAnnotations(fOccurrenceAnnotations, annotationMap);
				} else {
					removeOccurrenceAnnotations();
					Iterator<Map.Entry<Annotation, Position>> iter= annotationMap.entrySet().iterator();
					while (iter.hasNext()) {
						Map.Entry<Annotation, Position> mapEntry= iter.next();
						annotationModel.addAnnotation(mapEntry.getKey(), mapEntry.getValue());
					}
				}
				fOccurrenceAnnotations= annotationMap.keySet().toArray(new Annotation[annotationMap.keySet().size()]);
			}

			return Status.OK_STATUS;
		}
	}

	/**
	 * Cancels the occurrences finder job upon document changes.
	 *
	 * @since 5.0
	 */
	class OccurrencesFinderJobCanceler implements IDocumentListener, ITextInputListener {

		public void install() {
			ISourceViewer sourceViewer= getSourceViewer();
			if (sourceViewer == null)
				return;

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

			sourceViewer.addTextInputListener(this);

			IDocument document= sourceViewer.getDocument();
			if (document != null)
				document.addDocumentListener(this);
		}

		public void uninstall() {
			ISourceViewer sourceViewer= getSourceViewer();
			if (sourceViewer != null)
				sourceViewer.removeTextInputListener(this);

			IDocumentProvider documentProvider= getDocumentProvider();
			if (documentProvider != null) {
				IDocument document= documentProvider.getDocument(getEditorInput());
				if (document != null)
					document.removeDocumentListener(this);
			}
		}

		@Override
		public void documentAboutToBeChanged(DocumentEvent event) {
			if (fOccurrencesAnnotationUpdaterJob != null)
				fOccurrencesAnnotationUpdaterJob.doCancel();
		}

		@Override
		public void documentChanged(DocumentEvent event) {
		}

		@Override
		public void inputDocumentAboutToBeChanged(IDocument oldInput, IDocument newInput) {
			if (oldInput == null)
				return;

			oldInput.removeDocumentListener(this);
		}

		@Override
		public void inputDocumentChanged(IDocument oldInput, IDocument newInput) {
			if (newInput == null)
				return;
			newInput.addDocumentListener(this);
		}
	}

	/**
	 * Updates the occurrences annotations based
	 * on the current selection.
	 *
	 * @param selection the text selection
	 * @param astRoot the compilation unit AST
	 * @since 5.0
	 */
	protected void updateOccurrenceAnnotations(ITextSelection selection, IASTTranslationUnit astRoot) {
		if (fOccurrencesAnnotationUpdaterJob != null)
			fOccurrencesAnnotationUpdaterJob.cancel();

		if (!fMarkOccurrenceAnnotations)
			return;

		if (astRoot == null || selection == null)
			return;

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

		ISelectionValidator validator= null;
		if (fForcedMarkOccurrencesSelection != selection && getSelectionProvider() instanceof ISelectionValidator) {
			validator= (ISelectionValidator) getSelectionProvider();
			if (!validator.isValid(selection)) {
				return;
			}
		}

		boolean hasChanged= false;
		if (document instanceof IDocumentExtension4) {
			int offset= selection.getOffset();
			long currentModificationStamp= ((IDocumentExtension4) document).getModificationStamp();
			IRegion markOccurrenceTargetRegion= fMarkOccurrenceTargetRegion;
			hasChanged= currentModificationStamp != fMarkOccurrenceModificationStamp;
			if (markOccurrenceTargetRegion != null && !hasChanged) {
				if (markOccurrenceTargetRegion.getOffset() <= offset && offset <= markOccurrenceTargetRegion.getOffset() + markOccurrenceTargetRegion.getLength())
					return;
			}
			fMarkOccurrenceTargetRegion= CWordFinder.findWord(document, offset);
			fMarkOccurrenceModificationStamp= currentModificationStamp;
		}

		OccurrenceLocation[] locations= null;

		IASTNodeSelector selector= astRoot.getNodeSelector(null);
		IASTName name= selector.findEnclosingName(selection.getOffset(), selection.getLength());
		if (name == null)
			name = selector.findEnclosingImplicitName(selection.getOffset(), selection.getLength());

		if (validator != null && !validator.isValid(selection)) {
			return;
		}

		if (name != null) {
			IBinding binding= name.resolveBinding();
			if (binding != null) {
				OccurrencesFinder occurrencesFinder= new OccurrencesFinder();
				if (occurrencesFinder.initialize(astRoot, name) == null) {
				    if (!fMarkOverloadedOperatorOccurrences) {
				        occurrencesFinder.setOptions(OccurrencesFinder.OPTION_EXCLUDE_IMPLICIT_REFERENCES);
				    }
					locations= occurrencesFinder.getOccurrences();
				}
			}
		}

		if (locations == null || locations.length == 0) {
			if (!fStickyOccurrenceAnnotations)
				removeOccurrenceAnnotations();
			else if (hasChanged) // check consistency of current annotations
				removeOccurrenceAnnotations();
			return;
		}

		fOccurrencesAnnotationUpdaterJob= new OccurrencesAnnotationUpdaterJob(document, locations, selection, validator);
		// we are already in a background job
		//fOccurrencesFinderJob.setPriority(Job.DECORATE);
		//fOccurrencesFinderJob.setSystem(true);
		//fOccurrencesFinderJob.schedule();
		fOccurrencesAnnotationUpdaterJob.run(new NullProgressMonitor());
	}

	protected void installOccurrencesFinder(boolean forceUpdate) {
		fMarkOccurrenceAnnotations= true;

		fPostSelectionListenerWithAST= new ISelectionListenerWithAST() {
			@Override
			public void selectionChanged(IEditorPart part, ITextSelection selection, IASTTranslationUnit astRoot) {
				updateOccurrenceAnnotations(selection, astRoot);
			}
		};
		SelectionListenerWithASTManager.getDefault().addListener(this, fPostSelectionListenerWithAST);
		if (forceUpdate && getSelectionProvider() != null) {
			ICElement inputCElement = getInputCElement();
			if (inputCElement instanceof ITranslationUnit) {
				fForcedMarkOccurrencesSelection= getSelectionProvider().getSelection();
				ASTProvider.getASTProvider().runOnAST(inputCElement, ASTProvider.WAIT_NO, getProgressMonitor(), new ASTRunnable() {
					@Override
					public IStatus runOnAST(ILanguage lang, IASTTranslationUnit ast) throws CoreException {
						updateOccurrenceAnnotations((ITextSelection) fForcedMarkOccurrencesSelection, ast);
						return Status.OK_STATUS;
					}
				});
			}
		}

		if (fOccurrencesFinderJobCanceler == null) {
			fOccurrencesFinderJobCanceler= new OccurrencesFinderJobCanceler();
			fOccurrencesFinderJobCanceler.install();
		}
	}

	protected void uninstallOccurrencesFinder() {
		fMarkOccurrenceAnnotations= false;

		if (fOccurrencesAnnotationUpdaterJob != null) {
			fOccurrencesAnnotationUpdaterJob.cancel();
			fOccurrencesAnnotationUpdaterJob= null;
		}

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

		if (fPostSelectionListenerWithAST != null) {
			SelectionListenerWithASTManager.getDefault().removeListener(this, fPostSelectionListenerWithAST);
			fPostSelectionListenerWithAST= null;
		}

		removeOccurrenceAnnotations();
	}

	protected boolean isMarkingOccurrences() {
		IPreferenceStore store= getPreferenceStore();
		return store != null && store.getBoolean(PreferenceConstants.EDITOR_MARK_OCCURRENCES);
	}

	void removeOccurrenceAnnotations() {
		fMarkOccurrenceModificationStamp= IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP;
		fMarkOccurrenceTargetRegion= null;

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

		IAnnotationModel annotationModel= documentProvider.getAnnotationModel(getEditorInput());
		if (annotationModel == null || fOccurrenceAnnotations == null)
			return;

		synchronized (getLockObject(annotationModel)) {
			if (annotationModel instanceof IAnnotationModelExtension) {
				((IAnnotationModelExtension) annotationModel).replaceAnnotations(fOccurrenceAnnotations, null);
			} else {
				for (Annotation occurrenceAnnotation : fOccurrenceAnnotations)
					annotationModel.removeAnnotation(occurrenceAnnotation);
			}
			fOccurrenceAnnotations= null;
		}
	}

	/**
	 * 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) {
		List<IPreferenceStore> stores= new ArrayList<>(3);

		ICProject project= EditorUtility.getCProject(input);
		if (project != null) {
			stores.add(new EclipsePreferencesAdapter(new ProjectScope(project.getProject()), CCorePlugin.PLUGIN_ID));
		}

		stores.add(CUIPlugin.getDefault().getPreferenceStore());
		stores.add(CUIPlugin.getDefault().getCorePreferenceStore());
		stores.add(EditorsUI.getPreferenceStore());

		return new ChainedPreferenceStore(stores.toArray(new IPreferenceStore[stores.size()]));
	}

	/**
	 * @return {@code true} if parser based Content Assist proposals are disabled.
	 *
	 * @since 5.0
	 */
	public boolean isParserBasedContentAssistDisabled() {
		return getPreferenceStore().getBoolean(PreferenceConstants.SCALABILITY_PARSER_BASED_CONTENT_ASSIST);
	}
	
	/**
	 * @return {@code true} if Content Assist auto activation is disabled.
	 *
	 * @since 5.0
	 */
	public boolean isContentAssistAutoActivartionDisabled() {
		return getPreferenceStore().getBoolean(PreferenceConstants.SCALABILITY_CONTENT_ASSIST_AUTO_ACTIVATION);
	}
	
	/**
	 * @return {@code true} if the number of lines in the file exceed
	 * the line number for scalability mode in the preference.
	 *
	 * @since 5.0
	 */
	public boolean isEnableScalablilityMode() {
		return fEnableScalablilityMode;
	}

	@Override
	protected boolean isPrefQuickDiffAlwaysOn() {
		// Enable only if not in scalability mode.
		// Workaround for http://bugs.eclipse.org/75555
		return super.isPrefQuickDiffAlwaysOn() && !isEnableScalablilityMode();
	}

	public boolean shouldProcessLocalParsingCompletions() {
		return true;
	}
	
	protected void uninstallOverrideIndicator() {
		if (fOverrideIndicatorManager != null) {
			fOverrideIndicatorManager.removeAnnotations();
			removeReconcileListener(fOverrideIndicatorManager);
			fOverrideIndicatorManager= null;
		}
	}
	
	/**
	 * Determines whether the preference change encoded by the given event
	 * changes the override indication.
	 *
	 * @param event the event to be investigated
	 * @return {@code true} if event causes a change
	 * @since 5.3
	 */
	protected boolean affectsOverrideIndicatorAnnotations(PropertyChangeEvent event) {
		String key= event.getProperty();
		AnnotationPreference preference= getAnnotationPreferenceLookup().getAnnotationPreference(OverrideIndicatorManager.ANNOTATION_TYPE);
		if (key == null || preference == null)
			return false;

		return key.equals(preference.getHighlightPreferenceKey())
			|| key.equals(preference.getVerticalRulerPreferenceKey())
			|| key.equals(preference.getOverviewRulerPreferenceKey())
			|| key.equals(preference.getTextPreferenceKey());
	}
	
	/**
	 * Returns the boolean preference for the given key.
	 *
	 * @param store the preference store
	 * @param key the preference key
	 * @return {@code true} if the key exists in the store and its value is {@code true}
	 * @since 5.3
	 */
	private boolean getBoolean(IPreferenceStore store, String key) {
		return key != null && store.getBoolean(key);
	}
	
	/**
	 * Tells whether override indicators are shown.
	 *
	 * @return {@code true} if the override indicators are shown
	 * @since 5.3
	 */
	protected boolean isShowingOverrideIndicators() {
		AnnotationPreference preference= getAnnotationPreferenceLookup().getAnnotationPreference(OverrideIndicatorManager.ANNOTATION_TYPE);
		IPreferenceStore store= getPreferenceStore();
		return getBoolean(store, preference.getHighlightPreferenceKey())
			|| getBoolean(store, preference.getVerticalRulerPreferenceKey())
			|| getBoolean(store, preference.getOverviewRulerPreferenceKey())
			|| getBoolean(store, preference.getTextPreferenceKey());
	}
	
	protected void installOverrideIndicator(boolean provideAST) {
		uninstallOverrideIndicator();
		IAnnotationModel model= getDocumentProvider().getAnnotationModel(getEditorInput());

		if (model == null)
			return;

		fOverrideIndicatorManager= new OverrideIndicatorManager(model, null);
		
		addReconcileListener(fOverrideIndicatorManager);

		ICElement inputCElement = getInputCElement();
		if (provideAST && inputCElement instanceof ITranslationUnit) {
			ASTProvider.getASTProvider().runOnAST(inputCElement, ASTProvider.WAIT_ACTIVE_ONLY, getProgressMonitor(), new ASTRunnable() {
				@Override
				public IStatus runOnAST(ILanguage lang, IASTTranslationUnit ast) throws CoreException {
					if (ast != null)
						fOverrideIndicatorManager.reconciled(ast, true, getProgressMonitor());
					return Status.OK_STATUS;
				}});
		}
	}
	
	@Override
	protected void editorSaved() {
		super.editorSaved();
		IWorkingCopy inputCElement = getInputCElement();
		if (inputCElement != null) {
			ITranslationUnit translationUnit = inputCElement.getOriginalElement();
			if (translationUnit != null) {
				for (Object listener : fPostSaveListeners.getListeners()) {
					((IPostSaveListener) listener).saved(translationUnit, getProgressMonitor());
				}
			}
		}
	}
	
	/**
	 * @since 5.4
	 */
	public void addPostSaveListener(IPostSaveListener listener) {
		fPostSaveListeners.add(listener);
	}
	
	/**
	 * @since 5.4
	 */
	public void removePostSaveListener(IPostSaveListener listener) {
		fPostSaveListeners.remove(listener);
	}

	@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 CExpandHover(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;
	}
}
