/*******************************************************************************
 * Copyright (c) 2000, 2017 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.ui.texteditor;

import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetEncoder;
import java.nio.charset.IllegalCharsetNameException;
import java.nio.charset.UnsupportedCharsetException;
import java.util.Iterator;
import java.util.List;

import com.ibm.icu.text.BreakIterator;
import com.ibm.icu.text.MessageFormat;

import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.custom.StyledTextPrintOptions;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.Shell;

import org.eclipse.core.commands.operations.IOperationApprover;
import org.eclipse.core.commands.operations.IUndoContext;
import org.eclipse.core.filesystem.EFS;
import org.eclipse.core.filesystem.IFileStore;
import org.eclipse.core.filesystem.URIUtil;

import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceStatus;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;

import org.eclipse.core.filebuffers.FileBuffers;
import org.eclipse.core.filebuffers.IFileBufferStatusCodes;

import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.GroupMarker;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.IMessageProvider;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.dialogs.MessageDialogWithToggle;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.window.Window;

import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.text.ITextViewerExtension6;
import org.eclipse.jface.text.ITextViewerExtension8;
import org.eclipse.jface.text.JFaceTextUtil;
import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.hyperlink.IHyperlinkDetector;
import org.eclipse.jface.text.revisions.IRevisionRulerColumn;
import org.eclipse.jface.text.revisions.IRevisionRulerColumnExtension;
import org.eclipse.jface.text.revisions.IRevisionRulerColumnExtension.RenderingMode;
import org.eclipse.jface.text.revisions.RevisionInformation;
import org.eclipse.jface.text.source.Annotation;
import org.eclipse.jface.text.source.AnnotationRulerColumn;
import org.eclipse.jface.text.source.ChangeRulerColumn;
import org.eclipse.jface.text.source.CompositeRuler;
import org.eclipse.jface.text.source.IAnnotationAccess;
import org.eclipse.jface.text.source.IAnnotationAccessExtension2;
import org.eclipse.jface.text.source.IAnnotationHover;
import org.eclipse.jface.text.source.IAnnotationModel;
import org.eclipse.jface.text.source.IChangeRulerColumn;
import org.eclipse.jface.text.source.IOverviewRuler;
import org.eclipse.jface.text.source.IOverviewRulerExtension;
import org.eclipse.jface.text.source.ISharedTextColors;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.jface.text.source.ISourceViewerExtension;
import org.eclipse.jface.text.source.ISourceViewerExtension3;
import org.eclipse.jface.text.source.IVerticalRuler;
import org.eclipse.jface.text.source.IVerticalRulerColumn;
import org.eclipse.jface.text.source.LineChangeHover;
import org.eclipse.jface.text.source.LineNumberChangeRulerColumn;
import org.eclipse.jface.text.source.LineNumberRulerColumn;
import org.eclipse.jface.text.source.OverviewRuler;
import org.eclipse.jface.text.source.SourceViewer;

import org.eclipse.ui.IEditorDescriptor;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.IURIEditorInput;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.IWorkbenchCommandConstants;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.actions.ContributionItemFactory;
import org.eclipse.ui.actions.OpenWithMenu;
import org.eclipse.ui.actions.WorkspaceModifyOperation;
import org.eclipse.ui.dialogs.PreferencesUtil;
import org.eclipse.ui.dialogs.SaveAsDialog;
import org.eclipse.ui.ide.FileStoreEditorInput;
import org.eclipse.ui.ide.IDEActionFactory;
import org.eclipse.ui.ide.IGotoMarker;
import org.eclipse.ui.internal.editors.quickdiff.CompositeRevertAction;
import org.eclipse.ui.internal.editors.quickdiff.RestoreAction;
import org.eclipse.ui.internal.editors.quickdiff.RevertBlockAction;
import org.eclipse.ui.internal.editors.quickdiff.RevertLineAction;
import org.eclipse.ui.internal.editors.quickdiff.RevertSelectionAction;
import org.eclipse.ui.internal.editors.text.EditorsPlugin;
import org.eclipse.ui.internal.editors.text.NLSUtility;
import org.eclipse.ui.internal.editors.text.RefreshEditorAction;
import org.eclipse.ui.internal.texteditor.AnnotationColumn;
import org.eclipse.ui.internal.texteditor.BooleanPreferenceToggleAction;
import org.eclipse.ui.internal.texteditor.FocusedInformationPresenter;
import org.eclipse.ui.internal.texteditor.LineNumberColumn;
import org.eclipse.ui.internal.texteditor.TextChangeHover;
import org.eclipse.ui.keys.IBindingService;
import org.eclipse.ui.operations.NonLocalUndoUserApprover;
import org.eclipse.ui.part.FileEditorInput;
import org.eclipse.ui.part.IShowInSource;
import org.eclipse.ui.part.ShowInContext;
import org.eclipse.ui.views.markers.MarkerViewUtil;

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

import org.eclipse.ui.editors.text.DefaultEncodingSupport;
import org.eclipse.ui.editors.text.EditorsUI;
import org.eclipse.ui.editors.text.ForwardingDocumentProvider;
import org.eclipse.ui.editors.text.IEncodingSupport;
import org.eclipse.ui.editors.text.IStorageDocumentProvider;
import org.eclipse.ui.editors.text.ITextEditorHelpContextIds;


/**
 * An intermediate editor comprising functionality not present in the leaner <code>AbstractTextEditor</code>,
 * but used in many heavy weight (and especially source editing) editors, such as line numbers,
 * change ruler, overview ruler, print margins, current line highlighting, etc.
 *
 * @since 3.0
 */
public abstract class AbstractDecoratedTextEditor extends StatusTextEditor {

	/**
	 * Preference key for showing the line number ruler.
	 */
	private final static String LINE_NUMBER_RULER= AbstractDecoratedTextEditorPreferenceConstants.EDITOR_LINE_NUMBER_RULER;
	/**
	 * Preference key for showing the overview ruler.
	 */
	private final static String OVERVIEW_RULER= AbstractDecoratedTextEditorPreferenceConstants.EDITOR_OVERVIEW_RULER;
	/**
	 * Preference key for highlighting current line.
	 */
	private final static String CURRENT_LINE= AbstractDecoratedTextEditorPreferenceConstants.EDITOR_CURRENT_LINE;
	/**
	 * Preference key for highlight color of current line.
	 */
	private final static String CURRENT_LINE_COLOR= AbstractDecoratedTextEditorPreferenceConstants.EDITOR_CURRENT_LINE_COLOR;
	/**
	 * Preference key for showing print margin ruler.
	 */
	private final static String PRINT_MARGIN= AbstractDecoratedTextEditorPreferenceConstants.EDITOR_PRINT_MARGIN;
	/**
	 * Preference key for print margin ruler color.
	 */
	private final static String PRINT_MARGIN_COLOR= AbstractDecoratedTextEditorPreferenceConstants.EDITOR_PRINT_MARGIN_COLOR;
	/**
	 * Preference key for print margin ruler column.
	 */
	private final static String PRINT_MARGIN_COLUMN= AbstractDecoratedTextEditorPreferenceConstants.EDITOR_PRINT_MARGIN_COLUMN;
	/**
	 * Preference key to get whether the overwrite mode is disabled.
	 * @since 3.1
	 */
	private final static String DISABLE_OVERWRITE_MODE= AbstractDecoratedTextEditorPreferenceConstants.EDITOR_DISABLE_OVERWRITE_MODE;

	/**
	 * Menu id for the overview ruler context menu.
	 *
	 * @since 3.4
	 */
	public final static String DEFAULT_OVERVIEW_RULER_CONTEXT_MENU_ID= "#OverviewRulerContext"; //$NON-NLS-1$

	/**
	 * Preference key that controls whether to use saturated colors in the overview ruler.
	 * 
	 * @since 3.8
	 */
	private static final String USE_SATURATED_COLORS_IN_OVERVIEW_RULER= AbstractDecoratedTextEditorPreferenceConstants.USE_SATURATED_COLORS_IN_OVERVIEW_RULER;


	/**
	 * Adapter class for <code>IGotoMarker</code>.
	 */
	private class GotoMarkerAdapter implements IGotoMarker {
		@Override
		public void gotoMarker(IMarker marker) {
			AbstractDecoratedTextEditor.this.gotoMarker(marker);
		}
	}


	/**
	 * The annotation preferences.
	 */
	private MarkerAnnotationPreferences fAnnotationPreferences;

	/**
	 * The overview ruler of this editor.
	 *
	 * <p>This field should not be referenced by subclasses. It is <code>protected</code> for API
	 * compatibility reasons and will be made <code>private</code> soon. Use
	 * {@link #getOverviewRuler()} instead.</p>
	 */
	protected IOverviewRuler fOverviewRuler;
	/**
	 * The overview ruler's context menu id.
	 *
	 * @since 3.4
	 */
	private String fOverviewRulerContextMenuId;

	/**
	 * Helper for accessing annotation from the perspective of this editor.
	 *
	 * <p>This field should not be referenced by subclasses. It is <code>protected</code> for API
	 * compatibility reasons and will be made <code>private</code> soon. Use
	 * {@link #getAnnotationAccess()} instead.</p>
	 */
	protected IAnnotationAccess fAnnotationAccess;
	/**
	 * Helper for managing the decoration support of this editor's viewer.
	 *
	 * <p>This field should not be referenced by subclasses. It is <code>protected</code> for API
	 * compatibility reasons and will be made <code>private</code> soon. Use
	 * {@link #getSourceViewerDecorationSupport(ISourceViewer)} instead.</p>
	 */
	protected SourceViewerDecorationSupport fSourceViewerDecorationSupport;
	/**
	 * The line number column.
	 *
	 * <p>This field should not be referenced by subclasses. It is <code>protected</code> for API
	 * compatibility reasons and will be made <code>private</code> soon. Use
	 * {@link AbstractTextEditor#getVerticalRuler()} to access the vertical bar instead.</p>
	 */
	protected LineNumberRulerColumn fLineNumberRulerColumn;
	/**
	 * The delegating line number ruler contribution.
	 * @since 3.3
	 */
	private LineNumberColumn fLineColumn;
	/**
	 * The editor's implicit document provider.
	 */
	private IDocumentProvider fImplicitDocumentProvider;
	/**
	 * The editor's goto marker adapter.
	 */
	private Object fGotoMarkerAdapter= new GotoMarkerAdapter();
	/**
	 * Indicates whether this editor is updating views that show markers.
	 * @see #updateMarkerViews(Annotation)
	 * @since 3.2
	 */
	protected boolean fIsUpdatingMarkerViews= false;

	/**
	 * Indicates whether it wants to update the marker views after a gotoMarker call.
	 * @see #updateMarkerViews(Annotation)
	 * @see #gotoMarker(IMarker)
	 * @since 3.6
	 */
	private boolean fIsComingFromGotoMarker= false;
	
