/*=============================================================================#
 # Copyright (c) 2005, 2021 Stephan Wahlbrink and others.
 # 
 # This program and the accompanying materials are made available under the
 # terms of the Eclipse Public License 2.0 which is available at
 # https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
 # which is available at https://www.apache.org/licenses/LICENSE-2.0.
 # 
 # SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
 # 
 # Contributors:
 #     Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
 #=============================================================================*/

package org.eclipse.statet.ltk.ui.sourceediting;

import static org.eclipse.statet.jcommons.lang.ObjectUtils.nonNullAssert;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.commands.IHandler2;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.content.IContentType;
import org.eclipse.core.runtime.preferences.IEclipsePreferences.IPreferenceChangeListener;
import org.eclipse.core.runtime.preferences.IEclipsePreferences.PreferenceChangeEvent;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IInformationControl;
import org.eclipse.jface.text.IInformationControlCreator;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ISynchronizable;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.text.ITextViewerExtension5;
import org.eclipse.jface.text.link.ILinkedModeListener;
import org.eclipse.jface.text.link.LinkedModeModel;
import org.eclipse.jface.text.source.IAnnotationModel;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.jface.text.source.IVerticalRuler;
import org.eclipse.jface.text.source.SourceViewer;
import org.eclipse.jface.text.source.projection.IProjectionListener;
import org.eclipse.jface.text.source.projection.ProjectionSupport;
import org.eclipse.jface.text.source.projection.ProjectionViewer;
import org.eclipse.jface.viewers.IPostSelectionProvider;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IPageLayout;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.contexts.IContextService;
import org.eclipse.ui.editors.text.TextEditor;
import org.eclipse.ui.handlers.IHandlerService;
import org.eclipse.ui.part.IShowInSource;
import org.eclipse.ui.part.IShowInTargetList;
import org.eclipse.ui.part.ShowInContext;
import org.eclipse.ui.services.IServiceLocator;
import org.eclipse.ui.texteditor.IDocumentProvider;
import org.eclipse.ui.texteditor.ITextEditorActionConstants;
import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds;
import org.eclipse.ui.texteditor.IUpdate;
import org.eclipse.ui.texteditor.SourceViewerDecorationSupport;
import org.eclipse.ui.texteditor.templates.ITemplatesPage;
import org.eclipse.ui.views.contentoutline.IContentOutlinePage;

import org.eclipse.statet.jcommons.collections.CopyOnWriteIdentityListSet;
import org.eclipse.statet.jcommons.collections.ImCollections;
import org.eclipse.statet.jcommons.collections.ImList;
import org.eclipse.statet.jcommons.lang.NonNull;
import org.eclipse.statet.jcommons.lang.NonNullByDefault;
import org.eclipse.statet.jcommons.lang.Nullable;
import org.eclipse.statet.jcommons.text.core.TextRegion;

import org.eclipse.statet.ecommons.preferences.PreferencesUtil;
import org.eclipse.statet.ecommons.preferences.SettingsChangeNotifier;
import org.eclipse.statet.ecommons.preferences.core.Preference;
import org.eclipse.statet.ecommons.preferences.core.util.PreferenceUtils;
import org.eclipse.statet.ecommons.text.ICharPairMatcher;
import org.eclipse.statet.ecommons.text.core.JFaceTextRegion;
import org.eclipse.statet.ecommons.text.core.sections.DocContentSections;
import org.eclipse.statet.ecommons.text.ui.TextHandlerUtil;
import org.eclipse.statet.ecommons.ui.ISettingsChangedHandler;
import org.eclipse.statet.ecommons.ui.util.UIAccess;

import org.eclipse.statet.internal.ltk.ui.EditingMessages;
import org.eclipse.statet.ltk.ast.core.AstNode;
import org.eclipse.statet.ltk.core.Ltk;
import org.eclipse.statet.ltk.model.core.DocumentModelProvider;
import org.eclipse.statet.ltk.model.core.ModelManager;
import org.eclipse.statet.ltk.model.core.ModelTypeDescriptor;
import org.eclipse.statet.ltk.model.core.element.LtkModelElement;
import org.eclipse.statet.ltk.model.core.element.SourceStructElement;
import org.eclipse.statet.ltk.model.core.element.SourceUnit;
import org.eclipse.statet.ltk.model.core.element.SourceUnitModelInfo;
import org.eclipse.statet.ltk.ui.ElementInfoController;
import org.eclipse.statet.ltk.ui.LTKInputData;
import org.eclipse.statet.ltk.ui.LtkActions;
import org.eclipse.statet.ltk.ui.ModelElementInputProvider;
import org.eclipse.statet.ltk.ui.PostSelectionCancelExtension;
import org.eclipse.statet.ltk.ui.PostSelectionWithElementInfoController;
import org.eclipse.statet.ltk.ui.PostSelectionWithElementInfoController.IgnoreActivation;
import org.eclipse.statet.ltk.ui.SelectionWithElementInfoListener;
import org.eclipse.statet.ltk.ui.sourceediting.actions.DeleteNextWordHandler;
import org.eclipse.statet.ltk.ui.sourceediting.actions.DeletePreviousWordHandler;
import org.eclipse.statet.ltk.ui.sourceediting.actions.GotoMatchingBracketHandler;
import org.eclipse.statet.ltk.ui.sourceediting.actions.GotoNextWordHandler;
import org.eclipse.statet.ltk.ui.sourceediting.actions.GotoPreviousWordHandler;
import org.eclipse.statet.ltk.ui.sourceediting.actions.SelectNextWordHandler;
import org.eclipse.statet.ltk.ui.sourceediting.actions.SelectPreviousWordHandler;
import org.eclipse.statet.ltk.ui.sourceediting.actions.SpecificContentAssistHandler;
import org.eclipse.statet.ltk.ui.sourceediting.actions.ToggleCommentHandler;
import org.eclipse.statet.ltk.ui.util.LTKSelectionUtils;