	/**
	 * Tells whether editing the current derived editor input is allowed.
	 * @since 3.3
	 */
	private boolean fIsEditingDerivedFileAllowed= true;
	/**
	 * Tells whether the derived state has been validated.
	 * @since 3.3
	 */
	private boolean fIsDerivedStateValidated= false;
	/**
	 * The focused information presenter, or <code>null</code> if not created yet.
	 * @since 3.5
	 */
	private FocusedInformationPresenter fInformationPresenter;

	/*
	 * Workaround for IllegalAccessError thrown because we are accessing
	 * a protected method in a different bundle from an inner class.
	 * @since 3.3
	 */
	private IVerticalRuler internalGetVerticalRuler() {
		return getVerticalRuler();
	}

	/**
	 * Creates a new text editor.
	 * 
	 * @see #initializeEditor()
	 * @see #initializeKeyBindingScopes()
	 */
	public AbstractDecoratedTextEditor() {
		super();
		fAnnotationPreferences= EditorsPlugin.getDefault().getMarkerAnnotationPreferences();
		setRangeIndicator(new DefaultRangeIndicator());
		initializeKeyBindingScopes();
		initializeEditor();
	}

	/**
	 * Initializes this editor. Subclasses may re-implement. If sub-classes do
	 * not change the contract, this method should not be extended, i.e. do not
	 * call <code>super.initializeEditor()</code> in order to avoid the
	 * temporary creation of objects that are immediately overwritten by
	 * subclasses.
	 */
	protected void initializeEditor() {
		setPreferenceStore(EditorsPlugin.getDefault().getPreferenceStore());
	}

	/**
	 * Initializes the key binding scopes of this editor.
	 */
	protected void initializeKeyBindingScopes() {
		setKeyBindingScopes(new String[] { "org.eclipse.ui.textEditorScope" });  //$NON-NLS-1$
	}

	@Override
	public void dispose() {
		if (fSourceViewerDecorationSupport != null) {
			fSourceViewerDecorationSupport.dispose();
			fSourceViewerDecorationSupport= null;
		}

		fAnnotationAccess= null;
		fAnnotationPreferences= null;

		fLineNumberRulerColumn= null;
		fLineColumn= null;

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

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

		fAnnotationAccess= getAnnotationAccess();
		fOverviewRuler= createOverviewRuler(getSharedColors());

		ISourceViewer viewer= new SourceViewer(parent, ruler, getOverviewRuler(), isOverviewRulerVisible(), styles);
		// ensure decoration support has been created and configured.
		getSourceViewerDecorationSupport(viewer);

		return viewer;
	}

	protected ISharedTextColors getSharedColors() {
		return EditorsPlugin.getDefault().getSharedTextColors();
	}

	protected IOverviewRuler createOverviewRuler(ISharedTextColors sharedColors) {
		IOverviewRuler ruler= new OverviewRuler(getAnnotationAccess(), VERTICAL_RULER_WIDTH, sharedColors);

		Iterator<AnnotationPreference> e= fAnnotationPreferences.getAnnotationPreferences().iterator();
		while (e.hasNext()) {
			AnnotationPreference preference= e.next();
			if (preference.contributesToHeader())
				ruler.addHeaderAnnotationType(preference.getAnnotationType());
		}
		return ruler;
	}

	/**
	 * Creates the annotation access for this editor.
	 *
	 * @return the created annotation access
	 */
	protected IAnnotationAccess createAnnotationAccess() {
		return new DefaultMarkerAnnotationAccess();
	}

	/**
	 * Configures the decoration support for this editor's source viewer. Subclasses may override this
	 * method, but should call their superclass' implementation at some point.
	 *
	 * @param support the decoration support to configure
	 */
	protected void configureSourceViewerDecorationSupport(SourceViewerDecorationSupport support) {

		Iterator<AnnotationPreference> e= fAnnotationPreferences.getAnnotationPreferences().iterator();
		while (e.hasNext())
			support.setAnnotationPreference(e.next());

		support.setCursorLinePainterPreferenceKeys(CURRENT_LINE, CURRENT_LINE_COLOR);
		support.setMarginPainterPreferenceKeys(PRINT_MARGIN, PRINT_MARGIN_COLOR, PRINT_MARGIN_COLUMN);
	}

	/*
	 * @see org.eclipse.ui.texteditor.AbstractTextEditor.createPartControl(Composite)
	 */
	@Override
	public void createPartControl(Composite parent) {
		super.createPartControl(parent);
		if (fSourceViewerDecorationSupport != null)
			fSourceViewerDecorationSupport.install(getPreferenceStore());

		IColumnSupport columnSupport= getAdapter(IColumnSupport.class);

		if (isLineNumberRulerVisible()) {
			RulerColumnDescriptor lineNumberColumnDescriptor= RulerColumnRegistry.getDefault().getColumnDescriptor(LineNumberColumn.ID);
			if (lineNumberColumnDescriptor != null)
				columnSupport.setColumnVisible(lineNumberColumnDescriptor, true);
		}

		if (isPrefQuickDiffAlwaysOn())
			showChangeInformation(true);

		if (fOverviewRuler instanceof IOverviewRulerExtension)
			((IOverviewRulerExtension)fOverviewRuler).setUseSaturatedColors(isPrefUseSaturatedColorsOn());

		if (!isOverwriteModeEnabled())
			enableOverwriteMode(false);

		if (!isRangeIndicatorEnabled()) {
			getSourceViewer().removeRangeIndication();
			getSourceViewer().setRangeIndicator(null);
		}

		// Assign the quick assist assistant to the annotation access.
		ISourceViewer viewer= getSourceViewer();
		if (fAnnotationAccess instanceof IAnnotationAccessExtension2 && viewer instanceof ISourceViewerExtension3)
			((IAnnotationAccessExtension2)fAnnotationAccess).setQuickAssistAssistant(((ISourceViewerExtension3)viewer).getQuickAssistAssistant());

		createOverviewRulerContextMenu();
	}

	/**
	 * Creates the context menu for the overview ruler.
	 * <p>
	 * Subclasses may extend or replace this method.
	 * </p>
	 *
	 * @since 3.4
	 */
	protected void createOverviewRulerContextMenu() {
		if (fOverviewRulerContextMenuId == null)
			fOverviewRulerContextMenuId= DEFAULT_OVERVIEW_RULER_CONTEXT_MENU_ID;

		if (fOverviewRuler == null || fOverviewRuler.getControl() == null)
			return;

		MenuManager menuManager= new MenuManager(fOverviewRulerContextMenuId, fOverviewRulerContextMenuId);
		menuManager.setRemoveAllWhenShown(true);
		menuManager.addMenuListener(getContextMenuListener());
		Menu menu= menuManager.createContextMenu(getOverviewRuler().getControl());
		getOverviewRuler().getControl().setMenu(menu);
		getEditorSite().registerContextMenu(fOverviewRulerContextMenuId, menuManager, getSelectionProvider(), false);
	}

	@Override
	protected IMenuListener createContextMenuListener() {
		final IMenuListener superListener= super.createContextMenuListener();
		return new IMenuListener() {
			@Override
			public void menuAboutToShow(IMenuManager menu) {
				if (!getOverviewRulerContextMenuId().equals(menu.getId())) {
					superListener.menuAboutToShow(menu);
					return;
				}
				setFocus();
				overviewRulerContextMenuAboutToShow(menu);
			}
		};
	}

	@Override
	protected Control createStatusControl(Composite parent, final IStatus status) {
		Object adapter= getAdapter(IEncodingSupport.class);
		DefaultEncodingSupport encodingSupport= null;
		if (adapter instanceof DefaultEncodingSupport)
			encodingSupport= (DefaultEncodingSupport)adapter;

		if (encodingSupport == null || !encodingSupport.isEncodingError(status))
			return super.createStatusControl(parent, status);

		Shell shell= getSite().getShell();
		Display display= shell.getDisplay();
		Color bgColor= display.getSystemColor(SWT.COLOR_LIST_BACKGROUND);
		Color fgColor= display.getSystemColor(SWT.COLOR_LIST_FOREGROUND);

		Composite composite= new Composite(parent, SWT.NONE);
		composite.setLayout(new GridLayout());
		composite.setBackground(bgColor);
		composite.setForeground(fgColor);

		Control control= super.createStatusControl(composite, status);
		control.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

		Composite buttonComposite= new Composite(composite, SWT.NONE);
		buttonComposite.setLayout(new GridLayout());
		buttonComposite.setLayoutData(new GridData(GridData.FILL_BOTH));
		buttonComposite.setBackground(bgColor);
		buttonComposite.setForeground(fgColor);

		encodingSupport.createStatusEncodingChangeControl(buttonComposite, status);

		return composite;
	}

	/**
	 * Tells whether the overview ruler is visible.
	 *
	 * @return whether the overview ruler is visible
	 */
	protected boolean isOverviewRulerVisible() {
		IPreferenceStore store= getPreferenceStore();
		return store != null ? store.getBoolean(OVERVIEW_RULER) : false;
	}

	@Override
	public void showChangeInformation(boolean show) {
		if (show == isChangeInformationShowing())
			return;

		IColumnSupport columnSupport= getAdapter(IColumnSupport.class);

		// only handle visibility of the combined column, but not the number/change only state
		if (show && fLineColumn == null) {
			RulerColumnDescriptor lineNumberColumnDescriptor= RulerColumnRegistry.getDefault().getColumnDescriptor(LineNumberColumn.ID);
			if (lineNumberColumnDescriptor != null)
				columnSupport.setColumnVisible(lineNumberColumnDescriptor, true);
		} else if (!show && fLineColumn != null && !isLineNumberRulerVisible()) {
			columnSupport.setColumnVisible(fLineColumn.getDescriptor(), false);
			fLineColumn= null;
		}
	}

	@Override
	public boolean isChangeInformationShowing() {
		return fLineColumn != null && fLineColumn.isShowingChangeInformation();
	}

	@Override
	public void showRevisionInformation(RevisionInformation info, String quickDiffProviderId) {
		if (info.getHoverControlCreator() == null)
			info.setHoverControlCreator(new RevisionHoverInformationControlCreator(false));
		if (info.getInformationPresenterControlCreator() == null)
			info.setInformationPresenterControlCreator(new RevisionHoverInformationControlCreator(true));

		showChangeInformation(true);
		if (fLineColumn != null)
			fLineColumn.showRevisionInformation(info, quickDiffProviderId);
	}

	/**
	 * Returns whether the line number ruler column should be
	 * visible according to the preference store settings. Subclasses may override this
	 * method to provide a custom preference setting.
	 *
	 * @return <code>true</code> if the line numbers should be visible
	 */
	protected boolean isLineNumberRulerVisible() {
		IPreferenceStore store= getPreferenceStore();
		return store != null ? store.getBoolean(LINE_NUMBER_RULER) : false;
	}

	/**
	 * Returns whether the overwrite mode is enabled according to the preference
	 * store settings. Subclasses may override this method to provide a custom
	 * preference setting.
	 *
	 * @return <code>true</code> if overwrite mode is enabled
	 * @since 3.1
	 */
	protected boolean isOverwriteModeEnabled() {
		IPreferenceStore store= getPreferenceStore();
		return store != null ? !store.getBoolean(DISABLE_OVERWRITE_MODE) : true;
	}

	/**
	 * Returns whether the range indicator is enabled according to the preference
	 * store settings. Subclasses may override this method to provide a custom
	 * preference setting.
	 *
	 * @return <code>true</code> if overwrite mode is enabled
	 * @since 3.1
	 */
	private boolean isRangeIndicatorEnabled() {
		IPreferenceStore store= getPreferenceStore();
		return store != null ? store.getBoolean(AbstractDecoratedTextEditorPreferenceConstants.SHOW_RANGE_INDICATOR) : true;
	}

	/**
	 * Returns whether quick diff info should be visible upon opening an editor
	 * according to the preference store settings.
	 *
	 * @return <code>true</code> if the line numbers should be visible
	 */
	protected boolean isPrefQuickDiffAlwaysOn() {
		IPreferenceStore store= getPreferenceStore();
		boolean setting= store != null ? store.getBoolean(AbstractDecoratedTextEditorPreferenceConstants.QUICK_DIFF_ALWAYS_ON) : false;
		return setting && isEditorInputModifiable();
	}

	/**
	 * Checks if the preference to use saturated colors is enabled for the overview ruler.
	 * 
	 * @return <code>true</code> if the saturated colors preference is enabled, <code>false</code>
	 *         otherwise
	 * @since 3.8
	 */
	private boolean isPrefUseSaturatedColorsOn() {
		IPreferenceStore store= getPreferenceStore();
		return store != null ? store.getBoolean(USE_SATURATED_COLORS_IN_OVERVIEW_RULER) : false;
	}

	/**
	 * Initializes the given line number ruler column from the preference store.
	 *
	 * @param rulerColumn the ruler column to be initialized
	 */
	protected void initializeLineNumberRulerColumn(LineNumberRulerColumn rulerColumn) {
		/*
		 * Left for compatibility. See LineNumberColumn.
		 */
		if (fLineColumn != null)
			fLineColumn.initializeLineNumberRulerColumn(rulerColumn);
	}

	/**
	 * Creates a new line number ruler column that is appropriately initialized.
	 *
	 * @return the created line number column
	 */
	protected IVerticalRulerColumn createLineNumberRulerColumn() {
		/*
		 * Left for compatibility. See LineNumberColumn.
		 */
		fLineNumberRulerColumn= new LineNumberChangeRulerColumn(getSharedColors());
		((IChangeRulerColumn) fLineNumberRulerColumn).setHover(createChangeHover());
		initializeLineNumberRulerColumn(fLineNumberRulerColumn);
		return fLineNumberRulerColumn;
	}

	/**
	 * Creates and returns a <code>LineChangeHover</code> to be used on this editor's change
	 * ruler column. This default implementation returns a plain <code>LineChangeHover</code>.
	 * Subclasses may override.
	 *
	 * @return the change hover to be used by this editors quick diff display
	 */
	protected LineChangeHover createChangeHover() {
		return new TextChangeHover();
	}

	/**
	 * Creates a new change ruler column for quick diff display independent of the
	 * line number ruler column
	 *
	 * @return a new change ruler column
	 * @deprecated as of 3.3. Not called any longer, replaced by {@link #createLineNumberRulerColumn()}
	 */
	@Deprecated
	protected IChangeRulerColumn createChangeRulerColumn() {
		/*
		 * Left for compatibility. See LineNumberColumn.
		 */
		return new ChangeRulerColumn(getSharedColors());
	}

	/**
	 * Returns {@link #createCompositeRuler()}. Subclasses should not override this method, but
	 * rather <code>createCompositeRuler</code> if they want to contribute their own vertical ruler
	 * implementation. If not an instance of {@link CompositeRuler} is returned, the built-in ruler
	 * columns (line numbers, annotations) will not work.
	 *
	 * <p>May become <code>final</code> in the future.</p>
	 *
	 * @see AbstractTextEditor#createVerticalRuler()
	 */
	@Override
	protected IVerticalRuler createVerticalRuler() {
		return createCompositeRuler();
	}


	/**
	 * Creates a composite ruler to be used as the vertical ruler by this editor.
	 * Subclasses may re-implement this method.
	 *
	 * @return the vertical ruler
	 */
	protected CompositeRuler createCompositeRuler() {
		return new CompositeRuler();
	}


	/**
	 * Creates the annotation ruler column. Subclasses may re-implement or extend.
	 *
	 * @param ruler the composite ruler that the column will be added
	 * @return an annotation ruler column
	 * @since 3.2
	 */
	protected IVerticalRulerColumn createAnnotationRulerColumn(CompositeRuler ruler) {
		return new AnnotationRulerColumn(VERTICAL_RULER_WIDTH, getAnnotationAccess());
	}

	@Override
	protected final IColumnSupport createColumnSupport() {
		return new ColumnSupport(this, RulerColumnRegistry.getDefault()) {
			@Override
			protected void initializeColumn(IContributedRulerColumn column) {
				super.initializeColumn(column);
				RulerColumnDescriptor descriptor= column.getDescriptor();
				IVerticalRuler ruler= internalGetVerticalRuler();
				if (ruler instanceof CompositeRuler) {
					if (AnnotationColumn.ID.equals(descriptor.getId())) {
						((AnnotationColumn)column).setDelegate(createAnnotationRulerColumn((CompositeRuler) ruler));
					} else if (LineNumberColumn.ID.equals(descriptor.getId())) {
						fLineColumn= ((LineNumberColumn) column);
						fLineColumn.setForwarder(new LineNumberColumn.ICompatibilityForwarder() {
							@Override
							public IVerticalRulerColumn createLineNumberRulerColumn() {
								return AbstractDecoratedTextEditor.this.createLineNumberRulerColumn();
							}
							@Override
							public boolean isQuickDiffEnabled() {
								return AbstractDecoratedTextEditor.this.isPrefQuickDiffAlwaysOn();
							}
							@Override
							public boolean isLineNumberRulerVisible() {
								return AbstractDecoratedTextEditor.this.isLineNumberRulerVisible();
							}
						});
					}
				}
			}

			@Override
			public void dispose() {
				fLineColumn= null;
				super.dispose();
			}
		};
	}

	@Override
	protected void handlePreferenceStoreChanged(PropertyChangeEvent event) {

		try {

			ISourceViewer sourceViewer= getSourceViewer();
			if (sourceViewer == null)
				return;

			String property= event.getProperty();

			if (fSourceViewerDecorationSupport != null && fOverviewRuler != null && OVERVIEW_RULER.equals(property))  {
				if (isOverviewRulerVisible())
					showOverviewRuler();
				else
					hideOverviewRuler();
				return;
			}

			if (USE_SATURATED_COLORS_IN_OVERVIEW_RULER.equals(property)) {
				if (fOverviewRuler instanceof IOverviewRulerExtension) {
					((IOverviewRulerExtension)fOverviewRuler).setUseSaturatedColors(isPrefUseSaturatedColorsOn());
					fOverviewRuler.update();
				}
			}

			if (DISABLE_OVERWRITE_MODE.equals(property)) {
				enableOverwriteMode(isOverwriteModeEnabled());
				return;
			}

			if (LINE_NUMBER_RULER.equals(property)) {
				// only handle visibility of the combined column, but not the number/change only state
				IColumnSupport columnSupport= getAdapter(IColumnSupport.class);
				if (isLineNumberRulerVisible() && fLineColumn == null) {
					RulerColumnDescriptor lineNumberColumnDescriptor= RulerColumnRegistry.getDefault().getColumnDescriptor(LineNumberColumn.ID);
					if (lineNumberColumnDescriptor != null)
						columnSupport.setColumnVisible(lineNumberColumnDescriptor, true);
				} else if (!isLineNumberRulerVisible() && fLineColumn != null && !fLineColumn.isShowingChangeInformation()) {
					columnSupport.setColumnVisible(fLineColumn.getDescriptor(), false);
					fLineColumn= null;
				}
				return;
			}

			if (AbstractDecoratedTextEditorPreferenceConstants.QUICK_DIFF_ALWAYS_ON.equals(property)) {
				showChangeInformation(isPrefQuickDiffAlwaysOn());
			}

			if (AbstractDecoratedTextEditorPreferenceConstants.EDITOR_TAB_WIDTH.equals(property)) {
				IPreferenceStore store= getPreferenceStore();
				if (store != null)
					sourceViewer.getTextWidget().setTabs(store.getInt(AbstractDecoratedTextEditorPreferenceConstants.EDITOR_TAB_WIDTH));
				if (isTabsToSpacesConversionEnabled()) {
					uninstallTabsToSpacesConverter();
					installTabsToSpacesConverter();
				}
				return;
			}

			if (AbstractDecoratedTextEditorPreferenceConstants.EDITOR_SPACES_FOR_TABS.equals(property)) {
				if (isTabsToSpacesConversionEnabled())
					installTabsToSpacesConverter();
				else
					uninstallTabsToSpacesConverter();
				return;
			}

			if (AbstractDecoratedTextEditorPreferenceConstants.EDITOR_UNDO_HISTORY_SIZE.equals(property) && sourceViewer instanceof ITextViewerExtension6) {
				IPreferenceStore store= getPreferenceStore();
				if (store != null)
					((ITextViewerExtension6)sourceViewer).getUndoManager().setMaximalUndoLevel(store.getInt(AbstractDecoratedTextEditorPreferenceConstants.EDITOR_UNDO_HISTORY_SIZE));
				return;
			}

			if (AbstractDecoratedTextEditorPreferenceConstants.SHOW_RANGE_INDICATOR.equals(property)) {
				if (isRangeIndicatorEnabled()) {
					getSourceViewer().setRangeIndicator(getRangeIndicator());
				} else {
					getSourceViewer().removeRangeIndication();
					getSourceViewer().setRangeIndicator(null);
				}
			}

			if (sourceViewer instanceof ITextViewerExtension6) {
				HyperlinkDetectorDescriptor[] descriptor= EditorsUI.getHyperlinkDetectorRegistry().getHyperlinkDetectorDescriptors();
				for (int i= 0; i < descriptor.length; i++) {
					if (descriptor[i].getId().equals(property) || (descriptor[i].getId() + HyperlinkDetectorDescriptor.STATE_MASK_POSTFIX).equals(property)) {
						IHyperlinkDetector[] detectors= getSourceViewerConfiguration().getHyperlinkDetectors(sourceViewer);
						int stateMask= getSourceViewerConfiguration().getHyperlinkStateMask(sourceViewer);
						ITextViewerExtension6 textViewer6= (ITextViewerExtension6)sourceViewer;
						textViewer6.setHyperlinkDetectors(detectors, stateMask);
						return;
					}
				}
			}

		} finally {
			super.handlePreferenceStoreChanged(event);
		}
	}