/**
 * Abstract LTK based source editor.
 */
@NonNullByDefault
public abstract class SourceEditor1 extends TextEditor implements SourceEditor,
			SettingsChangeNotifier.ChangeListener, IPreferenceChangeListener,
			IShowInSource, IShowInTargetList {
	
	
	protected static final ImList<String> ACTION_SET_CONTEXT_IDS= ImCollections.newIdentityList(
			"org.eclipse.statet.ltk.contexts.EditSource1MenuSet", //$NON-NLS-1$
			"org.eclipse.ui.edit.text.actionSet.presentation" ); //$NON-NLS-1$
	
	private static final ImList<String> CONTEXT_IDS= ImCollections.addElement(
			ACTION_SET_CONTEXT_IDS,
			"org.eclipse.statet.workbench.contexts.TextEditor" ); //$NON-NLS-1$
	
	
/*- Static utility methods --------------------------------------------------*/
	
	/**
	 * Returns the lock object for the given annotation model.
	 * 
	 * @param annotationModel the annotation model
	 * @return the annotation model's lock object
	 */
	protected static final Object getLockObject(final IAnnotationModel annotationModel) {
		if (annotationModel instanceof ISynchronizable) {
			final Object lock= ((ISynchronizable)annotationModel).getLockObject();
			if (lock != null) {
				return lock;
			}
		}
		return annotationModel;
	}
	
	private TextRegion expand(final TextRegion region, final @Nullable TextRegion regionOpt) {
		return (regionOpt != null) ? region.expansion(regionOpt) : region;
	}
	
	
/*- Inner classes -----------------------------------------------------------*/
	
	protected class PostSelectionEditorCancel extends PostSelectionCancelExtension {
		
		public PostSelectionEditorCancel() {
		}
		
		@Override
		public void init() {
			final ISourceViewer viewer= getSourceViewer();
			if (viewer != null) {
				viewer.addTextInputListener(this);
				viewer.getDocument().addDocumentListener(this);
			}
		}
		
		@Override
		public void dispose() {
			final ISourceViewer viewer= getSourceViewer();
			if (viewer != null) {
				viewer.removeTextInputListener(this);
				final IDocument document= viewer.getDocument();
				if (document != null) {
					document.removeDocumentListener(this);
				}
			}
		}
	}
	
	private class EffectSynchonizer implements TextEditToolSynchronizer, ILinkedModeListener {
		
		private EffectSynchonizer() {
		}
		
		@Override
		public void install(final LinkedModeModel model) {
			SourceEditor1.this.effectSynchonizerCounter++;
			
			final var markOccurrencesProvider= SourceEditor1.this.markOccurrencesProvider;
			if (markOccurrencesProvider != null) {
				markOccurrencesProvider.uninstall();
			}
			
			model.addLinkingListener(this);
		}
		
		@Override
		public void left(final LinkedModeModel model, final int flags) {
			SourceEditor1.this.effectSynchonizerCounter--;
			
			updateMarkOccurrencesEnablement();
		}
		
		@Override
		public void resume(final LinkedModeModel model, final int flags) {
		}
		
		@Override
		public void suspend(final LinkedModeModel model) {
		}
		
	}
	
	
/*- Fields -----------------------------------------------------------------*/
	
	private final IContentType contentType;
	private final ModelTypeDescriptor modelType;
	
	private SourceEditorViewerConfigurator configurator;
	private boolean lazySetup;
	private @Nullable SourceUnit sourceUnit;
	private ElementInfoController modelProvider;
	private @Nullable PostSelectionWithElementInfoController modelPostSelection;
	protected volatile Point currentSelection;
	
	/** The outline page of this editor */
	private @Nullable SourceEditor1OutlinePage outlinePage;
	
	/** The templates page of this editor */
	private @Nullable ITemplatesPage templatesPage;
	
	private StructureSelectionHistory selectionHistory;
	private @Nullable Preference<Boolean> foldingEnablement;
	private ProjectionSupport foldingSupport;
	private @Nullable SourceEditorAddon foldingProvider;
	private @Nullable FoldingActionGroup foldingActionGroup;
	private @Nullable Preference<Boolean> markOccurrencesEnablement;
	private @Nullable SourceEditorAddon markOccurrencesProvider;
	
	private @Nullable EffectSynchonizer effectSynchronizer;
	private int effectSynchonizerCounter;
	
	private final CopyOnWriteIdentityListSet<IUpdate> contentUpdateables= new CopyOnWriteIdentityListSet<>();
	private final CopyOnWriteIdentityListSet<IHandler2> stateUpdateables= new CopyOnWriteIdentityListSet<>();
	
	private boolean inputChange;
	private int inputUpdate= Integer.MAX_VALUE;
	
	private @Nullable ImageDescriptor imageDescriptor;
	
	
/*- Contructors ------------------------------------------------------------*/
	
	public SourceEditor1(final IContentType contentType) {
		super();
		this.contentType= contentType;
		this.modelType= Ltk.getExtContentTypeManager().getModelTypeForContentType(contentType.getId());
	}
	
	
/*- Methods ----------------------------------------------------------------*/
	
	@Override
	public IContentType getContentType() {
		return this.contentType;
	}
	
	/**
	 * Returns the model type of source units of the editor.
	 * The value must not change for an editor instance and all source units
	 * in the editor must be of the same type.
	 * 
	 * @return id of the model type
	 */
	public String getModelTypeId() {
		return this.modelType.getId();
	}
	
	@Override
	protected void initializeEditor() {
		this.configurator= createConfiguration();
		super.initializeEditor();
		setCompatibilityMode(false);
		final SourceEditorViewerConfiguration configuration= this.configurator.getSourceViewerConfiguration();
		setPreferenceStore(configuration.getPreferences());
		setSourceViewerConfiguration(configuration);
		if (configuration.isSmartInsertSupported()) {
			configureInsertMode(SMART_INSERT, true);
		}
		
		PreferencesUtil.getSettingsChangeNotifier().addChangeListener(this);
	}
	
	protected abstract SourceEditorViewerConfigurator createConfiguration();
	
	protected @Nullable SourceEditorViewerConfigurator createInfoConfigurator() {
		return null;
	}
	
	
	protected void enableStructuralFeatures(final ModelManager modelManager,
			final @Nullable Preference<Boolean> codeFoldingEnablement,
			final @Nullable Preference<Boolean> markOccurrencesEnablement) {
		this.modelProvider= new ElementInfoController(modelManager, Ltk.EDITOR_CONTEXT);
		this.foldingEnablement= codeFoldingEnablement;
		this.markOccurrencesEnablement= markOccurrencesEnablement;
	}
	
	/**
	 * Overwrites the default title image (editor icon) during the initialization of the editor
	 * input.
	 * 
	 * The image is created and disposed automatically.
	 * 
	 * For example, it can be used to overwrite the default image using the image descriptor of 
	 * the editor input in {@link #setDocumentProvider(IEditorInput)}
	 * 
	 * @param descriptor the image description of the icon or <code>null</code>
	 */
	protected void overwriteTitleImage(final @Nullable ImageDescriptor descriptor) {
		final var oldDescriptor= this.imageDescriptor;
		if (oldDescriptor == descriptor) {
			return;
		}
		if (oldDescriptor != null) {
			JFaceResources.getResources().destroyImage(oldDescriptor);
		}
		this.imageDescriptor= descriptor;
		if (descriptor != null) {
			super.setTitleImage(JFaceResources.getResources().createImage(descriptor));
		}
	}
	
	@Override
	protected void setTitleImage(final @Nullable Image titleImage) {
		if (this.imageDescriptor == null) {
			super.setTitleImage(titleImage);
		}
	}
	
	protected Collection<String> getContextIds() {
		return CONTEXT_IDS;
	}
	
	@Override
	protected void initializeKeyBindingScopes() {
		final Collection<String> ids= getContextIds();
		setKeyBindingScopes(ids.toArray(new String[ids.size()]));
	}
	
	@Override
	protected @NonNull String[] collectContextMenuPreferencePages() {
		final List<String> list= new ArrayList<>();
		collectContextMenuPreferencePages(list);
		list.addAll(ImCollections.newList(super.collectContextMenuPreferencePages()));
		return list.toArray(new @NonNull String[list.size()]);
	}
	
	protected void collectContextMenuPreferencePages(final List<String> pageIds) {
	}
	
	
	@Override
	protected void doSetInput(final @Nullable IEditorInput input) throws CoreException {
		if (this.modelProvider != null && this.sourceUnit != null) {
			this.modelProvider.setInput(null);
		}
		
		// project has changed
		final ISourceViewer sourceViewer= getSourceViewer();
		if (sourceViewer != null) {
			this.configurator.unconfigureTarget();
		}
		else {
			this.lazySetup= true;
		}
		
		this.inputChange= true;
		this.inputUpdate= 1;
		super.doSetInput(input);
		// setup in 
		//   1) setDocumentProvider -> setupConfiguration(..., input)
		//   2) handleInsertModeChanged -> setupConfiguration(..., input, SourceViewer)
		this.inputChange= false;
		this.inputUpdate= Integer.MAX_VALUE;
		
		initSmartInsert();
		
		if (input != null) {
			final var outlinePage= this.outlinePage;
			if (outlinePage != null) {
				updateOutlinePageInput(outlinePage);
			}
		}
	}
	
	private void initSmartInsert() {
		final SourceEditorViewerConfiguration config= this.configurator.getSourceViewerConfiguration();
		if (config.isSmartInsertSupported()) {
			if (config.isSmartInsertByDefault()) {
				setInsertMode(SMART_INSERT);
			}
			else {
				setInsertMode(INSERT);
			}
		}
	}
	
	@Override
	protected void setPartName(final String partName) {
		super.setPartName(partName);
		
		// see doSetInput
		if (this.inputChange) {
			if (this.inputUpdate != 1) {
				return;
			}
			this.inputUpdate= 2;
			final IEditorInput input= getEditorInput();
			setupConfiguration(input);
		}
	}
	
	@Override
	protected void handleInsertModeChanged() {
		// see doSetInput
		if (this.inputChange && !this.lazySetup) {
			if (this.inputUpdate != 2) {
				return;
			}
			this.inputUpdate= 3;
			final IEditorInput input= getEditorInput();
			final ISourceViewer sourceViewer= getSourceViewer();
			if (input != null && sourceViewer != null) {
				setupConfiguration(input, sourceViewer);
				this.configurator.configureTarget();
			}
			this.inputChange= false;
		}
		
		super.handleInsertModeChanged();
	}
	
	/**
	 * Subclasses should setup the SourceViewerConfiguration.
	 */
	protected void setupConfiguration(final @Nullable IEditorInput newInput) {
		final IDocumentProvider documentProvider= getDocumentProvider();
		if (documentProvider instanceof DocumentModelProvider) {
			this.sourceUnit= (newInput != null) ?
					((DocumentModelProvider)documentProvider).getWorkingCopy(newInput) :
					null;
			if (this.modelProvider != null) {
				this.modelProvider.setInput(this.sourceUnit);
			}
		}
	}
	
	/**
	 * Subclasses should setup the SourceViewerConfiguration.
	 */
	protected void setupConfiguration(final IEditorInput newInput, final ISourceViewer sourceViewer) {
		updateStateDependentActions();
	}
	
	@Override
	public @Nullable SourceUnit getSourceUnit() {
		return this.sourceUnit;
	}
	
	
	@Override
	public SourceViewer getViewer() {
		return (SourceViewer)super.getSourceViewer();
	}
	
	@Override
	public DocContentSections getDocumentContentInfo() {
		return this.configurator.getDocumentContentInfo();
	}
	
	@Override
	public IWorkbenchPart getWorkbenchPart() {
		return this;
	}
	
	@Override
	public IServiceLocator getServiceLocator() {
		return getSite();
	}
	
	@Override
	public boolean isEditable(final boolean validate) {
		if (validate) {
			return SourceEditor1.this.validateEditorInputState();
		}
		return SourceEditor1.this.isEditorInputModifiable();
	}
	
	public ModelElementInputProvider getModelInputProvider() {
		return this.modelProvider;
	}
	
	public void addPostSelectionWithElementInfoListener(final SelectionWithElementInfoListener listener) {
		final var modelPostSelection= this.modelPostSelection;
		if (modelPostSelection != null) {
			modelPostSelection.addListener(listener);
		}
	}
	
	public void removePostSelectionWithElementInfoListener(final SelectionWithElementInfoListener listener) {
		final var modelPostSelection= this.modelPostSelection;
		if (modelPostSelection != null) {
			modelPostSelection.removeListener(listener);
		}
	}
	
	
	@Override
	public void createPartControl(final Composite parent) {
		super.createPartControl(parent);
		
		if (this.modelProvider != null) {
			final var modelPostSelection= new PostSelectionWithElementInfoController(
					this.modelProvider, (IPostSelectionProvider)getSelectionProvider(),
					new PostSelectionEditorCancel() );
			modelPostSelection.addListener(new SelectionWithElementInfoListener() {
				@Override
				public void inputChanged() {
				}
				@Override
				public void stateChanged(final LTKInputData state) {
					final TextRegion toHighlight= getRangeToHighlight(state);
					if (toHighlight != null) {
						setHighlightRange(toHighlight.getStartOffset(), toHighlight.getLength(), false);
					}
					else {
						resetHighlightRange();
					}
				}
			});
			this.modelPostSelection= modelPostSelection;
		}
		if (this.foldingEnablement != null) {
			final ProjectionViewer viewer= (ProjectionViewer)getSourceViewer();
			
			this.foldingSupport= new ProjectionSupport(viewer, getAnnotationAccess(), getSharedColors());
			final SourceEditorViewerConfigurator config= createInfoConfigurator();
			if (config != null) {
				final IInformationControlCreator presentationCreator= new IInformationControlCreator() {
					@Override
					public IInformationControl createInformationControl(final Shell parent) {
						return new SourceViewerInformationControl(parent,
								createInfoConfigurator(), getOrientation() );
					}
				};
				this.foldingSupport.setHoverControlCreator(new IInformationControlCreator() {
					@Override
					public IInformationControl createInformationControl(final Shell parent) {
						return new SourceViewerInformationControl(parent,
								createInfoConfigurator(), getOrientation(), presentationCreator );
					}
				});
				this.foldingSupport.setInformationPresenterControlCreator(presentationCreator);
			}
			this.foldingSupport.install();
			viewer.addProjectionListener(new IProjectionListener() {
				@Override
				public void projectionEnabled() {
					installFoldingProvider();
				}
				@Override
				public void projectionDisabled() {
					uninstallFoldingProvider();
				}
			});
			PreferenceUtils.getInstancePrefs().addPreferenceNodeListener(
					this.foldingEnablement.getQualifier(), this);
			updateFoldingEnablement();
		}
		if (this.markOccurrencesEnablement != null) {
			PreferenceUtils.getInstancePrefs().addPreferenceNodeListener(
					this.markOccurrencesEnablement.getQualifier(), this);
			updateMarkOccurrencesEnablement();
		}
		
		if (this.lazySetup) {
			this.lazySetup= false;
			setupConfiguration(getEditorInput(), getSourceViewer());
			this.configurator.setTarget(this);
		}
		
		{	final IContextService contextService= nonNullAssert(
					getServiceLocator().getService(IContextService.class) );
			for (final String id : getContextIds()) {
				contextService.activateContext(id);
			}
		}
	}
	
	@Override
	protected ISourceViewer createSourceViewer(final Composite parent, final IVerticalRuler ruler, final int styles) {
		this.fAnnotationAccess= getAnnotationAccess();
		this.fOverviewRuler= createOverviewRuler(getSharedColors());
		
		final ISourceViewer viewer= new SourceEditorViewer(parent,
				ruler, getOverviewRuler(), isOverviewRulerVisible(), styles,
				getSourceViewerFlags() );
		// ensure decoration support has been created and configured.
		getSourceViewerDecorationSupport(viewer);
		
		return viewer;
	}
	
	protected int getSourceViewerFlags() {
		return 0;
	}
	
	protected @Nullable IRegion getRangeToReveal(final SourceUnitModelInfo modelInfo,
			final SourceStructElement<?, ?> element) {
		return null;
	}
	
	protected @Nullable TextRegion getRangeToHighlight(final LTKInputData state) {
		final SourceUnitModelInfo info= state.getInputInfo();
		if (info == null) {
			return null;
		}
		
		final TextRegion region= getRangeToHighlight(info, state.getModelSelection());
		if (region != null) {
			return region;
		}
		
		final AstNode root= info.getAst().getRoot();
		TRY_AST: if (root != null) {
			final ITextSelection selection= (ITextSelection)state.getSelection();
			final int n= root.getChildCount();
			for (int i= 0; i < n; i++) {
				final AstNode child= root.getChild(i);
				if (selection.getOffset() >= child.getStartOffset()) {
					if (selection.getOffset()+selection.getLength() <= child.getEndOffset()) {
						return child;
					}
				}
				else {
					break TRY_AST;
				}
			}
		}
		return null;
	}
	
	protected @Nullable TextRegion getRangeToHighlight(final SourceUnitModelInfo info,
			@Nullable SourceStructElement element) {
		while (element != null) {
			switch (element.getElementType() & LtkModelElement.MASK_C1) {
			case LtkModelElement.C1_CLASS:
			case LtkModelElement.C1_METHOD:
				return expand(element.getSourceRange(), element.getDocumentationRange());
			case LtkModelElement.C1_SOURCE:
				if ((element.getElementType() & LtkModelElement.MASK_C2) == LtkModelElement.C2_SOURCE_CHUNK) {
					return expand(element.getSourceRange(), element.getDocumentationRange());
				}
				return null;
			case LtkModelElement.C1_VARIABLE:
				if ((element.getSourceParent().getElementType() & LtkModelElement.MASK_C2) == LtkModelElement.C2_SOURCE_FILE) {
					return expand(element.getSourceRange(), element.getDocumentationRange());
				}
				//$FALL-THROUGH$
			default:
				element= element.getSourceParent();
				continue;
			}
		}
		return null;
	}
	
	
	protected @Nullable SourceEditorAddon createCodeFoldingProvider() {
		return null;
	}
	
	private void installFoldingProvider() {
		uninstallFoldingProvider();
		final var foldingProvider= createCodeFoldingProvider();
		if (foldingProvider != null) {
			foldingProvider.install(this);
			this.foldingProvider= foldingProvider;
		}
	}
	
	private void uninstallFoldingProvider() {
		final var foldingProvider= this.foldingProvider;
		if (foldingProvider != null) {
			this.foldingProvider= null;
			foldingProvider.uninstall();
		}
	}
	
	private void updateFoldingEnablement() {
		if (this.foldingEnablement != null) {
			UIAccess.getDisplay().asyncExec(new Runnable() {
				@Override
				public void run() {
					final Boolean enable= PreferenceUtils.getInstancePrefs().getPreferenceValue(
							SourceEditor1.this.foldingEnablement );
					final ProjectionViewer viewer= (ProjectionViewer)getSourceViewer();
					if (enable != null && UIAccess.isOkToUse(viewer)) {
						if (enable != viewer.isProjectionMode()) {
							viewer.doOperation(ProjectionViewer.TOGGLE);
						}
					}
				}
			});
		}
	}
	
	
	protected @Nullable SourceEditorAddon createMarkOccurrencesProvider() {
		return null;
	}
	
	private void uninstallMarkOccurrencesProvider() {
		final var markOccurrencesProvider= this.markOccurrencesProvider;
		if (markOccurrencesProvider != null) {
			this.markOccurrencesProvider= null;
			markOccurrencesProvider.uninstall();
		}
	}
	
	private void updateMarkOccurrencesEnablement() {
		if (this.markOccurrencesEnablement != null) {
			UIAccess.getDisplay().asyncExec(new Runnable() {
				@Override
				public void run() {
					final Boolean enable= PreferenceUtils.getInstancePrefs().getPreferenceValue(
							SourceEditor1.this.markOccurrencesEnablement );
					if (enable) {
						var provider= SourceEditor1.this.markOccurrencesProvider;
						if (provider == null) {
							provider= createMarkOccurrencesProvider();
							SourceEditor1.this.markOccurrencesProvider= provider;
						}
						if (provider != null && SourceEditor1.this.effectSynchonizerCounter == 0) {
							provider.install(SourceEditor1.this);
						}
					}
					else {
						uninstallMarkOccurrencesProvider();
					}
				}
			});
		}
	}
	
	
	@Override
	protected void configureSourceViewerDecorationSupport(final SourceViewerDecorationSupport support) {
		super.configureSourceViewerDecorationSupport(support);
		this.configurator.configureSourceViewerDecorationSupport(support);
	}
	
	@Override
	protected void createActions() {
		super.createActions();
		final IHandlerService handlerService= nonNullAssert(
				getServiceLocator().getService(IHandlerService.class) );
		final StyledText textWidget= getViewer().getTextWidget();
		
		{	final IHandler2 handler= new GotoNextWordHandler(this);
			setAction(ITextEditorActionDefinitionIds.WORD_NEXT, null);
			TextHandlerUtil.disable(textWidget, ITextEditorActionDefinitionIds.WORD_NEXT);
			handlerService.activateHandler(ITextEditorActionDefinitionIds.WORD_NEXT, handler);
		}
		{	final IHandler2 handler= new GotoPreviousWordHandler(this);
			setAction(ITextEditorActionDefinitionIds.WORD_PREVIOUS, null);
			TextHandlerUtil.disable(textWidget, ITextEditorActionDefinitionIds.WORD_NEXT);
			handlerService.activateHandler(ITextEditorActionDefinitionIds.WORD_PREVIOUS, handler);
		}
		{	final IHandler2 handler= new SelectNextWordHandler(this);
			setAction(ITextEditorActionDefinitionIds.SELECT_WORD_NEXT, null);
			TextHandlerUtil.disable(textWidget, ITextEditorActionDefinitionIds.SELECT_WORD_NEXT);
			handlerService.activateHandler(ITextEditorActionDefinitionIds.SELECT_WORD_NEXT, handler);
		}
		{	final IHandler2 handler= new SelectPreviousWordHandler(this);
			setAction(ITextEditorActionDefinitionIds.SELECT_WORD_PREVIOUS, null);
			TextHandlerUtil.disable(textWidget, ITextEditorActionDefinitionIds.SELECT_WORD_PREVIOUS);
			handlerService.activateHandler(ITextEditorActionDefinitionIds.SELECT_WORD_PREVIOUS, handler);
		}
		{	final IHandler2 handler= new DeleteNextWordHandler(this);
			setAction(ITextEditorActionDefinitionIds.DELETE_NEXT_WORD, null);
			TextHandlerUtil.disable(textWidget, ITextEditorActionDefinitionIds.DELETE_NEXT_WORD);
			handlerService.activateHandler(ITextEditorActionDefinitionIds.DELETE_NEXT_WORD, handler);
			markAsStateDependentHandler(handler, true);
		}
		{	final IHandler2 handler= new DeletePreviousWordHandler(this);
			setAction(ITextEditorActionDefinitionIds.DELETE_PREVIOUS_WORD, null);
			TextHandlerUtil.disable(textWidget, ITextEditorActionDefinitionIds.DELETE_PREVIOUS_WORD);
			handlerService.activateHandler(ITextEditorActionDefinitionIds.DELETE_PREVIOUS_WORD, handler);
			markAsStateDependentHandler(handler, true);
		}
		
		final ICharPairMatcher matcher= this.configurator.getSourceViewerConfiguration().getPairMatcher();
		if (matcher != null) {
			handlerService.activateHandler(LtkActions.GOTO_MATCHING_BRACKET_COMMAND_ID,
					new GotoMatchingBracketHandler(matcher, this));
		}
		{	final IHandler2 handler= new SpecificContentAssistHandler(this,
					this.configurator.getSourceViewerConfiguration().getContentAssist() );
			handlerService.activateHandler(LtkActions.SPECIFIC_CONTENT_ASSIST_COMMAND_ID, handler);
		}
		
		{	final IHandler2 handler= createToggleCommentHandler();
			if (handler != null) {
				handlerService.activateHandler(LtkActions.TOGGLE_COMMENT, handler);
			}
		}
		{	final IHandler2 handler= createCorrectIndentHandler();
			if (handler != null) {
				handlerService.activateHandler(LtkActions.CORRECT_INDENT_COMMAND_ID, handler);
			}
		}
		
		if (this.foldingEnablement != null) {
			this.foldingActionGroup= createFoldingActionGroup();
		}
		if (this.modelProvider != null) {
			this.selectionHistory= new StructureSelectionHistory(this);
			handlerService.activateHandler(LtkActions.SELECT_ENCLOSING_COMMAND_ID,
					new StructureSelectHandler.Enclosing(this, this.selectionHistory));
			handlerService.activateHandler(LtkActions.SELECT_PREVIOUS_COMMAND_ID,
					new StructureSelectHandler.Previous(this, this.selectionHistory));
			handlerService.activateHandler(LtkActions.SELECT_NEXT_COMMAND_ID,
					new StructureSelectHandler.Next(this, this.selectionHistory));
			final StructureSelectionHistoryBackHandler backHandler= new StructureSelectionHistoryBackHandler(this, this.selectionHistory);
			handlerService.activateHandler(LtkActions.SELECT_LAST_COMMAND_ID, backHandler);
			this.selectionHistory.addUpdateListener(backHandler);
		}
		
		//WorkbenchHelp.setHelp(action, IJavaHelpContextIds.TOGGLE_COMMENT_ACTION);
	}
	
	protected FoldingActionGroup createFoldingActionGroup() {
		return new FoldingActionGroup(this, (ProjectionViewer)getSourceViewer());
	}
	
	protected @Nullable IHandler2 createToggleCommentHandler() {
		final IHandler2 commentHandler= new ToggleCommentHandler(this);
		markAsStateDependentHandler(commentHandler, true);
		return commentHandler;
	}
	
	protected @Nullable IHandler2 createCorrectIndentHandler() {
		return null;
	}
	
	protected void markAsContentDependentHandler(final IUpdate handler, final boolean mark) {
		if (mark) {
			this.contentUpdateables.add(handler);
		}
		else {
			this.contentUpdateables.remove(handler);
		}
	}
	
	protected void markAsStateDependentHandler(final IHandler2 handler, final boolean mark) {
		if (mark) {
			this.stateUpdateables.add(handler);
		}
		else {
			this.stateUpdateables.remove(handler);
		}
	}
	
	@Override
	protected void updateContentDependentActions() {
		super.updateContentDependentActions();
		for (final IUpdate handler : this.contentUpdateables) {
			handler.update();
		}
	}
	
	@Override
	protected void updateStateDependentActions() {
		super.updateStateDependentActions();
		for (final IHandler2 handler : this.stateUpdateables) {
			handler.setEnabled(this);
		}
	}
	
	@Override
	protected void rulerContextMenuAboutToShow(final IMenuManager menu) {
		super.rulerContextMenuAboutToShow(menu);
		
		final var foldingActionGroup= this.foldingActionGroup;
		if (foldingActionGroup != null) {
			final IMenuManager foldingMenu= new MenuManager(EditingMessages.CodeFolding_label, "projection"); //$NON-NLS-1$
			menu.appendToGroup(ITextEditorActionConstants.GROUP_RULERS, foldingMenu);
			foldingActionGroup.fillMenu(foldingMenu);
		}
	}
	
	
	@Override
	public TextEditToolSynchronizer getTextEditToolSynchronizer() {
		var effectSynchronizer= this.effectSynchronizer;
		if (effectSynchronizer == null) {
			effectSynchronizer= new EffectSynchonizer();
			this.effectSynchronizer= effectSynchronizer;
		}
		return effectSynchronizer;
	}
	
	@Override
	@SuppressWarnings("unchecked")
	public <T> @Nullable T getAdapter(final Class<T> adapterType) {
		if (adapterType == SourceEditor.class) {
			return (T)this;
		}
		if (adapterType == ISourceViewer.class) {
			return (T)getSourceViewer();
		}
		
		if (adapterType == IContentType.class) {
			return (T)this.contentType;
		}
		
		if (adapterType == IContentOutlinePage.class) {
			var outlinePage= this.outlinePage;
			if (outlinePage == null) {
				outlinePage= createOutlinePage();
				if (outlinePage != null) {
					updateOutlinePageInput(outlinePage);
				}
				this.outlinePage= outlinePage;
			}
			return (T)outlinePage;
		}
		if (adapterType == ITemplatesPage.class) {
			var templatesPage= this.templatesPage;
			if (templatesPage == null) {
				templatesPage= createTemplatesPage();
				this.templatesPage= templatesPage;
			}
			return (T)templatesPage;
		}
		if (this.foldingSupport != null) {
			final Object adapter= this.foldingSupport.getAdapter(getSourceViewer(), adapterType);
			if (adapter != null) {
				return (T)adapter;
			}
		}
		
		return super.getAdapter(adapterType);
	}
	
	
	@Override
	public void settingsChanged(final Set<String> groupIds) {
		final Map<String, Object> options= new HashMap<>();
		UIAccess.getDisplay().syncExec(new Runnable() {
			@Override
			public void run() {
				handleSettingsChanged(groupIds, options);
			}
		});
	}
	
	/**
	 * @see ISettingsChangedHandler#handleSettingsChanged(Set, Map)
	 */
	protected void handleSettingsChanged(final Set<String> groupIds, final Map<String, Object> options) {
		if (this.configurator != null) {
			this.configurator.handleSettingsChanged(groupIds, options);
		}
	}
	
	@Override
	public void preferenceChange(final PreferenceChangeEvent event) {
		if (this.foldingEnablement != null && event.getKey().equals(this.foldingEnablement.getKey())) {
			updateFoldingEnablement();
		}
		if (this.markOccurrencesEnablement != null && event.getKey().equals(this.markOccurrencesEnablement.getKey())) {
			updateMarkOccurrencesEnablement();
		}
	}
	
	protected void updateIndentSettings() {
		updateIndentPrefixes();
	}
	
	
	@Override
	protected void handleCursorPositionChanged() {
		this.currentSelection= getSourceViewer().getSelectedRange();
		super.handleCursorPositionChanged();
	}
	
	
	protected @Nullable SourceEditor1OutlinePage createOutlinePage() {
		return null;
	}
	
	protected void updateOutlinePageInput(final SourceEditor1OutlinePage page) {
	}
	
	void handleOutlinePageClosed() {
		final var outlinePage= this.outlinePage;
		if (outlinePage != null) {
			this.outlinePage= null;
			resetHighlightRange();
		}
	}
	
	protected @Nullable ITemplatesPage createTemplatesPage() {
		return null;
	}
	
	
	// inject annotation painter workaround
	@Override
	protected SourceViewerDecorationSupport getSourceViewerDecorationSupport(final ISourceViewer viewer) {
		var decorationSupport= this.fSourceViewerDecorationSupport;
		if (decorationSupport == null) {
			decorationSupport= new org.eclipse.statet.ltk.ui.sourceediting.SourceViewerDecorationSupport(
					viewer, getOverviewRuler(), getAnnotationAccess(), getSharedColors() );
			configureSourceViewerDecorationSupport(decorationSupport);
			this.fSourceViewerDecorationSupport= decorationSupport;
		}
		return decorationSupport;
	}
	
	@Override
	public void selectAndReveal(final int start, final int length) {
		selectAndReveal(start, length, start, length);
	}
	
	@Override
	protected void selectAndReveal(final int selectionStart, final int selectionLength,
			final int revealStart, final int revealLength) {
		final var modelPostSelection= this.modelPostSelection;
		if (modelPostSelection != null) {
			modelPostSelection.setUpdateOnSelection(true);
			try {
				super.selectAndReveal(selectionStart, selectionLength, revealStart, revealLength);
			}
			finally {
				modelPostSelection.setUpdateOnSelection(false);
			}
		}
		else {
			super.selectAndReveal(selectionStart, selectionLength, revealStart, revealLength);
		}
	}
	
	public void setSelection(final ISelection selection, final SelectionWithElementInfoListener listener) {
		final var modelPostSelection= this.modelPostSelection;
		if (modelPostSelection != null && listener != null) {
			final IgnoreActivation activation= modelPostSelection.ignoreNext(listener);
			doSetSelection(selection);
			activation.deleteNext();
		}
		else {
			doSetSelection(selection);
		}
	}
	
	@Override
	protected void doSetSelection(final ISelection selection) {
		if (selection instanceof IStructuredSelection) {
			final IStructuredSelection structured= (IStructuredSelection)selection;
			if (!structured.isEmpty()) {
				final Object first= structured.getFirstElement();
				TextRegion region= null;
				if (first instanceof SourceStructElement) {
					final var sourceElement= (SourceStructElement<?, ?>)first;
					region= LTKSelectionUtils.getRegionToSelect(sourceElement);
					
					final var sourceUnit= sourceElement.getSourceUnit();
					final var modelInfo= sourceUnit.getModelInfo(getModelTypeId(), 0, null);
					if (modelInfo != null) {
						final IRegion toReveal= getRangeToReveal(modelInfo, sourceElement);
						if (toReveal != null) {
							final SourceViewer viewer= getViewer();
							if (viewer instanceof ITextViewerExtension5) {
								((ITextViewerExtension5)viewer).exposeModelRange(toReveal);
							}
							getViewer().revealRange(toReveal.getOffset(), toReveal.getLength());
						}
						final TextRegion toHighlight= getRangeToHighlight(modelInfo, sourceElement);
						if (toHighlight != null) {
							setHighlightRange(toHighlight.getStartOffset(), toHighlight.getLength(), true);
						}
					}
				}
				if (region == null && first instanceof TextRegion) {
					region= (TextRegion)first;
				}
				else if (region == null && first instanceof IRegion) {
					region= JFaceTextRegion.toTextRegion((IRegion)first);
				}
				
				if (region != null) {
					selectAndReveal(region.getStartOffset(), region.getLength());
					return;
				}
			}
		}
		super.doSetSelection(selection);
	}
	
	
	@Override
	public void dispose() {
		if (this.modelProvider != null) {
			this.modelProvider.setInput(null);
			this.modelProvider.dispose();
		}
		
		PreferencesUtil.getSettingsChangeNotifier().removeChangeListener(this);
		{	final var modelPostSelection= this.modelPostSelection;
			if (modelPostSelection != null) {
				this.modelPostSelection= null;
				modelPostSelection.dispose();
			}
		}
		{	final var foldingEnablement= this.foldingEnablement;
			if (foldingEnablement != null) {
				PreferenceUtils.getInstancePrefs().removePreferenceNodeListener(
						foldingEnablement.getQualifier(), this );
				uninstallFoldingProvider();
		}
		}
		{	final var markOccurrencesEnablement= this.markOccurrencesEnablement;
			if (markOccurrencesEnablement != null) {
				PreferenceUtils.getInstancePrefs().removePreferenceNodeListener(
						markOccurrencesEnablement.getQualifier(), this );
				uninstallMarkOccurrencesProvider();
			}
		}
		
		super.dispose();
		
		if (this.imageDescriptor != null) {
			JFaceResources.getResources().destroyImage(this.imageDescriptor);
			this.imageDescriptor= null;
		}
		
		this.sourceUnit= null;
		this.modelProvider= null;
	}
	
	@Override
	public ShowInContext getShowInContext() {
		final Point selectionPoint= this.currentSelection;
		final ISourceViewer sourceViewer= getSourceViewer();
		final SourceUnit unit= getSourceUnit();
		ISelection selection= null;
		if (selectionPoint != null && unit != null && sourceViewer != null) {
			selection= new LTKInputData(unit, getSelectionProvider());
		}
		return new ShowInContext(getEditorInput(), selection);
	}
	
	@Override
	public @NonNull String[] getShowInTargetIds() {
		return new @NonNull String[] {
			IPageLayout.ID_PROJECT_EXPLORER };
	}
	
}