	/**
	 * Shows the overview ruler.
	 */
	protected void showOverviewRuler() {
		if (fOverviewRuler != null) {
			if (getSourceViewer() instanceof ISourceViewerExtension) {
				((ISourceViewerExtension) getSourceViewer()).showAnnotationsOverview(true);
				fSourceViewerDecorationSupport.updateOverviewDecorations();
			}
		}
	}

	/**
	 * Hides the overview ruler.
	 */
	protected void hideOverviewRuler() {
		if (getSourceViewer() instanceof ISourceViewerExtension) {
			fSourceViewerDecorationSupport.hideAnnotationOverview();
			((ISourceViewerExtension) getSourceViewer()).showAnnotationsOverview(false);
		}
	}

	/**
	 * Returns the annotation access.
	 *
	 * @return the annotation access
	 */
	protected IAnnotationAccess getAnnotationAccess() {
		if (fAnnotationAccess == null)
			fAnnotationAccess= createAnnotationAccess();
		return fAnnotationAccess;
	}

	/**
	 * Returns the annotation preference lookup.
	 *
	 * @return the annotation preference lookup
	 */
	protected AnnotationPreferenceLookup getAnnotationPreferenceLookup() {
		return EditorsPlugin.getDefault().getAnnotationPreferenceLookup();
	}

	/**
	 * Returns the overview ruler.
	 *
	 * @return the overview ruler
	 */
	protected IOverviewRuler getOverviewRuler() {
		if (fOverviewRuler == null)
			fOverviewRuler= createOverviewRuler(getSharedColors());
		return fOverviewRuler;
	}

	/**
	 * Returns the source viewer decoration support.
	 *
	 * @param viewer the viewer for which to return a decoration support
	 * @return the source viewer decoration support
	 */
	protected SourceViewerDecorationSupport getSourceViewerDecorationSupport(ISourceViewer viewer) {
		if (fSourceViewerDecorationSupport == null) {
			fSourceViewerDecorationSupport= new SourceViewerDecorationSupport(viewer, getOverviewRuler(), getAnnotationAccess(), getSharedColors());
			configureSourceViewerDecorationSupport(fSourceViewerDecorationSupport);
		}
		return fSourceViewerDecorationSupport;
	}

	/**
	 * Returns the annotation preferences.
	 *
	 * @return the annotation preferences
	 */
	protected MarkerAnnotationPreferences getAnnotationPreferences() {
		return fAnnotationPreferences;
	}


	/**
	 * If the editor can be saved all marker ranges have been changed according to
	 * the text manipulations. However, those changes are not yet propagated to the
	 * marker manager. Thus, when opening a marker, the marker's position in the editor
	 * must be determined as it might differ from the position stated in the marker.
	 *
	 * @param marker the marker to go to
	 * @deprecated visibility will be reduced, use <code>getAdapter(IGotoMarker.class) for accessing this method</code>
	 */
	@Deprecated
	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();
			}

			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)
					line= document.getLineOfOffset(start);
				else {
					line= MarkerUtilities.getLineNumber(marker);
					// Marker line numbers are 1-based
					-- line;
					start= document.getLineOffset(line);
				}
				end= start + document.getLineLength(line) - 1;
			} catch (BadLocationException e) {
				return;
			}
		}

		int length= document.getLength();
		if (end <= length && start <= length) {
			fIsComingFromGotoMarker= true;
			selectAndReveal(start, end - start);
		}
	}

	@Override
	public boolean isEditable() {
		if (!super.isEditable())
			return false;
		return fIsEditingDerivedFileAllowed;
	}

	@Override
	public boolean validateEditorInputState() {
		if (!super.validateEditorInputState())
			return false;

		return validateEditorInputDerived();
	}

	/**
	 * Validates the editor input for derived state.
	 * If the given input is derived then this method
	 * can show a dialog asking whether to edit the
	 * derived file.
	 *
	 * @return <code>true</code> if the input is OK for editing, <code>false</code> otherwise
	 * @since 3.3
	 */
	private boolean validateEditorInputDerived() {
		if (fIsDerivedStateValidated)
			return fIsEditingDerivedFileAllowed;

		if (getDocumentProvider() instanceof IDocumentProviderExtension) {
			IDocumentProviderExtension extension= (IDocumentProviderExtension)getDocumentProvider();
			IStatus status= extension.getStatus(getEditorInput());
			String pluginId= status.getPlugin();
			boolean isDerivedStatus= status.getCode() == IFileBufferStatusCodes.DERIVED_FILE && (FileBuffers.PLUGIN_ID.equals(pluginId) || EditorsUI.PLUGIN_ID.equals(pluginId));
			if (!isDerivedStatus)
				return true;
		}

		final String warnKey= AbstractDecoratedTextEditorPreferenceConstants.EDITOR_WARN_IF_INPUT_DERIVED;
		IPreferenceStore store= getPreferenceStore();
		if (!store.getBoolean(warnKey))
			return true;

		MessageDialogWithToggle toggleDialog= MessageDialogWithToggle.openYesNoQuestion(
				getSite().getShell(),
				TextEditorMessages.AbstractDecoratedTextEditor_warning_derived_title,
				TextEditorMessages.AbstractDecoratedTextEditor_warning_derived_message,
				TextEditorMessages.AbstractDecoratedTextEditor_warning_derived_dontShowAgain,
				false,
				null,
				null);

		EditorsUI.getPreferenceStore().setValue(warnKey, !toggleDialog.getToggleState());
		fIsDerivedStateValidated= true;
		return fIsEditingDerivedFileAllowed= toggleDialog.getReturnCode() == IDialogConstants.YES_ID;
	}

	/*
	 * For an explanation why we override this method see http://bugs.eclipse.org/42230
	 *
	 * @see org.eclipse.ui.texteditor.StatusTextEditor#isErrorStatus(org.eclipse.core.runtime.IStatus)
	 */
	@Override
	protected boolean isErrorStatus(IStatus status) {
		if (!super.isErrorStatus(status))
			return false;

		if (!status.isMultiStatus())
			return !isReadOnlyLocalStatus(status);

		IStatus[] childrenStatus= status.getChildren();
		for (int i= 0; i < childrenStatus.length; i++) {
			if (childrenStatus[i].getSeverity() == IStatus.ERROR && !isReadOnlyLocalStatus(childrenStatus[i]))
				return true;
		}

		return false;
	}

	/**
	 * Check whether the given status is a <code>IResourceStatus.READ_ONLY_LOCAL</code>
	 * error.
	 *
	 * @param status the status to be checked
	 * @return <code>true</code> if the given status is a <code>IResourceStatus.READ_ONLY_LOCAL</code> error
	 * @since 3.3
	 */
	private boolean isReadOnlyLocalStatus(IStatus status) {
		return status.getCode() == IResourceStatus.READ_ONLY_LOCAL;
	}

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

		ResourceAction action= new AddMarkerAction(TextEditorMessages.getBundleForConstructedKeys(), "Editor.AddBookmark.", this, IMarker.BOOKMARK, true); //$NON-NLS-1$
		action.setHelpContextId(ITextEditorHelpContextIds.BOOKMARK_ACTION);
		action.setActionDefinitionId(IWorkbenchCommandConstants.EDIT_ADD_BOOKMARK);
		setAction(IDEActionFactory.BOOKMARK.getId(), action);

		action= new AddTaskAction(TextEditorMessages.getBundleForConstructedKeys(), "Editor.AddTask.", this); //$NON-NLS-1$
		action.setHelpContextId(ITextEditorHelpContextIds.ADD_TASK_ACTION);
		action.setActionDefinitionId(IWorkbenchCommandConstants.EDIT_ADD_TASK);
		setAction(IDEActionFactory.ADD_TASK.getId(), action);

		action= new ChangeEncodingAction(TextEditorMessages.getBundleForConstructedKeys(), "Editor.ChangeEncodingAction.", this); //$NON-NLS-1$
		action.setHelpContextId(ITextEditorHelpContextIds.CHANGE_ENCODING);
		action.setActionDefinitionId(ITextEditorActionDefinitionIds.CHANGE_ENCODING);
		setAction(ITextEditorActionConstants.CHANGE_ENCODING, action);
		markAsPropertyDependentAction(ITextEditorActionConstants.CHANGE_ENCODING, true);

		action= new ResourceAction(TextEditorMessages.getBundleForConstructedKeys(), "Editor.ToggleLineNumbersAction.", IAction.AS_CHECK_BOX) { //$NON-NLS-1$
			@Override
			public void run() {
				toggleLineNumberRuler();
			}
		};
		action.setActionDefinitionId(ITextEditorActionDefinitionIds.LINENUMBER_TOGGLE);
		setAction(ITextEditorActionConstants.LINENUMBERS_TOGGLE, action);

		action= new ResourceAction(TextEditorMessages.getBundleForConstructedKeys(), "Editor.ToggleQuickDiffAction.", IAction.AS_CHECK_BOX) { //$NON-NLS-1$
			@Override
			public void run() {
				toggleQuickDiffRuler();
			}
		};
		action.setActionDefinitionId(ITextEditorActionDefinitionIds.QUICKDIFF_TOGGLE);
		setAction(ITextEditorActionConstants.QUICKDIFF_TOGGLE, action);

		action= new RevertLineAction(this, false);
		action.setActionDefinitionId(ITextEditorActionDefinitionIds.QUICKDIFF_REVERTLINE);
		setAction(ITextEditorActionConstants.QUICKDIFF_REVERTLINE, action);

		action= new RevertSelectionAction(this, false);
		setAction(ITextEditorActionConstants.QUICKDIFF_REVERTSELECTION, action);

		action= new RevertBlockAction(this, false);
		setAction(ITextEditorActionConstants.QUICKDIFF_REVERTBLOCK, action);

		action= new RestoreAction(this, false);
		setAction(ITextEditorActionConstants.QUICKDIFF_REVERTDELETION, action);

		IAction action2= new CompositeRevertAction(this, new IAction[] {
		                                       getAction(ITextEditorActionConstants.QUICKDIFF_REVERTSELECTION),
		                                       getAction(ITextEditorActionConstants.QUICKDIFF_REVERTBLOCK),
										       getAction(ITextEditorActionConstants.QUICKDIFF_REVERTDELETION),
										       getAction(ITextEditorActionConstants.QUICKDIFF_REVERTLINE)});
		action2.setActionDefinitionId(ITextEditorActionDefinitionIds.QUICKDIFF_REVERT);
		setAction(ITextEditorActionConstants.QUICKDIFF_REVERT, action2);

		action= new ResourceAction(TextEditorMessages.getBundleForConstructedKeys(), "Editor.HideRevisionInformationAction.") { //$NON-NLS-1$
			@Override
			public void run() {
				if (fLineColumn != null)
					fLineColumn.hideRevisionInformation();
			}
		};
		setAction(ITextEditorActionConstants.REVISION_HIDE_INFO, action);

		action= new ResourceAction(TextEditorMessages.getBundleForConstructedKeys(), "Editor.CycleRevisionRenderingAction.") { //$NON-NLS-1$
			@Override
			public void run() {
				final RenderingMode[] modes= { IRevisionRulerColumnExtension.AGE, IRevisionRulerColumnExtension.AUTHOR, IRevisionRulerColumnExtension.AUTHOR_SHADED_BY_AGE};
				IPreferenceStore store= EditorsUI.getPreferenceStore();
				String current= store.getString(AbstractDecoratedTextEditorPreferenceConstants.REVISION_RULER_RENDERING_MODE);
				for (int i= 0; i < modes.length; i++) {
					String mode= modes[i].name();
					if (mode.equals(current)) {
						int nextIndex= (i + 1) % modes.length;
						RenderingMode nextMode= modes[nextIndex];
						store.setValue(AbstractDecoratedTextEditorPreferenceConstants.REVISION_RULER_RENDERING_MODE, nextMode.name());
					}
				}
			}
		};
		action.setActionDefinitionId(ITextEditorActionDefinitionIds.REVISION_RENDERING_CYCLE);
		setAction(ITextEditorActionConstants.REVISION_RENDERING_CYCLE, action);

		action= new BooleanPreferenceToggleAction(TextEditorMessages.getBundleForConstructedKeys(), "Editor.ToggleRevisionAuthorAction.", IAction.AS_CHECK_BOX, EditorsUI.getPreferenceStore(), AbstractDecoratedTextEditorPreferenceConstants.REVISION_RULER_SHOW_AUTHOR); //$NON-NLS-1$
		action.setActionDefinitionId(ITextEditorActionDefinitionIds.REVISION_AUTHOR_TOGGLE);
		setAction(ITextEditorActionConstants.REVISION_SHOW_AUTHOR_TOGGLE, action);

		action= new BooleanPreferenceToggleAction(TextEditorMessages.getBundleForConstructedKeys(), "Editor.ToggleRevisionIdAction.", IAction.AS_CHECK_BOX, EditorsUI.getPreferenceStore(), AbstractDecoratedTextEditorPreferenceConstants.REVISION_RULER_SHOW_REVISION); //$NON-NLS-1$
		action.setActionDefinitionId(ITextEditorActionDefinitionIds.REVISION_ID_TOGGLE);
		setAction(ITextEditorActionConstants.REVISION_SHOW_ID_TOGGLE, action);

		final Shell shell;
		if (getSourceViewer() != null)
			shell= getSourceViewer().getTextWidget().getShell();
		else
			shell= null;
		action= new ResourceAction(TextEditorMessages.getBundleForConstructedKeys(), "Editor.RulerPreferencesAction.") { //$NON-NLS-1$
			@Override
			public void run() {
				String[] preferencePages= collectRulerMenuPreferencePages();
				if (preferencePages.length > 0 && (shell == null || !shell.isDisposed()))
					PreferencesUtil.createPreferenceDialogOn(shell, preferencePages[0], preferencePages, null).open();
			}

		};
		setAction(ITextEditorActionConstants.RULER_PREFERENCES, action);

		action= new ResourceAction(TextEditorMessages.getBundleForConstructedKeys(), "Editor.ContextPreferencesAction.") { //$NON-NLS-1$
			@Override
			public void run() {
				String[] preferencePages= collectContextMenuPreferencePages();
				if (preferencePages.length > 0 && (shell == null || !shell.isDisposed()))
					PreferencesUtil.createPreferenceDialogOn(shell, preferencePages[0], preferencePages, null).open();
			}
		};
		setAction(ITextEditorActionConstants.CONTEXT_PREFERENCES, action);

		IAction showWhitespaceCharactersAction= getAction(ITextEditorActionConstants.SHOW_WHITESPACE_CHARACTERS);
		if (showWhitespaceCharactersAction instanceof ShowWhitespaceCharactersAction)
			((ShowWhitespaceCharactersAction)showWhitespaceCharactersAction).setPreferenceStore(EditorsUI.getPreferenceStore());

		setAction(ITextEditorActionConstants.REFRESH, new RefreshEditorAction(this));
		markAsPropertyDependentAction(ITextEditorActionConstants.REFRESH, true);

		// Override print action to provide additional options
		if (getAction(ITextEditorActionConstants.PRINT).isEnabled() && getSourceViewer() instanceof ITextViewerExtension8)
			createPrintAction();
		
		action= new ResourceAction(TextEditorMessages.getBundleForConstructedKeys(), "Editor.ShowChangeRulerInformation.", IAction.AS_PUSH_BUTTON) { //$NON-NLS-1$
			@Override
			public void run() {
				showChangeRulerInformation();
			}
		};
		action.setActionDefinitionId(ITextEditorActionDefinitionIds.SHOW_CHANGE_RULER_INFORMATION_ID);
		setAction(ITextEditorActionConstants.SHOW_CHANGE_RULER_INFORMATION, action);

		action= new ResourceAction(TextEditorMessages.getBundleForConstructedKeys(), "Editor.ShowRulerAnnotationInformation.", IAction.AS_PUSH_BUTTON) { //$NON-NLS-1$
			@Override
			public void run() {
				showRulerAnnotationInformation();
			}
		};
		action.setActionDefinitionId(ITextEditorActionDefinitionIds.SHOW_RULER_ANNOTATION_INFORMATION_ID);
		setAction(ITextEditorActionConstants.SHOW_RULER_ANNOTATION_INFORMATION, action);
	}

	/**
	 * Opens a sticky change ruler hover for the caret line. Does nothing if no change hover is
	 * available.
	 * 
	 * @since 3.5
	 */
	private void showChangeRulerInformation() {
		IVerticalRuler ruler= getVerticalRuler();
		if (!(ruler instanceof CompositeRuler) || fLineColumn == null)
			return;
		
		CompositeRuler compositeRuler= (CompositeRuler)ruler;

		// fake a mouse move (some hovers rely on this to determine the hovered line):
		int x= fLineColumn.getControl().getLocation().x;
		
		ISourceViewer sourceViewer= getSourceViewer();
		StyledText textWidget= sourceViewer.getTextWidget();
		int caretOffset= textWidget.getCaretOffset();
		int caretLine= textWidget.getLineAtOffset(caretOffset);
		int y= textWidget.getLinePixel(caretLine);
		
		compositeRuler.setLocationOfLastMouseButtonActivity(x, y);
		
		IAnnotationHover hover= fLineColumn.getHover();
		showFocusedRulerHover(hover, sourceViewer, caretOffset);
    }

	/**
	 * Opens a sticky annotation ruler hover for the caret line. Does nothing if no annotation hover
	 * is available.
	 * 
	 * @since 3.6
	 */
	private void showRulerAnnotationInformation() {
		ISourceViewer sourceViewer= getSourceViewer();
		IAnnotationHover hover= getSourceViewerConfiguration().getAnnotationHover(sourceViewer);
		int caretOffset= sourceViewer.getTextWidget().getCaretOffset();
		
		showFocusedRulerHover(hover, sourceViewer, caretOffset);
	}

	/**
	 * Shows a focused hover at the specified offset.
	 * Does nothing if <code>hover</code> is <code>null</code> or cannot be shown.
	 * 
	 * @param hover the hover to be shown, can be <code>null</code>
	 * @param sourceViewer the source viewer
	 * @param caretOffset the caret offset
	 * 
	 * @since 3.6
	 */
	private void showFocusedRulerHover(IAnnotationHover hover, ISourceViewer sourceViewer, int caretOffset) {
		if (hover == null)
			return;
		
		int modelCaretOffset= widgetOffset2ModelOffset(sourceViewer, caretOffset);
		if (modelCaretOffset == -1)
			return;
		
		IDocument document= sourceViewer.getDocument();
		if (document == null)
			return;
		
		try {
			int line= document.getLineOfOffset(modelCaretOffset);
			if (fInformationPresenter == null) {
				fInformationPresenter= new FocusedInformationPresenter(sourceViewer, getSourceViewerConfiguration());
			}
			fInformationPresenter.openFocusedAnnotationHover(hover, line);
		} catch (BadLocationException e) {
			return;
		}
	}

	/**
	 * Creates and registers the print action.
	 *
	 * @since 3.4
	 */
	private void createPrintAction() {
		final ISourceViewer viewer= getSourceViewer();
		ResourceAction action= new ResourceAction(TextEditorMessages.getBundleForConstructedKeys(), "Editor.Print.") { //$NON-NLS-1$

			@Override
			public void run() {
				StyledTextPrintOptions options= new StyledTextPrintOptions();
				options.printTextFontStyle= true;
				options.printTextForeground= true;
				options.printTextBackground= true;
				options.jobName= getTitle();
				options.header= StyledTextPrintOptions.SEPARATOR + getTitle();
				options.footer= StyledTextPrintOptions.SEPARATOR + NLSUtility.format(TextEditorMessages.AbstractDecoratedTextEditor_printPageNumber, StyledTextPrintOptions.PAGE_TAG);

				if (isLineNumberRulerVisible()) {
					options.printLineNumbers= true;

					// Compute line number labels
					options.lineLabels= new String[viewer.getTextWidget().getLineCount()];
					for (int i= 0; i < options.lineLabels.length; i++)
						options.lineLabels[i]= String.valueOf(JFaceTextUtil.widgetLine2ModelLine(viewer, i) + 1);
				}

				((ITextViewerExtension8)viewer).print(options);
			}
		};

		action.setHelpContextId(IAbstractTextEditorHelpContextIds.PRINT_ACTION);
		action.setActionDefinitionId(IWorkbenchCommandConstants.FILE_PRINT);
		setAction(ITextEditorActionConstants.PRINT, action);
	}

	@SuppressWarnings("unchecked")
	@Override
	public <T> T getAdapter(Class<T> adapter) {
		if (IGotoMarker.class.equals(adapter))
			return (T) fGotoMarkerAdapter;

		if (IAnnotationAccess.class.equals(adapter))
			return (T) getAnnotationAccess();

		if (adapter == IShowInSource.class) {
			return (T) new IShowInSource() {
				@Override
				public ShowInContext getShowInContext() {
					ISelection selection= null;
					ISelectionProvider selectionProvider= getSelectionProvider();
					if (selectionProvider != null)
						selection= selectionProvider.getSelection();
					return new ShowInContext(getEditorInput(), selection);
				}
			};
		}

		if (IRevisionRulerColumn.class.equals(adapter)) {
			if (fLineNumberRulerColumn instanceof IRevisionRulerColumn)
				return (T) fLineNumberRulerColumn;
		}

		if (MarkerAnnotationPreferences.class.equals(adapter))
			return (T) EditorsPlugin.getDefault().getMarkerAnnotationPreferences();

		return super.getAdapter(adapter);

	}

	/*
	 * If there is no explicit document provider set, the implicit one is
	 * re-initialized based on the given editor input.
	 *
	 * @see org.eclipse.ui.texteditor.AbstractTextEditor#setDocumentProvider(org.eclipse.ui.IEditorInput)
	 */
	@Override
	protected void setDocumentProvider(IEditorInput input) {
		fImplicitDocumentProvider= DocumentProviderRegistry.getDefault().getDocumentProvider(input);
		IDocumentProvider provider= super.getDocumentProvider();
		if (provider instanceof ForwardingDocumentProvider) {
			ForwardingDocumentProvider forwarder= (ForwardingDocumentProvider) provider;
			forwarder.setParentProvider(fImplicitDocumentProvider);
		}
	}

	@Override
	public IDocumentProvider getDocumentProvider() {
		IDocumentProvider provider= super.getDocumentProvider();
		if (provider == null)
			return fImplicitDocumentProvider;
		return provider;
	}

	@Override
	protected void disposeDocumentProvider() {
		super.disposeDocumentProvider();
		fImplicitDocumentProvider= null;
	}

	/*
	 * @see AbstractTextEditor#doSetInput(IEditorInput)
	 *
	 * This implementation also updates change information in the quick diff
	 * ruler.
	 */
	@Override
	protected void doSetInput(IEditorInput input) throws CoreException {
		fIsDerivedStateValidated= false;
		fIsEditingDerivedFileAllowed= true;

		if (fLineColumn != null)
			fLineColumn.hideRevisionInformation();

		super.doSetInput(input);

		RulerColumnDescriptor lineNumberColumnDescriptor= RulerColumnRegistry.getDefault().getColumnDescriptor(LineNumberColumn.ID);
		if (lineNumberColumnDescriptor != null) {
			IColumnSupport columnSupport= getAdapter(IColumnSupport.class);
			columnSupport.setColumnVisible(lineNumberColumnDescriptor, isLineNumberRulerVisible() || isPrefQuickDiffAlwaysOn());
		}
	}

	@Override
	protected void handleEditorInputChanged() {
		final IDocumentProvider provider= getDocumentProvider();
		IEditorInput input= getEditorInput();
		if (provider != null && input != null) {
			if (!isDirty() && input.getAdapter(IFile.class) != null) {
				if (Platform.getPreferencesService().getBoolean(ResourcesPlugin.PI_RESOURCES, ResourcesPlugin.PREF_LIGHTWEIGHT_AUTO_REFRESH, false, null))
					return;
			}
		}
		super.handleEditorInputChanged();
	}

	/**
	 * This implementation asks the user for the workspace path of a file resource and saves the document there.
	 *
	 * @param progressMonitor the progress monitor to be used
	 * @since 3.2
	 */
	@Override
	protected void performSaveAs(IProgressMonitor progressMonitor) {
		Shell shell= PlatformUI.getWorkbench().getModalDialogShellProvider().getShell();
		final IEditorInput input= getEditorInput();

		IDocumentProvider provider= getDocumentProvider();
		final IEditorInput newInput;

		if (input instanceof IURIEditorInput && !(input instanceof IFileEditorInput)) {
			FileDialog dialog= new FileDialog(shell, SWT.SAVE);
			IPath oldPath= URIUtil.toPath(((IURIEditorInput)input).getURI());
			if (oldPath != null && !oldPath.isEmpty()) {
				dialog.setFileName(oldPath.lastSegment());
				dialog.setFilterPath(oldPath.removeLastSegments(1).toOSString());
			}

			String path= dialog.open();
			if (path == null) {
				if (progressMonitor != null)
					progressMonitor.setCanceled(true);
				return;
			}

			// Check whether file exists and if so, confirm overwrite
			final File localFile= new File(path);
			if (localFile.exists()) {
		        MessageDialog overwriteDialog= new MessageDialog(
		        		shell,
		        		TextEditorMessages.AbstractDecoratedTextEditor_saveAs_overwrite_title,
		        		null,
		        		NLSUtility.format(TextEditorMessages.AbstractDecoratedTextEditor_saveAs_overwrite_message, path),
		        		MessageDialog.WARNING,
		        		new String[] { IDialogConstants.YES_LABEL, IDialogConstants.NO_LABEL },
		        		1); // 'No' is the default
				if (overwriteDialog.open() != Window.OK) {
					if (progressMonitor != null) {
						progressMonitor.setCanceled(true);
						return;
					}
				}
			}

			IFileStore fileStore;
			try {
				fileStore= EFS.getStore(localFile.toURI());
			} catch (CoreException ex) {
				EditorsPlugin.log(ex.getStatus());
				String title= TextEditorMessages.AbstractDecoratedTextEditor_error_saveAs_title;
				String msg= NLSUtility.format(TextEditorMessages.AbstractDecoratedTextEditor_error_saveAs_message, ex.getMessage());
				MessageDialog.openError(shell, title, msg);
				return;
			}

			IFile file= getWorkspaceFile(fileStore);
			if (file != null)
				newInput= new FileEditorInput(file);
			else
				newInput= new FileStoreEditorInput(fileStore);

		} else {
			SaveAsDialog dialog= new SaveAsDialog(shell);

			IFile original= (input instanceof IFileEditorInput) ? ((IFileEditorInput) input).getFile() : null;
			if (original != null)
				dialog.setOriginalFile(original);
			else
				dialog.setOriginalName(input.getName());

			dialog.create();

			if (provider.isDeleted(input) && original != null) {
				String message= NLSUtility.format(TextEditorMessages.AbstractDecoratedTextEditor_warning_saveAs_deleted, original.getName());
				dialog.setErrorMessage(null);
				dialog.setMessage(message, IMessageProvider.WARNING);
			}

			if (dialog.open() == Window.CANCEL) {
				if (progressMonitor != null)
					progressMonitor.setCanceled(true);
				return;
			}

			IPath filePath= dialog.getResult();
			if (filePath == null) {
				if (progressMonitor != null)
					progressMonitor.setCanceled(true);
				return;
			}

			IWorkspace workspace= ResourcesPlugin.getWorkspace();
			IFile file= workspace.getRoot().getFile(filePath);
			newInput= new FileEditorInput(file);

		}

		if (provider == null) {
			// editor has programmatically been  closed while the dialog was open
			return;
		}

		boolean success= false;
		try {

			provider.aboutToChange(newInput);
			provider.saveDocument(progressMonitor, newInput, provider.getDocument(input), true);
			success= true;

		} catch (CoreException x) {
			final IStatus status= x.getStatus();
			if (status == null || status.getSeverity() != IStatus.CANCEL) {
				String title= TextEditorMessages.AbstractDecoratedTextEditor_error_saveAs_title;
				String msg= NLSUtility.format(TextEditorMessages.AbstractDecoratedTextEditor_error_saveAs_message, x.getMessage());
				MessageDialog.openError(shell, title, msg);
			}
		} finally {
			provider.changed(newInput);
			if (success)
				setInput(newInput);
		}

		if (progressMonitor != null)
			progressMonitor.setCanceled(!success);
	}

	/**
	 * Presents an error dialog to the user when a problem happens during save.
	 * <p>
	 * Overrides the default behavior by showing a more advanced error dialog in case of encoding
	 * problems.
	 * </p>
	 * 
	 * @param title the dialog title
	 * @param message the message to display
	 * @param exception the exception to handle
	 * @since 3.6
	 */
	@Override
	protected void openSaveErrorDialog(String title, String message, CoreException exception) {
		IStatus status= exception.getStatus();
		final IDocumentProvider documentProvider= getDocumentProvider();
		if (!(status.getCode() == IFileBufferStatusCodes.CHARSET_MAPPING_FAILED && documentProvider instanceof IStorageDocumentProvider)) {
			super.openSaveErrorDialog(title, message, exception);
			return;
		}

		final int saveAsUTF8ButtonId= IDialogConstants.OK_ID + IDialogConstants.CANCEL_ID + 1;
		final int selectUnmappableCharButtonId= saveAsUTF8ButtonId + 1;
		final Charset charset= getCharset();
		
		ErrorDialog errorDialog= new ErrorDialog(getSite().getShell(), title, message, status, IStatus.ERROR) {

			@Override
			protected void createButtonsForButtonBar(Composite parent) {
				super.createButtonsForButtonBar(parent);
				createButton(parent, saveAsUTF8ButtonId, TextEditorMessages.AbstractDecoratedTextEditor_save_error_Dialog_button_saveAsUTF8, false);
				if (charset != null)
					createButton(parent, selectUnmappableCharButtonId, TextEditorMessages.AbstractDecoratedTextEditor_save_error_Dialog_button_selectUnmappable, false);
			}

			@Override
			protected void buttonPressed(int id) {
				if (id == saveAsUTF8ButtonId || id == selectUnmappableCharButtonId) {
					setReturnCode(id);
					close();
				} else
					super.buttonPressed(id);
			}

			@Override
			protected boolean shouldShowDetailsButton() {
				return false;
			}

		};

		int returnCode= errorDialog.open();

		if (returnCode == saveAsUTF8ButtonId) {
			((IStorageDocumentProvider)documentProvider).setEncoding(getEditorInput(), "UTF-8"); //$NON-NLS-1$
			IProgressMonitor monitor= getProgressMonitor();
			try {
				doSave(monitor);
			} finally {
				monitor.done();
			}
		} else if (returnCode == selectUnmappableCharButtonId) {
			CharsetEncoder encoder= charset.newEncoder();
			IDocument document= getDocumentProvider().getDocument(getEditorInput());
			int documentLength= document.getLength();
			int offset= 0;
			BreakIterator charBreakIterator= BreakIterator.getCharacterInstance();
			charBreakIterator.setText(document.get());
			while (offset < documentLength) {
				try {
					int next= charBreakIterator.next();
					String ch= document.get(offset, next - offset);
					if (!encoder.canEncode(ch)) {
						selectAndReveal(offset, next - offset);
						return;
					}
					offset= next;
				} catch (BadLocationException ex) {
					EditorsPlugin.log(ex);
					// Skip this character. Showing yet another dialog here is overkill
				}
			}
		}
	}


	/**
	 * Returns the charset of the current editor input.
	 * 
	 * @return the charset of the current editor input or <code>null</code> if it fails
	 * @since 3.6
	 */
	private Charset getCharset() {
		IEncodingSupport encodingSupport= getAdapter(IEncodingSupport.class);
		if (encodingSupport == null)
			return null;
		try {
			return Charset.forName(encodingSupport.getEncoding());
		} catch (UnsupportedCharsetException ex) {
			return null;
		} catch (IllegalCharsetNameException ex) {
			return null;
		}
	}

	/**
	 * Checks whether there given file store points
	 * to a file in the workspace. Only returns a
	 * workspace file if there's a single match.
	 *
	 * @param fileStore the file store
	 * @return the <code>IFile</code> that matches the given file store
	 * @since 3.2
	 */
	private IFile getWorkspaceFile(IFileStore fileStore) {
		IWorkspaceRoot workspaceRoot= ResourcesPlugin.getWorkspace().getRoot();
		IFile[] files= workspaceRoot.findFilesForLocationURI(fileStore.toURI());
		if (files != null && files.length == 1)
			return files[0];
		return null;
	}

	/**
	 * Sets the ruler's overview context menu id.
	 *
	 * @param contextMenuId the overview ruler context menu id
	 * @since 3.4
	 */
	protected void setOverviewRulerContextMenuId(String contextMenuId) {
		Assert.isNotNull(contextMenuId);
		fOverviewRulerContextMenuId= contextMenuId;
	}

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

	/**
	 * Sets up the overview ruler context menu before it is made visible.
	 * <p>
	 * Subclasses may extend to add other actions.
	 * </p>
	 *
	 * @param menu the menu
	 * @since 3.4
	 */
	protected void overviewRulerContextMenuAboutToShow(IMenuManager menu) {
		final String preferenceLabel= findSelectedOverviewRulerAnnotationLabel();
		final Shell shell= getSite().getShell();
		IAction action= new ResourceAction(TextEditorMessages.getBundleForConstructedKeys(), "Editor.RulerPreferencesAction.") { //$NON-NLS-1$

			@Override
			public void run() {
				String[] preferencePages= collectOverviewRulerMenuPreferencePages();
				if (preferencePages.length > 0 && (shell == null || !shell.isDisposed())) {
					PreferencesUtil.createPreferenceDialogOn(shell, preferencePages[0], preferencePages, preferenceLabel).open();
				}
			}
		};

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

	private String findSelectedOverviewRulerAnnotationLabel() {
		IAnnotationModel model= getSourceViewer().getAnnotationModel();
		if (model == null) {
			return null;
		}
		Point selection= getSourceViewer().getSelectedRange();
		Annotation annotation= null;
		Iterator<Annotation> iter= model.getAnnotationIterator();
		while (iter.hasNext()) {
			annotation= iter.next();
			Position p= model.getPosition(annotation);
			if (p.getOffset() == selection.x && p.getLength() == selection.y)
				break;
		}

		if (annotation != null) {
			AnnotationPreference ap= getAnnotationPreferenceLookup().getAnnotationPreference(annotation);
			if (ap != null)
				return ap.getPreferenceLabel();
		}

		return null;
	}

	@Override
	protected void rulerContextMenuAboutToShow(IMenuManager menu) {
		/*
		 * XXX: workaround for reliable menu item ordering.
		 * This can be changed once the action contribution story converges,
		 * see http://dev.eclipse.org/viewcvs/index.cgi/~checkout~/platform-ui-home/R3_1/dynamic_teams/dynamic_teams.html#actionContributions
		 */
		// pre-install menus for contributions and call super
		menu.add(new Separator("debug")); //$NON-NLS-1$
		menu.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
		menu.add(new GroupMarker(ITextEditorActionConstants.GROUP_RESTORE));
		menu.add(new Separator("add")); //$NON-NLS-1$
		menu.add(new Separator(ITextEditorActionConstants.GROUP_RULERS));
		menu.add(new Separator(ITextEditorActionConstants.GROUP_REST));

		super.rulerContextMenuAboutToShow(menu);

		addRulerContributionActions(menu);

		/* quick diff */
		if (isEditorInputModifiable()) {
			IAction quickdiffAction= getAction(ITextEditorActionConstants.QUICKDIFF_TOGGLE);
			quickdiffAction.setChecked(isChangeInformationShowing());
			menu.appendToGroup(ITextEditorActionConstants.GROUP_RULERS, quickdiffAction);

			if (isChangeInformationShowing()) {
				TextEditorAction revertLine= new RevertLineAction(this, true);
				TextEditorAction revertSelection= new RevertSelectionAction(this, true);
				TextEditorAction revertBlock= new RevertBlockAction(this, true);
				TextEditorAction revertDeletion= new RestoreAction(this, true);

				revertSelection.update();
				revertBlock.update();
				revertLine.update();
				revertDeletion.update();

				// only add block action if selection action is not enabled
				if (revertSelection.isEnabled())
					menu.appendToGroup(ITextEditorActionConstants.GROUP_RESTORE, revertSelection);
				else if (revertBlock.isEnabled())
					menu.appendToGroup(ITextEditorActionConstants.GROUP_RESTORE, revertBlock);
				if (revertLine.isEnabled())
					menu.appendToGroup(ITextEditorActionConstants.GROUP_RESTORE, revertLine);
				if (revertDeletion.isEnabled())
					menu.appendToGroup(ITextEditorActionConstants.GROUP_RESTORE, revertDeletion);
			}
		}

		// revision info
		if (fLineColumn != null && fLineColumn.isShowingRevisionInformation()) {
			IMenuManager revisionMenu= new MenuManager(TextEditorMessages.AbstractDecoratedTextEditor_revisions_menu);
			menu.appendToGroup(ITextEditorActionConstants.GROUP_RULERS, revisionMenu);

			IAction hideRevisionInfoAction= getAction(ITextEditorActionConstants.REVISION_HIDE_INFO);
			revisionMenu.add(hideRevisionInfoAction);
			revisionMenu.add(new Separator());

			String[] labels= { TextEditorMessages.AbstractDecoratedTextEditor_revision_colors_option_by_date, TextEditorMessages.AbstractDecoratedTextEditor_revision_colors_option_by_author, TextEditorMessages.AbstractDecoratedTextEditor_revision_colors_option_by_author_and_date };
			final RenderingMode[] modes= { IRevisionRulerColumnExtension.AGE, IRevisionRulerColumnExtension.AUTHOR, IRevisionRulerColumnExtension.AUTHOR_SHADED_BY_AGE};
			final IPreferenceStore uiStore= EditorsUI.getPreferenceStore();
			String current= uiStore.getString(AbstractDecoratedTextEditorPreferenceConstants.REVISION_RULER_RENDERING_MODE);
			for (int i= 0; i < modes.length; i++) {
				final String mode= modes[i].name();
				IAction action= new Action(labels[i], IAction.AS_RADIO_BUTTON) {
					@Override
					public void run() {
						// set preference globally, LineNumberColumn reacts on preference change
						uiStore.setValue(AbstractDecoratedTextEditorPreferenceConstants.REVISION_RULER_RENDERING_MODE, mode);
					}
				};
				action.setChecked(mode.equals(current));
				revisionMenu.add(action);
			}

			revisionMenu.add(new Separator());

			IAction action= getAction(ITextEditorActionConstants.REVISION_SHOW_AUTHOR_TOGGLE);
			if (action instanceof IUpdate)
				((IUpdate)action).update();
			revisionMenu.add(action);
			action= getAction(ITextEditorActionConstants.REVISION_SHOW_ID_TOGGLE);
			if (action instanceof IUpdate)
				((IUpdate)action).update();
			revisionMenu.add(action);
		}

		IAction lineNumberAction= getAction(ITextEditorActionConstants.LINENUMBERS_TOGGLE);
		lineNumberAction.setChecked(fLineColumn != null && fLineColumn.isShowingLineNumbers());
		menu.appendToGroup(ITextEditorActionConstants.GROUP_RULERS, lineNumberAction);

		IAction preferencesAction= getAction(ITextEditorActionConstants.RULER_PREFERENCES);
		menu.appendToGroup(ITextEditorActionConstants.GROUP_RULERS, new Separator(ITextEditorActionConstants.GROUP_SETTINGS));
		menu.appendToGroup(ITextEditorActionConstants.GROUP_SETTINGS, preferencesAction);
	}

	/**
	 * Adds "show" actions for all contributed rulers that support it.
	 *
	 * @param menu the ruler context menu
	 * @since 3.3
	 */
	private void addRulerContributionActions(IMenuManager menu) {
		// store directly in generic editor preferences
		final IColumnSupport support= getAdapter(IColumnSupport.class);
		IPreferenceStore store= EditorsUI.getPreferenceStore();
		final RulerColumnPreferenceAdapter adapter= new RulerColumnPreferenceAdapter(store, AbstractTextEditor.PREFERENCE_RULER_CONTRIBUTIONS);
		List<RulerColumnDescriptor> descriptors= RulerColumnRegistry.getDefault().getColumnDescriptors();
		for (Iterator<RulerColumnDescriptor> t= descriptors.iterator(); t.hasNext();) {
			final RulerColumnDescriptor descriptor= t.next();
			if (!descriptor.isIncludedInMenu() || !support.isColumnSupported(descriptor))
				continue;
			final boolean isVisible= support.isColumnVisible(descriptor);
			IAction action= new Action(MessageFormat.format(TextEditorMessages.AbstractDecoratedTextEditor_show_ruler_label, new Object[] {descriptor.getName()}), IAction.AS_CHECK_BOX) {
				@Override
				public void run() {
					if (descriptor.isGlobal())
						// column state is modified via preference listener of AbstractTextEditor
						adapter.setEnabled(descriptor, !isVisible);
					else
						// directly modify column for this editor instance
						support.setColumnVisible(descriptor, !isVisible);
				}
			};
			action.setChecked(isVisible);
			action.setImageDescriptor(descriptor.getIcon());
			menu.appendToGroup(ITextEditorActionConstants.GROUP_RULERS, action);
		}
	}

	/**
	 * Toggles the line number global preference and shows the line number ruler
	 * accordingly.
	 *
	 * @since 3.1
	 */
	private void toggleLineNumberRuler() {
		// globally
		IPreferenceStore store= EditorsUI.getPreferenceStore();
		store.setValue(LINE_NUMBER_RULER, !isLineNumberRulerVisible());
	}

	/**
	 * Toggles the quick diff global preference and shows the quick diff ruler
	 * accordingly.
	 *
	 * @since 3.1
	 */
	private void toggleQuickDiffRuler() {
		// change the visibility locally if this editor is not in sync with the global preference
		// toggle the preference if we are in sync.
		IPreferenceStore store= EditorsUI.getPreferenceStore();
		boolean current= store.getBoolean(AbstractDecoratedTextEditorPreferenceConstants.QUICK_DIFF_ALWAYS_ON);
		if (current == isChangeInformationShowing())
			store.setValue(AbstractDecoratedTextEditorPreferenceConstants.QUICK_DIFF_ALWAYS_ON, !current);
		else
			showChangeInformation(current);
	}

	@Override
	protected void editorContextMenuAboutToShow(IMenuManager menu) {
		super.editorContextMenuAboutToShow(menu);

		IAction preferencesAction= getAction(ITextEditorActionConstants.CONTEXT_PREFERENCES);
		menu.appendToGroup(IWorkbenchActionConstants.MB_ADDITIONS, new Separator(ITextEditorActionConstants.GROUP_SETTINGS));
		menu.appendToGroup(ITextEditorActionConstants.GROUP_SETTINGS, preferencesAction);

		menu.appendToGroup(ITextEditorActionConstants.GROUP_SAVE, new Separator(ITextEditorActionConstants.GROUP_OPEN));

		IEditorInput editorInput= getEditorInput();
		if ((editorInput.getAdapter(IResource.class)) instanceof IFile) {
			MenuManager openWithSubMenu= new MenuManager(TextEditorMessages.AbstractDecoratedTextEditor_openWith_menu);
			final IWorkbenchPage page= getEditorSite().getPage();

			// XXX: Internal reference will get fixed during 3.7, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=307026
			openWithSubMenu.add(new OpenWithMenu(page, editorInput) {
				@Override
				protected void openEditor(IEditorDescriptor editorDescriptor, boolean openUsingDescriptor) {
					super.openEditor(editorDescriptor, openUsingDescriptor);
					ISelection selection= getSelectionProvider().getSelection();
					if (selection instanceof ITextSelection) {
						revealInEditor(page.getActiveEditor(), ((ITextSelection)selection).getOffset(), ((ITextSelection)selection).getLength());
					}
				}
			});
			menu.appendToGroup(ITextEditorActionConstants.GROUP_OPEN, openWithSubMenu);
		}

		MenuManager showInSubMenu= new MenuManager(getShowInMenuLabel());
		showInSubMenu.add(ContributionItemFactory.VIEWS_SHOW_IN.create(getEditorSite().getWorkbenchWindow()));
		menu.appendToGroup(ITextEditorActionConstants.GROUP_OPEN, showInSubMenu);
	}

	/**
	 * Selects and reveals the given offset and length in the given editor part.
	 * 
	 * @param editor the editor part
	 * @param offset the offset
	 * @param length the length
	 * @since 3.7
	 */
	private static void revealInEditor(IEditorPart editor, final int offset, final int length) {
		if (editor instanceof ITextEditor) {
			((ITextEditor)editor).selectAndReveal(offset, length);
			return;
		}

		// Support for non-text editor - try IGotoMarker interface
		final IGotoMarker gotoMarkerTarget;
		if (editor instanceof IGotoMarker)
			gotoMarkerTarget= (IGotoMarker)editor;
		else
			gotoMarkerTarget= editor != null ? editor.getAdapter(IGotoMarker.class) : null;
		if (gotoMarkerTarget != null) {
			final IEditorInput input= editor.getEditorInput();
			if (input instanceof IFileEditorInput) {
				WorkspaceModifyOperation op= new WorkspaceModifyOperation() {
					@Override
					protected void execute(IProgressMonitor monitor) throws CoreException {
						IMarker marker= null;
						try {
							marker= ((IFileEditorInput)input).getFile().createMarker(IMarker.TEXT);
							marker.setAttribute(IMarker.CHAR_START, offset);
							marker.setAttribute(IMarker.CHAR_END, offset + length);

							gotoMarkerTarget.gotoMarker(marker);

						} finally {
							if (marker != null)
								marker.delete();
						}
					}
				};

				try {
					op.run(null);
				} catch (InvocationTargetException ex) {
					// reveal failed
				} catch (InterruptedException e) {
					Assert.isTrue(false, "this operation can not be canceled"); //$NON-NLS-1$
				}
			}
			return;
		}
	}

	/**
	 * Returns the menu label for 'Show In' together with its key binding string.
	 *
	 * @return the 'Show In' menu label
	 * @since 3.2
	 */
	private String getShowInMenuLabel() {
		String keyBinding= null;

		IBindingService bindingService= PlatformUI.getWorkbench().getAdapter(IBindingService.class);
		if (bindingService != null)
			keyBinding= bindingService.getBestActiveBindingFormattedFor(IWorkbenchCommandConstants.NAVIGATE_SHOW_IN_QUICK_MENU);

		if (keyBinding == null)
			keyBinding= ""; //$NON-NLS-1$

		return NLSUtility.format(TextEditorMessages.AbstractDecoratedTextEditor_showIn_menu, keyBinding);
	}

	/**
	 * Returns the preference page ids of the preference pages to be shown when executing the
	 * preferences action from the editor context menu. The first page will be selected.
	 * <p>
	 * Subclasses may extend or replace.
	 * </p>
	 * 
	 * @return the preference page ids to show, may be empty
	 * @since 3.1
	 */
	protected String[] collectContextMenuPreferencePages() {
		return new String[] { "org.eclipse.ui.preferencePages.GeneralTextEditor", //$NON-NLS-1$
				"org.eclipse.ui.editors.preferencePages.Annotations", //$NON-NLS-1$
				"org.eclipse.ui.editors.preferencePages.QuickDiff", //$NON-NLS-1$
				"org.eclipse.ui.editors.preferencePages.Accessibility", //$NON-NLS-1$
				"org.eclipse.ui.editors.preferencePages.Spelling", //$NON-NLS-1$
				"org.eclipse.ui.editors.preferencePages.LinkedModePreferencePage", //$NON-NLS-1$
				"org.eclipse.ui.preferencePages.ColorsAndFonts", //$NON-NLS-1$
		};
	}

	/**
	 * Returns the preference page ids of the preference pages to be shown when executing the
	 * preferences action from the editor ruler context menu. The first page will be selected.
	 * <p>
	 * The default is to return the same list as <code>collectContextMenuPreferencePages</code>.
	 * </p>
	 * <p>
	 * Subclasses may extend or replace.
	 * </p>
	 * 
	 * @return the preference page ids to show, may be empty
	 * @since 3.1
	 */
	protected String[] collectRulerMenuPreferencePages() {
		return collectContextMenuPreferencePages();
	}

	/**
	 * Returns the preference page ids of the preference pages to be shown when executing the
	 * preferences action from the editor overview ruler context menu. The first page will be
	 * selected.
	 * <p>
	 * The default is to select the 'Annotations' preference page.
	 * </p>
	 * <p>
	 * Subclasses may extend or replace.
	 * </p>
	 * 
	 * @return the preference page ids to show, may be empty
	 * @since 3.4
	 */
	protected String[] collectOverviewRulerMenuPreferencePages() {
		return new String[] { "org.eclipse.ui.editors.preferencePages.Annotations", //$NON-NLS-1$
				"org.eclipse.ui.preferencePages.GeneralTextEditor", //$NON-NLS-1$
				"org.eclipse.ui.editors.preferencePages.Accessibility", //$NON-NLS-1$
				"org.eclipse.ui.editors.preferencePages.QuickDiff", //$NON-NLS-1$
				"org.eclipse.ui.preferencePages.ColorsAndFonts" //$NON-NLS-1$
		};
	}

	@Override
	protected IOperationApprover getUndoRedoOperationApprover(IUndoContext undoContext) {
		IEditorInput input= getEditorInput();
		if (input != null && input.getAdapter(IResource.class) != null)
			return new NonLocalUndoUserApprover(undoContext, this, new Object [] { input }, IResource.class);
		return super.getUndoRedoOperationApprover(undoContext);
	}

	/**
	 * Returns whether the given annotation is configured as a target for the
	 * "Go to Next/Previous Annotation" actions.
	 * <p>
	 * The annotation is a target if their annotation type is configured to be
	 * in the Next/Previous tool bar drop down menu and if it is checked.
	 * </p>
	 *
	 * @param annotation the annotation
	 * @return <code>true</code> if this is a target, <code>false</code> otherwise
	 * @since 3.2
	 */
	@Override
	protected boolean isNavigationTarget(Annotation annotation) {
		AnnotationPreference preference= getAnnotationPreferenceLookup().getAnnotationPreference(annotation);
//		See bug 41689
//		String key= forward ? preference.getIsGoToNextNavigationTargetKey() : preference.getIsGoToPreviousNavigationTargetKey();
		String key= preference == null ? null : preference.getIsGoToNextNavigationTargetKey();
		return (key != null && getPreferenceStore().getBoolean(key));
	}

	/**
	 * {@inheritDoc}
	 * <p>
	 * This extended implementation updates views that also show the
	 * select marker annotation.
	 * </p>
	 * @since 3.2
	 */
	@Override
	public Annotation gotoAnnotation(boolean forward) {
		Annotation annotation= super.gotoAnnotation(forward);
		if (annotation != null)
			updateMarkerViews(annotation);
		return annotation;
	}

	/**
	 * Updates visible views that show markers.
	 * <p>
	 * If the given annotation can be associated with a marker then this method tries select the
	 * this marker in views that show markers.
	 * </p>
	 *
	 * @param annotation the annotation
	 * @since 3.2
	 */
	protected void updateMarkerViews(Annotation annotation) {
		if (fIsComingFromGotoMarker) {
			fIsComingFromGotoMarker= false;
			return;
		}

		IMarker marker= null;
		if (annotation instanceof MarkerAnnotation)
			marker= ((MarkerAnnotation)annotation).getMarker();

		if (marker != null) {
			try {
				fIsUpdatingMarkerViews= true;
				IWorkbenchPage page= getSite().getPage();
				MarkerViewUtil.showMarker(page, marker, false);
			} finally {
				fIsUpdatingMarkerViews= false;
			}
		}
	}

	/*
	 * @see org.eclipse.ui.texteditor.AbstractTextEditor#isTabConversionEnabled()
	 * @since 3.3
	 */
	@Override
	protected boolean isTabsToSpacesConversionEnabled() {
		return getPreferenceStore() != null && getPreferenceStore().getBoolean(AbstractDecoratedTextEditorPreferenceConstants.EDITOR_SPACES_FOR_TABS);
	}
}
