/*******************************************************************************
 * Copyright (c) 2001, 2004 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
 *     Jens Lukowski/Innoopract - initial renaming/restructuring
 *     
 *******************************************************************************/
package org.eclipse.wst.sse.ui;

import java.io.IOException;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.ResourceBundle;
import java.util.Timer;
import java.util.TimerTask;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IStorage;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.ILog;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Preferences;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.ui.actions.IToggleBreakpointsTarget;
import org.eclipse.emf.common.command.Command;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.GroupMarker;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IStatusLineManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.text.DefaultInformationControl;
import org.eclipse.jface.text.DocumentEvent;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IDocumentListener;
import org.eclipse.jface.text.IInformationControl;
import org.eclipse.jface.text.IInformationControlCreator;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextHover;
import org.eclipse.jface.text.ITextOperationTarget;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.ITextViewerExtension;
import org.eclipse.jface.text.ITextViewerExtension2;
import org.eclipse.jface.text.ITextViewerExtension5;
import org.eclipse.jface.text.source.Annotation;
import org.eclipse.jface.text.source.ICharacterPairMatcher;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.jface.text.source.IVerticalRuler;
import org.eclipse.jface.text.source.LineChangeHover;
import org.eclipse.jface.text.source.SourceViewerConfiguration;
import org.eclipse.jface.text.source.projection.ProjectionSupport;
import org.eclipse.jface.text.source.projection.ProjectionViewer;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.DropTarget;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseMoveListener;
import org.eclipse.swt.events.MouseTrackAdapter;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IEditorActionBarContributor;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.IPageLayout;
import org.eclipse.ui.IStorageEditorInput;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.editors.text.EditorsUI;
import org.eclipse.ui.editors.text.ITextEditorHelpContextIds;
import org.eclipse.ui.editors.text.TextEditor;
import org.eclipse.ui.help.IWorkbenchHelpSystem;
import org.eclipse.ui.part.EditorActionBarContributor;
import org.eclipse.ui.part.IShowInTargetList;
import org.eclipse.ui.progress.IWorkbenchSiteProgressService;
import org.eclipse.ui.texteditor.AnnotationPreference;
import org.eclipse.ui.texteditor.ChainedPreferenceStore;
import org.eclipse.ui.texteditor.DefaultRangeIndicator;
import org.eclipse.ui.texteditor.IAbstractTextEditorHelpContextIds;
import org.eclipse.ui.texteditor.IDocumentProvider;
import org.eclipse.ui.texteditor.IDocumentProviderExtension;
import org.eclipse.ui.texteditor.IElementStateListener;
import org.eclipse.ui.texteditor.IStatusField;
import org.eclipse.ui.texteditor.ITextEditor;
import org.eclipse.ui.texteditor.ITextEditorActionConstants;
import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds;
import org.eclipse.ui.texteditor.IUpdate;
import org.eclipse.ui.texteditor.IWorkbenchActionDefinitionIds;
import org.eclipse.ui.texteditor.MarkerRulerAction;
import org.eclipse.ui.texteditor.SourceViewerDecorationSupport;
import org.eclipse.ui.texteditor.TextOperationAction;
import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
import org.eclipse.ui.views.properties.IPropertySheetPage;
import org.eclipse.wst.sse.core.IModelStateListenerExtended;
import org.eclipse.wst.sse.core.INodeNotifier;
import org.eclipse.wst.sse.core.IStructuredModel;
import org.eclipse.wst.sse.core.IndexedRegion;
import org.eclipse.wst.sse.core.StructuredModelManager;
import org.eclipse.wst.sse.core.document.IDocumentCharsetDetector;
import org.eclipse.wst.sse.core.internal.encoding.EncodingMemento;
import org.eclipse.wst.sse.core.internal.text.IExecutionDelegatable;
import org.eclipse.wst.sse.core.text.IStructuredDocument;
import org.eclipse.wst.sse.core.text.IStructuredDocumentRegion;
import org.eclipse.wst.sse.core.text.ITextRegion;
import org.eclipse.wst.sse.core.undo.IStructuredTextUndoManager;
import org.eclipse.wst.sse.core.util.StringUtils;
import org.eclipse.wst.sse.ui.edit.util.ActionDefinitionIds;
import org.eclipse.wst.sse.ui.edit.util.StructuredTextEditorActionConstants;
import org.eclipse.wst.sse.ui.extension.ExtendedConfigurationBuilder;
import org.eclipse.wst.sse.ui.extension.ExtendedEditorActionBuilder;
import org.eclipse.wst.sse.ui.extension.ExtendedEditorDropTargetAdapter;
import org.eclipse.wst.sse.ui.extension.IExtendedContributor;
import org.eclipse.wst.sse.ui.extension.IExtendedMarkupEditor;
import org.eclipse.wst.sse.ui.extension.IPopupMenuContributor;
import org.eclipse.wst.sse.ui.extensions.ConfigurationPointCalculator;
import org.eclipse.wst.sse.ui.extensions.breakpoint.NullSourceEditingTextTools;
import org.eclipse.wst.sse.ui.extensions.breakpoint.SourceEditingTextTools;
import org.eclipse.wst.sse.ui.extensions.spellcheck.SpellCheckTarget;
import org.eclipse.wst.sse.ui.internal.IModelProvider;
import org.eclipse.wst.sse.ui.internal.Logger;
import org.eclipse.wst.sse.ui.internal.ReadOnlyAwareDropTargetAdapter;
import org.eclipse.wst.sse.ui.internal.SSEUIPlugin;
import org.eclipse.wst.sse.ui.internal.StorageModelProvider;
import org.eclipse.wst.sse.ui.internal.debug.BreakpointRulerAction;
import org.eclipse.wst.sse.ui.internal.debug.EditBreakpointAction;
import org.eclipse.wst.sse.ui.internal.debug.ManageBreakpointAction;
import org.eclipse.wst.sse.ui.internal.debug.ToggleBreakpointAction;
import org.eclipse.wst.sse.ui.internal.debug.ToggleBreakpointsTarget;
import org.eclipse.wst.sse.ui.internal.editor.EditorExecutionContext;
import org.eclipse.wst.sse.ui.internal.editor.EditorModelUtil;
import org.eclipse.wst.sse.ui.internal.editor.IHelpContextIds;
import org.eclipse.wst.sse.ui.internal.editor.StructuredModelDocumentProvider;
import org.eclipse.wst.sse.ui.internal.extension.BreakpointProviderBuilder;
import org.eclipse.wst.sse.ui.internal.hyperlink.OpenHyperlinkAction;
import org.eclipse.wst.sse.ui.internal.preferences.EditorPreferenceNames;
import org.eclipse.wst.sse.ui.internal.projection.IStructuredTextFoldingProvider;
import org.eclipse.wst.sse.ui.internal.properties.ShowPropertiesAction;
import org.eclipse.wst.sse.ui.internal.selection.SelectionHistory;
import org.eclipse.wst.sse.ui.internal.selection.StructureSelectEnclosingAction;
import org.eclipse.wst.sse.ui.internal.selection.StructureSelectHistoryAction;
import org.eclipse.wst.sse.ui.internal.selection.StructureSelectNextAction;
import org.eclipse.wst.sse.ui.internal.selection.StructureSelectPreviousAction;
import org.eclipse.wst.sse.ui.text.DocumentRegionEdgeMatcher;
import org.eclipse.wst.sse.ui.util.Assert;
import org.eclipse.wst.sse.ui.views.contentoutline.ContentOutlineConfiguration;
import org.eclipse.wst.sse.ui.views.contentoutline.StructuredContentOutlineConfiguration;
import org.eclipse.wst.sse.ui.views.contentoutline.StructuredTextEditorContentOutlinePage;
import org.eclipse.wst.sse.ui.views.properties.ConfigurablePropertySheetPage;
import org.eclipse.wst.sse.ui.views.properties.PropertySheetConfiguration;
import org.eclipse.wst.sse.ui.views.properties.StructuredPropertySheetConfiguration;
import org.w3c.dom.Document;
import org.w3c.dom.Node;

public class StructuredTextEditor extends TextEditor implements IExtendedMarkupEditor, IDocumentListener {

	class InternalElementStateListener implements IElementStateListener {

		public void elementContentAboutToBeReplaced(Object element) {
			// we just forward the event
			handleElementContentAboutToBeReplaced(element);
		}

		public void elementContentReplaced(Object element) {
			// we just forward the event
			handleElementContentReplaced(element);
		}

		public void elementDeleted(Object element) {
			// we just forward the event
			handleElementDeleted(element);
		}

		public void elementDirtyStateChanged(Object element, boolean isDirty) {
			// we just forward the event
			handleElementDirtyStateChanged(element, isDirty);
		}

		public void elementMoved(Object originalElement, Object movedElement) {
			// we just forward the event
			handleElementMoved(originalElement, movedElement);
		}
	}

	class InternalModelStateListener implements IModelStateListenerExtended {
		public void modelAboutToBeChanged(IStructuredModel model) {
			if (getTextViewer() != null) {
				// getTextViewer().setRedraw(false);
			}
		}

		public void modelAboutToBeReinitialized(IStructuredModel structuredModel) {
			if (getTextViewer() != null) {
				// getTextViewer().setRedraw(false);
				getTextViewer().unconfigure();
				SourceViewerConfiguration config = getSourceViewerConfiguration();
				if (config instanceof StructuredTextViewerConfiguration) {
					((StructuredTextViewerConfiguration) config).unConfigure(getSourceViewer());
				}
			}
		}

		public void modelChanged(IStructuredModel model) {
			if (getTextViewer() != null) {
				// getTextViewer().setRedraw(true);
				// Since the model can be changed on a background
				// thread, we will update menus on display thread,
				// if we are not already on display thread,
				// and if there is not an update already pending.
				// (we can get lots of 'modelChanged' events in rapid
				// succession, so only need to do one.
				if (!fUpdateMenuTextPending) {
					runOnDisplayThreadIfNeededed(new Runnable() {
						public void run() {
							updateMenuText();
							fUpdateMenuTextPending = false;
						}
					});
				}

			}
		}

		public void modelDirtyStateChanged(IStructuredModel model, boolean isDirty) {
			// do nothing
		}

		public void modelReinitialized(IStructuredModel structuredModel) {
			try {
				if (getSourceViewer() != null) {
					SourceViewerConfiguration cfg = getSourceViewerConfiguration();
					if (cfg != null && cfg instanceof StructuredTextViewerConfiguration) {
						initializeSourceViewerConfiguration(((StructuredTextViewerConfiguration) cfg));
					}
					getSourceViewer().configure(cfg);
				}
			} catch (Exception e) {
				// https://w3.opensource.ibm.com/bugzilla/show_bug.cgi?id=1166
				// investigate each error case post beta
				Logger.logException("problem trying to configure after model change", e); //$NON-NLS-1$
			} finally {
				// so we don't freeze workbench (eg. during page language or
				// content type change)
				((ITextViewerExtension) getSourceViewer()).setRedraw(true);
			}
		}

		// Note: this one should probably be used to
		// control viewer
		// instead of viewer having its own listener
		public void modelResourceDeleted(IStructuredModel model) {
			// do nothing
		}

		public void modelResourceMoved(IStructuredModel originalmodel, IStructuredModel movedmodel) {
			// do nothing
		}

		/**
		 * This 'Runnable' should be very brief, and should not "call out" to
		 * other code especially if it depends on the state of the model.
		 * 
		 * @param r
		 */
		private void runOnDisplayThreadIfNeededed(Runnable r) {
			// if there is no Display at all (that is, running headless),
			// or if we are already running on the display thread, then
			// simply execute the runnable.
			if (getDisplay() == null || (Thread.currentThread() == getDisplay().getThread())) {
				r.run();
			} else {
				// otherwise force the runnable to run on the display thread.
				getDisplay().asyncExec(r);
			}
		}
	}

	class MouseTracker extends MouseTrackAdapter implements MouseMoveListener {
		/** The tracker's subject control. */
		private Control fSubjectControl;

		/**
		 * Creates a new mouse tracker.
		 */
		public MouseTracker() {
			// do nothing
		}

		public void mouseHover(MouseEvent event) {
			// System.out.println("hover: "+event.x + "x" + event.y);
			hoverX = event.x;
			hoverY = event.y;
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.swt.events.MouseMoveListener#mouseMove(org.eclipse.swt.events.MouseEvent)
		 */
		public void mouseMove(MouseEvent e) {
			hoverX = e.x;
			hoverY = e.y;
		}

		/**
		 * Starts this mouse tracker. The given control becomes this tracker's
		 * subject control. Installs itself as mouse track listener on the
		 * subject control.
		 * 
		 * @param subjectControl
		 *            the subject control
		 */
		public void start(Control subjectControl) {
			fSubjectControl = subjectControl;
			if (fSubjectControl != null && !fSubjectControl.isDisposed()) {
				fSubjectControl.addMouseMoveListener(this);
				fSubjectControl.addMouseTrackListener(this);
				fSubjectControl.addDisposeListener(new DisposeListener() {
					public void widgetDisposed(DisposeEvent e) {
						stop();
					}
				});
			}
		}

		/**
		 * Stops this mouse tracker. Removes itself as mouse track, mouse
		 * move, and shell listener from the subject control.
		 */
		public void stop() {
			if (fSubjectControl != null && !fSubjectControl.isDisposed()) {
				fSubjectControl.removeMouseMoveListener(this);
				fSubjectControl.removeMouseTrackListener(this);
				fSubjectControl = null;
			}
		}
	}

	class ShowInTargetListAdapter implements IShowInTargetList {
		/**
		 * Array of ID Strings that define the default show in targets for
		 * this editor.
		 * 
		 * @see org.eclipse.ui.part.IShowInTargetList#getShowInTargetIds()
		 * @return the array of ID Strings that define the default show in
		 *         targets for this editor.
		 */
		public String[] getShowInTargetIds() {
			return fShowInTargetIds;
		}
	}

	class TimeOutExpired extends TimerTask {

		public void run() {
			getDisplay().syncExec(new Runnable() {
				public void run() {
					if (getDisplay() != null && !getDisplay().isDisposed())
						endBusyStateInternal();
				}
			});
		}

	}

	protected final static char[] BRACKETS = {'{', '}', '(', ')', '[', ']'};
	private static final long BUSY_STATE_DELAY = 1000;
	public static final String CORE_SSE_ACTIVITY_ID = "com.ibm.wtp.xml.core"; //$NON-NLS-1$
	protected static final String DOT = "."; //$NON-NLS-1$
	private static final String EDITOR_CONTEXT_MENU_ID = "org.eclipse.wst.sse.ui.StructuredTextEditor.context"; //$NON-NLS-1$

	/** Non-NLS strings */
	private static final String EDITOR_KEYBINDING_SCOPE_ID = "org.eclipse.wst.sse.ui.structuredTextEditorScope"; //$NON-NLS-1$
	public static final String GROUP_NAME_ADDITIONS = "additions"; //$NON-NLS-1$
	public static final String GROUP_NAME_FORMAT = "Format"; //$NON-NLS-1$
	public static final String GROUP_NAME_FORMAT_EXT = "Format.ext"; //$NON-NLS-1$
	private static final String REDO_ACTION_DESC = SSEUIPlugin.getResourceString("%Redo__{0}._UI_"); //$NON-NLS-1$ = "Redo: {0}."
	private static final String REDO_ACTION_DESC_DEFAULT = SSEUIPlugin.getResourceString("%Redo_Text_Change._UI_"); //$NON-NLS-1$ = "Redo Text Change."
	private static final String REDO_ACTION_TEXT = SSEUIPlugin.getResourceString("%&Redo_{0}_@Ctrl+Y_UI_"); //$NON-NLS-1$ = "&Redo {0} @Ctrl+Y"
	private static final String REDO_ACTION_TEXT_DEFAULT = SSEUIPlugin.getResourceString("%&Redo_Text_Change_@Ctrl+Y_UI_"); //$NON-NLS-1$ = "&Redo Text Change @Ctrl+Y"
	protected static final String SSE_MODEL_ID = "org.eclipse.wst.sse.core"; //$NON-NLS-1$
	/**
	 * Constant for representing an error status. This is considered a value
	 * object.
	 */
	static final protected IStatus STATUS_ERROR = new Status(IStatus.ERROR, SSEUIPlugin.ID, IStatus.INFO, "ERROR", null); //$NON-NLS-1$
	/**
	 * Constant for representing an ok status. This is considered a value
	 * object.
	 */
	static final protected IStatus STATUS_OK = new Status(IStatus.OK, SSEUIPlugin.ID, IStatus.OK, "OK", null); //$NON-NLS-1$

	/** Translatable strings */
	private static final String UNDO_ACTION_DESC = SSEUIPlugin.getResourceString("%Undo__{0}._UI_"); //$NON-NLS-1$ = "Undo: {0}."
	private static final String UNDO_ACTION_DESC_DEFAULT = SSEUIPlugin.getResourceString("%Undo_Text_Change._UI_"); //$NON-NLS-1$ = "Undo Text Change."
	private static final String UNDO_ACTION_TEXT = SSEUIPlugin.getResourceString("%&Undo_{0}_@Ctrl+Z_UI_"); //$NON-NLS-1$ = "&Undo {0} @Ctrl+Z"
	private static final String UNDO_ACTION_TEXT_DEFAULT = SSEUIPlugin.getResourceString("%&Undo_Text_Change_@Ctrl+Z_UI_"); //$NON-NLS-1$ = "&Undo Text Change @Ctrl+Z"

	/**
	 * @param args
	 *            java.lang.String[]
	 */
	public static void main(String[] args) {
		StructuredTextEditor editor = null;
		try {
			editor = new StructuredTextEditor();
			System.out.println("Created: " + editor); //$NON-NLS-1$
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	// development time/debug variables only
	private int adapterRequests;
	private long adapterTime;
	private boolean fBackgroundJobEnded;
	private boolean fBusyState;
	private Timer fBusyTimer;
	Runnable fCurrentRunnable = null;
	boolean fDirtyBeforeDocumentEvent = false;
	protected ExtendedEditorDropTargetAdapter fDropAdapter;
	protected DropTarget fDropTarget;
	protected boolean fEditorDisposed = false;
	private IEditorPart fEditorPart;
	private InternalModelStateListener fInternalModelStateListener;

	protected MouseTracker fMouseTracker;
	protected IContentOutlinePage fOutlinePage;
	/** This editor's projection model updater */
	private IStructuredTextFoldingProvider fProjectionModelUpdater;
	/** This editor's projection support */
	private ProjectionSupport fProjectionSupport;
	protected IPropertySheetPage fPropertySheetPage;
	private String fRememberTitle;
	String[] fShowInTargetIds = new String[]{IPageLayout.ID_RES_NAV};
	private IAction fShowPropertiesAction = null;
	private IStructuredModel fStructuredModel;

	private boolean fUpdateMenuTextPending;
	protected int hoverX = -1;
	protected int hoverY = -1;
	private InternalElementStateListener internalElementStateListener = new InternalElementStateListener();
	private boolean shouldClose = false;
	private long startPerfTime;

	public StructuredTextEditor() {

		super();
		initializeDocumentProvider(null);
	}

	/*
	 * This method is just to make firePropertyChanged accessbible from some
	 * (anonomous) inner classes.
	 */
	protected void _firePropertyChange(int property) {
		super.firePropertyChange(property);
	}

	protected void abstractTextEditorContextMenuAboutToShow(IMenuManager menu) {
		menu.add(new Separator(ITextEditorActionConstants.GROUP_UNDO));
		menu.add(new Separator(ITextEditorActionConstants.GROUP_COPY));
		menu.add(new Separator(ITextEditorActionConstants.GROUP_PRINT));
		menu.add(new Separator(ITextEditorActionConstants.GROUP_EDIT));
		menu.add(new Separator(ITextEditorActionConstants.GROUP_FIND));
		menu.add(new Separator(IWorkbenchActionConstants.GROUP_ADD));
		menu.add(new Separator(ITextEditorActionConstants.GROUP_REST));
		menu.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
		menu.add(new Separator(ITextEditorActionConstants.GROUP_SAVE));

		if (isEditable()) {
			addAction(menu, ITextEditorActionConstants.GROUP_UNDO, ITextEditorActionConstants.UNDO);
			addAction(menu, ITextEditorActionConstants.GROUP_UNDO, ITextEditorActionConstants.REVERT_TO_SAVED);
			addAction(menu, ITextEditorActionConstants.GROUP_COPY, ITextEditorActionConstants.CUT);
			addAction(menu, ITextEditorActionConstants.GROUP_COPY, ITextEditorActionConstants.COPY);
			addAction(menu, ITextEditorActionConstants.GROUP_COPY, ITextEditorActionConstants.PASTE);
			addAction(menu, ITextEditorActionConstants.GROUP_SAVE, ITextEditorActionConstants.SAVE);
		} else {
			addAction(menu, ITextEditorActionConstants.GROUP_COPY, ITextEditorActionConstants.COPY);
		}

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

	protected void addContextMenuActions(IMenuManager menu) {
		// Only offer actions that affect the text if the viewer allows
		// modification and supports any of these operations
		IAction formatAll = getAction(StructuredTextEditorActionConstants.ACTION_NAME_FORMAT_DOCUMENT);
		IAction formatSelection = getAction(StructuredTextEditorActionConstants.ACTION_NAME_FORMAT_ACTIVE_ELEMENTS);
		IAction cleanupAll = getAction(StructuredTextEditorActionConstants.ACTION_NAME_CLEANUP_DOCUMENT);
		boolean enableFormatMenu = (formatAll != null && formatAll.isEnabled()) || (formatSelection != null && formatSelection.isEnabled()) || (cleanupAll != null && cleanupAll.isEnabled());

		if (getSourceViewer().isEditable() && enableFormatMenu) {
			String label = SSEUIPlugin.getResourceString("%FormatMenu.label"); //$NON-NLS-1$ = "Format"
			MenuManager subMenu = new MenuManager(label, GROUP_NAME_FORMAT);
			subMenu.add(new GroupMarker(GROUP_NAME_FORMAT_EXT));
			addAction(subMenu, StructuredTextEditorActionConstants.ACTION_NAME_FORMAT_DOCUMENT);
			addAction(subMenu, StructuredTextEditorActionConstants.ACTION_NAME_FORMAT_ACTIVE_ELEMENTS);
			subMenu.add(new GroupMarker(GROUP_NAME_ADDITIONS));
			addAction(menu, ITextEditorActionConstants.GROUP_EDIT, StructuredTextEditorActionConstants.ACTION_NAME_CLEANUP_DOCUMENT);
			menu.appendToGroup(ITextEditorActionConstants.GROUP_EDIT, subMenu);
		}

		// Some Design editors (DTD) rely on this view for their own uses
		menu.appendToGroup(IWorkbenchActionConstants.GROUP_ADD, fShowPropertiesAction);
	}

	protected void addExtendedContextMenuActions(IMenuManager menu) {
		IEditorActionBarContributor c = getEditorSite().getActionBarContributor();
		if (c instanceof IPopupMenuContributor) {
			((IPopupMenuContributor) c).contributeToPopupMenu(menu);
		} else {
			ExtendedEditorActionBuilder builder = new ExtendedEditorActionBuilder();
			IExtendedContributor pmc = builder.readActionExtensions(getConfigurationPoints());
			if (pmc != null) {
				pmc.setActiveEditor(this);
				pmc.contributeToPopupMenu(menu);
			}
		}
	}

	protected void addExtendedRulerContextMenuActions(IMenuManager menu) {
		// none at this level
	}



	/**
	 * 
	 */
	public void beginBackgroundOperation() {
		fBackgroundJobEnded = false;
		// if already in busy state, no need to do anything
		// and, we only start, or reset, the timed busy
		// state when we get the "endBackgroundOperation" call.
		if (!inBusyState()) {
			beginBusyStateInternal();
		}
	}

	/**
	 * 
	 */
	private void beginBusyStateInternal() {

		fBusyState = true;
		startBusyTimer();

		ISourceViewer viewer = getSourceViewer();
		if (viewer instanceof StructuredTextViewer) {
			((StructuredTextViewer) viewer).beginBackgroundUpdate();

		}
		showBusy(true);
	}

	// private void addFindOccurrencesAction(String matchType, String
	// matchText, IMenuManager menu) {
	//
	// AbstractFindOccurrencesAction action = new
	// AbstractFindOccurrencesAction(getFileInEditor(), new
	// SearchUIConfiguration(), (IStructuredDocument) getDocument(),
	// matchType, matchText, getProgressMonitor());
	// action.setText("Occurrences of \"" + matchText + "\" in File");
	// menu.appendToGroup(ITextEditorActionConstants.GROUP_EDIT, action);
	// }

	/**
	 * Instead of us closing directly, we have to close with our containing
	 * (multipage) editor, if it exists.
	 */
	public void close(final boolean save) {
		if (getSite() == null) {
			// if site hasn't been set yet, then we're not
			// completely open
			// so set a flag not to open
			shouldClose = true;
		} else {
			if (getEditorPart() != null) {
				Display display = getSite().getShell().getDisplay();
				display.asyncExec(new Runnable() {

					public void run() {
						getSite().getPage().closeEditor(getEditorPart(), save);
					}
				});
			} else {
				super.close(save);
			}
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.texteditor.AbstractDecoratedTextEditor#collectContextMenuPreferencePages()
	 */
	protected String[] collectContextMenuPreferencePages() {
		List allIds = new ArrayList(0);

		// get contributed preference pages
		ExtendedConfigurationBuilder builder = ExtendedConfigurationBuilder.getInstance();
		String[] configurationIds = getConfigurationPoints();
		for (int i = 0; i < configurationIds.length; i++) {
			String[] definitions = builder.getDefinitions("preferencepages", configurationIds[i]); //$NON-NLS-1$
			for (int j = 0; j < definitions.length; j++) {
				String someIds = definitions[j];
				if (someIds != null && someIds.length() > 0) {
					// supports multiple comma-delimited page IDs in one
					// element
					String[] ids = StringUtils.unpack(someIds);
					for (int k = 0; k < ids.length; k++) {
						// trim, just to keep things clean
						String id = ids[k].trim();
						if (!allIds.contains(id)) {
							allIds.add(id);
						}
					}
				}
			}
		}

		// add pages contributed by super
		String[] superPages = super.collectContextMenuPreferencePages();
		for (int m = 0; m < superPages.length; m++) {
			// trim, just to keep things clean
			String id = superPages[m].trim();
			if (!allIds.contains(id)) {
				allIds.add(id);
			}
		}

		return (String[]) allIds.toArray(new String[0]);
	}

	/**
	 * Compute and set double-click action for the source editor, depending on
	 * the input.
	 */
	protected void computeAndSetDoubleClickAction(IStructuredModel model) {
		if (model == null)
			return;
		// If we're editing a breakpoint-supported input, make double-clicking
		// on the ruler toggle a breakpoint instead of toggling a bookmark.
		String ext = BreakpointRulerAction.getFileExtension(getEditorInput());
		if (BreakpointProviderBuilder.getInstance().isAvailable(model.getContentTypeIdentifier(), ext)) {
			setAction(ITextEditorActionConstants.RULER_DOUBLE_CLICK, getAction(ActionDefinitionIds.TOGGLE_BREAKPOINTS));
		} else {
			// The Default Text Editor uses editorContribution to perform this
			// mapping, but since it relies on the IEditorSite ID, it can't be
			// relied on for MultiPageEditorParts. Instead, force the action
			// registration manually.
			setAction(ITextEditorActionConstants.RULER_DOUBLE_CLICK, new MarkerRulerAction(SSEUIPlugin.getDefault().getResourceBundle(), "Editor.ManageBookmarks.", this, getVerticalRuler(), IMarker.BOOKMARK, true));
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.texteditor.ExtendedTextEditor#configureSourceViewerDecorationSupport(org.eclipse.ui.texteditor.SourceViewerDecorationSupport)
	 */
	protected void configureSourceViewerDecorationSupport(SourceViewerDecorationSupport support) {
		support.setCharacterPairMatcher(createCharacterPairMatcher());
		support.setMatchingCharacterPainterPreferenceKeys(EditorPreferenceNames.MATCHING_BRACKETS, EditorPreferenceNames.MATCHING_BRACKETS_COLOR);

		super.configureSourceViewerDecorationSupport(support);
	}

	protected void createActions() {
		super.createActions();
		ResourceBundle resourceBundle = SSEUIPlugin.getDefault().getResourceBundle();
		IWorkbenchHelpSystem helpSystem = SSEUIPlugin.getDefault().getWorkbench().getHelpSystem();
		// TextView Action - moving the selected text to
		// the clipboard
		// override the cut/paste/delete action to make
		// them run on read-only
		// files
		Action action = new TextOperationAction(resourceBundle, "Editor.Cut.", this, ITextOperationTarget.CUT, true); //$NON-NLS-1$
		action.setActionDefinitionId(IWorkbenchActionDefinitionIds.CUT);
		setAction(ITextEditorActionConstants.CUT, action);
		helpSystem.setHelp(action, IAbstractTextEditorHelpContextIds.CUT_ACTION);
		// TextView Action - inserting the clipboard
		// content at the current
		// position
		// override the cut/paste/delete action to make
		// them run on read-only
		// files
		action = new TextOperationAction(resourceBundle, "Editor.Paste.", this, ITextOperationTarget.PASTE, true); //$NON-NLS-1$
		action.setActionDefinitionId(IWorkbenchActionDefinitionIds.PASTE);
		setAction(ITextEditorActionConstants.PASTE, action);
		helpSystem.setHelp(action, IAbstractTextEditorHelpContextIds.PASTE_ACTION);
		// TextView Action - deleting the selected text or
		// if selection is
		// empty the character at the right of the current
		// position
		// override the cut/paste/delete action to make
		// them run on read-only
		// files
		action = new TextOperationAction(resourceBundle, "Editor.Delete.", this, ITextOperationTarget.DELETE, true); //$NON-NLS-1$
		action.setActionDefinitionId(IWorkbenchActionDefinitionIds.DELETE);
		setAction(ITextEditorActionConstants.DELETE, action);
		helpSystem.setHelp(action, IAbstractTextEditorHelpContextIds.DELETE_ACTION);
		// SourceView Action - requesting information at
		// the current insertion
		// position
		action = new TextOperationAction(SSEUIPlugin.getDefault().getResourceBundle(), StructuredTextEditorActionConstants.ACTION_NAME_INFORMATION + DOT, this, ISourceViewer.INFORMATION, true);
		action.setActionDefinitionId(ActionDefinitionIds.INFORMATION);
		setAction(StructuredTextEditorActionConstants.ACTION_NAME_INFORMATION, action);
		markAsStateDependentAction(StructuredTextEditorActionConstants.ACTION_NAME_INFORMATION, true);
		// SourceView Action - requesting content assist to
		// show completetion
		// proposals for the current insert position
		action = new TextOperationAction(resourceBundle, StructuredTextEditorActionConstants.ACTION_NAME_CONTENTASSIST_PROPOSALS + DOT, this, ISourceViewer.CONTENTASSIST_PROPOSALS, true);
		helpSystem.setHelp(action, IHelpContextIds.CONTMNU_CONTENTASSIST_HELPID);
		action.setActionDefinitionId(ITextEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS);
		setAction(StructuredTextEditorActionConstants.ACTION_NAME_CONTENTASSIST_PROPOSALS, action);
		markAsStateDependentAction(StructuredTextEditorActionConstants.ACTION_NAME_CONTENTASSIST_PROPOSALS, true);
		// SourceView Action - requesting content assist to
		// show the content
		// information for the current insert position
		action = new TextOperationAction(SSEUIPlugin.getDefault().getResourceBundle(), StructuredTextEditorActionConstants.ACTION_NAME_CONTENTASSIST_CONTEXT_INFORMATION + DOT, this, ISourceViewer.CONTENTASSIST_CONTEXT_INFORMATION);
		action.setActionDefinitionId(ITextEditorActionDefinitionIds.CONTENT_ASSIST_CONTEXT_INFORMATION);
		setAction(StructuredTextEditorActionConstants.ACTION_NAME_CONTENTASSIST_CONTEXT_INFORMATION, action);
		markAsStateDependentAction(StructuredTextEditorActionConstants.ACTION_NAME_CONTENTASSIST_CONTEXT_INFORMATION, true);
		// StructuredTextViewer Action - requesting
		// correction assist to show
		// correction proposals for the current position
		action = new TextOperationAction(resourceBundle, StructuredTextEditorActionConstants.ACTION_NAME_QUICK_FIX + DOT, this, StructuredTextViewer.QUICK_FIX, true);
		action.setActionDefinitionId(ActionDefinitionIds.QUICK_FIX);
		setAction(StructuredTextEditorActionConstants.ACTION_NAME_QUICK_FIX, action);
		markAsStateDependentAction(StructuredTextEditorActionConstants.ACTION_NAME_QUICK_FIX, true);
		// StructuredTextViewer Action - requesting format
		// of the whole
		// document
		action = new TextOperationAction(resourceBundle, StructuredTextEditorActionConstants.ACTION_NAME_FORMAT_DOCUMENT + DOT, this, StructuredTextViewer.FORMAT_DOCUMENT);
		helpSystem.setHelp(action, IHelpContextIds.CONTMNU_FORMAT_DOC_HELPID);
		action.setActionDefinitionId(ActionDefinitionIds.FORMAT_DOCUMENT);
		setAction(StructuredTextEditorActionConstants.ACTION_NAME_FORMAT_DOCUMENT, action);
		markAsStateDependentAction(StructuredTextEditorActionConstants.ACTION_NAME_FORMAT_DOCUMENT, true);
		markAsSelectionDependentAction(StructuredTextEditorActionConstants.ACTION_NAME_FORMAT_DOCUMENT, true);
		// StructuredTextViewer Action - requesting format
		// of the active
		// elements
		action = new TextOperationAction(resourceBundle, StructuredTextEditorActionConstants.ACTION_NAME_FORMAT_ACTIVE_ELEMENTS + DOT, this, StructuredTextViewer.FORMAT_ACTIVE_ELEMENTS);
		helpSystem.setHelp(action, IHelpContextIds.CONTMNU_FORMAT_ELEMENTS_HELPID);
		action.setActionDefinitionId(ActionDefinitionIds.FORMAT_ACTIVE_ELEMENTS);
		setAction(StructuredTextEditorActionConstants.ACTION_NAME_FORMAT_ACTIVE_ELEMENTS, action);
		markAsStateDependentAction(StructuredTextEditorActionConstants.ACTION_NAME_FORMAT_ACTIVE_ELEMENTS, true);
		markAsSelectionDependentAction(StructuredTextEditorActionConstants.ACTION_NAME_FORMAT_ACTIVE_ELEMENTS, true);
		// StructuredTextEditor Action - add breakpoints
		action = new ToggleBreakpointAction(this, getVerticalRuler());
		setAction(ActionDefinitionIds.TOGGLE_BREAKPOINTS, action);
		// StructuredTextEditor Action - manage breakpoints
		action = new ManageBreakpointAction(this, getVerticalRuler());
		setAction(ActionDefinitionIds.MANAGE_BREAKPOINTS, action);
		// StructuredTextEditor Action - edit breakpoints
		action = new EditBreakpointAction(this, getVerticalRuler());
		setAction(ActionDefinitionIds.EDIT_BREAKPOINTS, action);
		// StructuredTextViewer Action - open file on selection
		action = new OpenHyperlinkAction(resourceBundle, StructuredTextEditorActionConstants.ACTION_NAME_OPEN_FILE + DOT, this, getSourceViewer());
		action.setActionDefinitionId(ActionDefinitionIds.OPEN_FILE);
		setAction(StructuredTextEditorActionConstants.ACTION_NAME_OPEN_FILE, action);

		fShowPropertiesAction = new ShowPropertiesAction();

		SelectionHistory selectionHistory = new SelectionHistory(this);
		action = new StructureSelectEnclosingAction(this, selectionHistory);
		action.setActionDefinitionId(ActionDefinitionIds.STRUCTURE_SELECT_ENCLOSING);
		setAction(StructuredTextEditorActionConstants.ACTION_NAME_STRUCTURE_SELECT_ENCLOSING, action);

		action = new StructureSelectNextAction(this, selectionHistory);
		action.setActionDefinitionId(ActionDefinitionIds.STRUCTURE_SELECT_NEXT);
		setAction(StructuredTextEditorActionConstants.ACTION_NAME_STRUCTURE_SELECT_NEXT, action);

		action = new StructureSelectPreviousAction(this, selectionHistory);
		action.setActionDefinitionId(ActionDefinitionIds.STRUCTURE_SELECT_PREVIOUS);
		setAction(StructuredTextEditorActionConstants.ACTION_NAME_STRUCTURE_SELECT_PREVIOUS, action);

		action = new StructureSelectHistoryAction(this, selectionHistory);
		action.setActionDefinitionId(ActionDefinitionIds.STRUCTURE_SELECT_HISTORY);
		setAction(StructuredTextEditorActionConstants.ACTION_NAME_STRUCTURE_SELECT_HISTORY, action);
		selectionHistory.setHistoryAction((StructureSelectHistoryAction) action);
	}

	protected LineChangeHover createChangeHover() {
		return new StructuredLineChangeHover();
	}

	protected ICharacterPairMatcher createCharacterPairMatcher() {
		ICharacterPairMatcher matcher = null;
		ExtendedConfigurationBuilder builder = ExtendedConfigurationBuilder.getInstance();
		String[] ids = getConfigurationPoints();
		for (int i = 0; matcher == null && i < ids.length; i++) {
			matcher = (ICharacterPairMatcher) builder.getConfiguration(DocumentRegionEdgeMatcher.ID, ids[i]);
		}
		if (matcher == null) {
			matcher = new ICharacterPairMatcher() {

				public void clear() {
				}

				public void dispose() {
				}

				public int getAnchor() {
					return ICharacterPairMatcher.LEFT;
				}

				public IRegion match(IDocument iDocument, int i) {
					return null;
				}
			};
		}
		return matcher;
	}

	/**
	 * Create a preference store that combines the source editor preferences
	 * with the base editor's preferences.
	 * 
	 * @return IPreferenceStore
	 */
	private IPreferenceStore createCombinedPreferenceStore() {
		IPreferenceStore sseEditorPrefs = SSEUIPlugin.getDefault().getPreferenceStore();
		IPreferenceStore baseEditorPrefs = EditorsUI.getPreferenceStore();
		return new ChainedPreferenceStore(new IPreferenceStore[]{sseEditorPrefs, baseEditorPrefs});
	}

	protected ContentOutlineConfiguration createContentOutlineConfiguration() {
		ContentOutlineConfiguration cfg = null;
		ExtendedConfigurationBuilder builder = ExtendedConfigurationBuilder.getInstance();
		String[] ids = getConfigurationPoints();
		for (int i = 0; cfg == null && i < ids.length; i++) {
			cfg = (ContentOutlineConfiguration) builder.getConfiguration(ContentOutlineConfiguration.ID, ids[i]);
		}
		return cfg;
	}

	protected void createModelDependentFields() {
		// none at this level
	}

	/**
	 * Use StructuredTextViewerConfiguration if a viewerconfiguration has not
	 * already been set. Also initialize StructuredTextViewer.
	 * 
	 * @see org.eclipse.ui.texteditor.AbstractDecoratedTextEditor#createPartControl(org.eclipse.swt.widgets.Composite)
	 */
	public void createPartControl(Composite parent) {
		if (getSourceViewerConfiguration() == null) {
			StructuredTextViewerConfiguration newViewerConfiguration = createSourceViewerConfiguration();
			setSourceViewerConfiguration(newViewerConfiguration);
		}

		super.createPartControl(parent);

		// instead of calling setInput twice, use initializeSourceViewer() to
		// handle source viewer initialization previously handled by setInput
		initializeSourceViewer();
	}

	protected PropertySheetConfiguration createPropertySheetConfiguration() {
		PropertySheetConfiguration cfg = null;
		ExtendedConfigurationBuilder builder = ExtendedConfigurationBuilder.getInstance();
		String[] ids = getConfigurationPoints();
		for (int i = 0; cfg == null && i < ids.length; i++) {
			cfg = (PropertySheetConfiguration) builder.getConfiguration(PropertySheetConfiguration.ID, ids[i]);
		}
		return cfg;
	}

	/**
	 * Loads the Show In Target IDs from the Extended Configuration extension
	 * point.
	 * 
	 * @return
	 */
	private String[] createShowInTargetIds() {
		List allIds = new ArrayList(0);
		ExtendedConfigurationBuilder builder = ExtendedConfigurationBuilder.getInstance();
		String[] configurationIds = getConfigurationPoints();
		for (int i = 0; i < configurationIds.length; i++) {
			String[] definitions = builder.getDefinitions("showintarget", configurationIds[i]); //$NON-NLS-1$
			for (int j = 0; j < definitions.length; j++) {
				String someIds = definitions[j];
				if (someIds != null && someIds.length() > 0) {
					String[] ids = StringUtils.unpack(someIds);
					for (int k = 0; k < ids.length; k++) {
						// trim, just to keep things clean
						String id = ids[k].trim();
						if (!allIds.contains(id)) {
							allIds.add(id);
						}
					}
				}
			}
		}

		if (!allIds.contains(IPageLayout.ID_RES_NAV)) {
			allIds.add(IPageLayout.ID_RES_NAV);
		}
		if (!allIds.contains(IPageLayout.ID_OUTLINE)) {
			allIds.add(IPageLayout.ID_OUTLINE);
		}
		return (String[]) allIds.toArray(new String[0]);
	}

	/**
	 * @return
	 */
	protected SourceEditingTextTools createSourceEditingTextTools() {
		SourceEditingTextTools tools = null;
		ExtendedConfigurationBuilder builder = ExtendedConfigurationBuilder.getInstance();
		String[] ids = getConfigurationPoints();
		for (int i = 0; tools == null && i < ids.length; i++) {
			tools = (SourceEditingTextTools) builder.getConfiguration(NullSourceEditingTextTools.ID, ids[i]);
		}
		if (tools == null) {
			tools = NullSourceEditingTextTools.getInstance();
		}
		return tools;
	}

	/**
	 * Creates the source viewer to be used by this editor
	 */
	protected ISourceViewer createSourceViewer(Composite parent, IVerticalRuler verticalRuler, int styles) {
		fAnnotationAccess = createAnnotationAccess();
		fOverviewRuler = createOverviewRuler(getSharedColors());
		StructuredTextViewer sourceViewer = createStructedTextViewer(parent, verticalRuler, styles);
		initSourceViewer(sourceViewer);
		return sourceViewer;
	}

	protected StructuredTextViewerConfiguration createSourceViewerConfiguration() {
		StructuredTextViewerConfiguration cfg = null;
		ExtendedConfigurationBuilder builder = ExtendedConfigurationBuilder.getInstance();
		String[] ids = getConfigurationPoints();
		for (int i = 0; cfg == null && i < ids.length; i++) {
			cfg = (StructuredTextViewerConfiguration) builder.getConfiguration(StructuredTextViewerConfiguration.ID, ids[i]);
		}
		if (cfg == null) {
			cfg = new StructuredTextViewerConfiguration();
			cfg.setDeclaringID(getClass().getName() + "#default"); //$NON-NLS-1$
		}
		initializeSourceViewerConfiguration(cfg);
		return cfg;
	}

	/**
	 * @deprecated - will be removed in M4
	 */
	protected SpellCheckTarget createSpellCheckTarget() {
		SpellCheckTarget target = null;
		ExtendedConfigurationBuilder builder = ExtendedConfigurationBuilder.getInstance();
		String[] ids = getConfigurationPoints();
		for (int i = 0; target == null && i < ids.length; i++) {
			target = (SpellCheckTarget) builder.getConfiguration(SpellCheckTargetImpl.ID, ids[i]);
		}
		if (target == null) {
			target = new SpellCheckTargetImpl();
		}
		target.setTextEditor(this);
		return target;
	}

	protected StructuredTextViewer createStructedTextViewer(Composite parent, IVerticalRuler verticalRuler, int styles) {
		return new StructuredTextViewer(parent, verticalRuler, getOverviewRuler(), isOverviewRulerVisible(), styles);
	}

	/**
	 * @see DekstopPart#dispose
	 */
	public void dispose() {
		Logger.trace("Source Editor", "StructuredTextEditor::dispose entry"); //$NON-NLS-1$ //$NON-NLS-2$
		if (org.eclipse.wst.sse.core.util.Debug.perfTestAdapterClassLoading) {
			System.out.println("Total calls to getAdapter: " + adapterRequests); //$NON-NLS-1$
			System.out.println("Total time in getAdapter: " + adapterTime); //$NON-NLS-1$
			System.out.println("Average time per call: " + (adapterTime / adapterRequests)); //$NON-NLS-1$
		}

		// just for work around for document memory leak
		// related to last position (stored in plugin!)
		// holding on to 'selection' which holds instance
		// of document
		// caution, this is making use of internal classes

		int caretOffset = getCaretPosition();
		// safeguard values used in the Position below
		if (caretOffset < 0) {
			caretOffset = 0;
		}

		// TODO: remove the code for now, need to track down the leak
		// FIXME: this was put in, to overcome memory leak (via the document
		// in the selection).
		// we need to fix the leak and/or find a better way.
		// TextEditorPlugin.getDefault().setLastEditPosition(new
		// EditPosition(getEditorInput(), getEditorSite().getId(),
		// TextSelection.emptySelection(), new Position(caretOffset)));

		// dispose of document folding support
		if (fProjectionModelUpdater != null) {
			fProjectionModelUpdater.uninstall();
			fProjectionModelUpdater = null;
		}

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

		// subclass may not have mouse tracker created
		// need to check for null before stopping
		if (fMouseTracker != null) {
			fMouseTracker.stop();
			fMouseTracker = null;
		}

		// added this 2/19/2004 to match the 'add' in
		// intializeDocumentProvider.
		if (getDocumentProvider() != null)
			getDocumentProvider().removeElementStateListener(internalElementStateListener);

		// added this 2/20/2004 based on probe results --
		// seems should be handled by setModel(null), but
		// that's a more radical change.
		// and, technically speaking, should not be needed,
		// but makes a memory leak
		// less severe.
		if (fStructuredModel != null) {
			if (fStructuredModel.getStructuredDocument() != null)
				fStructuredModel.getStructuredDocument().removeDocumentListener(this);
			fStructuredModel.removeModelStateListener(getInternalModelStateListener());
		}

		if (getDocument() != null) {
			IDocument doc = getDocument();
			doc.removeDocumentListener(this);
			if (doc instanceof IExecutionDelegatable) {
				((IExecutionDelegatable) doc).setExecutionDelegate(null);
			}
		}

		fEditorDisposed = true;
		disposeModelDependentFields();
		// some things in the configuration need to clean
		// up after themselves
		SourceViewerConfiguration config = getSourceViewerConfiguration();
		if (config instanceof StructuredTextViewerConfiguration) {
			((StructuredTextViewerConfiguration) config).unConfigure(getSourceViewer());
		}

		if (fDropTarget != null)
			fDropTarget.dispose();

		setPreferenceStore(null);

		// strictly speaking, but following null outs
		// should not be needed,
		// but in the event of a memory leak, they make the
		// memory leak less
		// severe
		fDropAdapter = null;
		fDropTarget = null;

		super.dispose();
		Logger.trace("Source Editor", "StructuredTextEditor::dispose exit"); //$NON-NLS-1$ //$NON-NLS-2$
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.texteditor.AbstractDecoratedTextEditor#disposeDocumentProvider()
	 */
	protected void disposeDocumentProvider() {
		if (fStructuredModel != null && !(getDocumentProvider() instanceof IModelProvider)) {
			fStructuredModel.releaseFromEdit();
		}
		super.disposeDocumentProvider();
	}

	/**
	 * Disposes model specific editor helpers such as statusLineHelper.
	 * Basically any code repeated in update() & dispose() should be placed
	 * here.
	 */
	protected void disposeModelDependentFields() {
		// none at this level
	}

	// This is for the IDocumentListener interface
	public void documentAboutToBeChanged(DocumentEvent event) {
		fDirtyBeforeDocumentEvent = isDirty();
	}

	// This is for the IDocumentListener interface
	public void documentChanged(DocumentEvent event) {
		if (isEditorInputReadOnly()) {
			// stop listening to document event
			// caused by the undo after validateEdit
			final int offset = event.getOffset() + event.getLength();
			fCurrentRunnable = new Runnable() {
				public void run() {
					if (!fEditorDisposed) {
						IStatus status = validateEdit(getSite().getShell());
						if (status != null && status.isOK()) {
							// nothing to do if 'ok'
						} else {
							getModel().getUndoManager().undo();
							getSourceViewer().setSelectedRange(offset, 0);
							if (!fDirtyBeforeDocumentEvent) {
								// reset dirty state if
								// model not dirty before
								// document event
								getModel().setDirtyState(false);
							}
						}
					}
					fCurrentRunnable = null;
				}
			};
			/*
			 * We need to ensure that this is run via 'asyncExec' since these
			 * notifications can come from a non-ui thread.
			 * 
			 * The non-ui thread call would occur when creating a new file
			 * under ClearCase (or other library) control. The creation of the
			 * new file would trigger a validateEdit call, on another thread,
			 * that would prompt the user to add the new file to version
			 * control.
			 */
			Display display = getDisplay();
			if (display != null) {
				if (Thread.currentThread() != display.getThread())
					// future_TODO: there's probably a better
					// way than relying on asycnExec
					display.asyncExec(fCurrentRunnable);
				else
					fCurrentRunnable.run();
			}
		}
	}

	/**
	 * @see ITextEditor#doRevertToSaved
	 */
	public void doRevertToSaved() {
		super.doRevertToSaved();
		if (fOutlinePage != null && fOutlinePage instanceof IUpdate)
			((IUpdate) fOutlinePage).update();
		// update menu text
		updateMenuText();
	}

	public void doSave(IProgressMonitor progressMonitor) {
		try {
			aboutToSaveModel();
			updateEncodingMemento();
			super.doSave(progressMonitor);
		} finally {
			savedModel();
		}
	}

	private void savedModel() {
		if (getModel() != null) {
			getModel().changedModel();
		}
	}

	private void aboutToSaveModel() {
		if (getModel() != null) {
			getModel().aboutToChangeModel();
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.texteditor.AbstractTextEditor#doSetInput(org.eclipse.ui.IEditorInput)
	 */
	protected void doSetInput(IEditorInput input) throws CoreException {
		try {
			// TODO: if opened in more than one editor, this will cause
			// problems.
			IEditorInput oldInput = getEditorInput();
			if (oldInput != null) {
				IDocument olddoc = getDocumentProvider().getDocument(oldInput);
				if (olddoc != null && olddoc instanceof IExecutionDelegatable) {
					((IExecutionDelegatable) olddoc).setExecutionDelegate(null);
				}
			}

			if (fStructuredModel != null) {
				fStructuredModel.releaseFromEdit();
			}

			super.doSetInput(input);

			if (getDocument() instanceof IExecutionDelegatable) {
				((IExecutionDelegatable) getDocument()).setExecutionDelegate(new EditorExecutionContext(this));
			}

			IStructuredModel model = null;
			// if we have a Model provider, get the model from it
			if (getDocumentProvider() instanceof IModelProvider) {
				model = ((IModelProvider) getDocumentProvider()).getModel(getEditorInput());
				if (!model.isShared()) {
					EditorModelUtil.addFactoriesTo(model);
				}
			} else {
				IDocument doc = getDocument();
				// IMPL: need to cleanup throughout to avoid any instanceof
				// checks
				if (doc instanceof IStructuredDocument) {
					// corresponding releaseFromEdit occurs in
					// disposeDocumentProvider
					model = StructuredModelManager.getModelManager().getExistingModelForEdit(doc);
					if (model == null) {
						model = StructuredModelManager.getModelManager().getModelForEdit((IStructuredDocument) doc);
						EditorModelUtil.addFactoriesTo(model);
					}
				} else {
					logUnexpectedDocumentKind(input);
				}
			}

			if (fStructuredModel != null || model != null) {
				setModel(model);
			}

			if (fProjectionModelUpdater != null)
				fProjectionModelUpdater.initialize();

			// start editor with smart insert mode
			setInsertMode(SMART_INSERT);
		} catch (CoreException exception) {
			// dispose editor
			dispose();

			throw new CoreException(exception.getStatus());
		}
	}

	private void logUnexpectedDocumentKind(IEditorInput input) {
		Logger.log(Logger.WARNING, "StructuredTextEditor being used without StructuredDocument");
		String name = null;
		if (input != null) {
			name = input.getName();
		} else {
			name = "input was null";
		}
		Logger.log(Logger.WARNING, "         Input Name: " + name);
		String implClass = null;
		if (getDocument() != null) {
			implClass = getDocument().getClass().toString();
		} else {
			implClass = "document was null";
		}
		Logger.log(Logger.WARNING, "         Document implementation: " + implClass);
	}

	/**
	 * Sets up this editor's context menu before it is made visible.
	 * 
	 * @param menu
	 *            the menu
	 */
	public void editorContextMenuAboutToShow(IMenuManager menu) {
		// To be consistant with the Java Editor, we want
		// to remove
		// ShiftRight and ShiftLeft from the context menu.
		//
		// ShiftRight and ShiftLeft were added in the super
		// implemenation of
		// this method. We want to skip it and call
		// AbstractTextEditor's
		// implementation directly. The easiest way is to
		// copy the method here.

		// super.editorContextMenuAboutToShow(menu);
		abstractTextEditorContextMenuAboutToShow(menu);

		addContextMenuActions(menu);
		addExtendedContextMenuActions(menu);
	}

	/**
	 * This is the public method to be called to notifiy us that document is
	 * being updated by backround job.
	 */
	public void endBackgroundOperation() {
		fBackgroundJobEnded = true;
		// note, we don't immediately end our 'internal busy' state,
		// since we may get many calls in a short period of
		// time. We always wait for the time out.
		resetBusyState();
	}


	/**
	 * Note this method can be called indirectly from background job operation
	 * ... but expected to be gaurded there with ILock, plus, can be called
	 * directly from timer thread, so the timer's run method guards with ILock
	 * too.
	 */
	private void endBusyStateInternal() {
		if (fBackgroundJobEnded) {
			fBusyTimer.cancel();
			showBusy(false);

			ISourceViewer viewer = getSourceViewer();
			if (viewer instanceof StructuredTextViewer) {
				((StructuredTextViewer) viewer).endBackgroundUpdate();
			}
			fBusyState = false;
		} else {
			// we will only be in this branch for a back ground job that is
			// taking
			// longer than our normal time-out period (meaning we got notified
			// of
			// the timeout "inbetween" calls to 'begin' and
			// 'endBackgroundOperation'.
			// (which, remember, can only happen since there are many calls to
			// begin/end in a short period of time, and we only "reset" on the
			// 'ends').
			// In this event, there's really nothing to do, we're still in
			// "busy state"
			// and should start a new reset cycle once endBackgroundjob is
			// called.
		}
	}

	public Object getAdapter(Class required) {
		if (org.eclipse.wst.sse.core.util.Debug.perfTestAdapterClassLoading) {
			startPerfTime = System.currentTimeMillis();
		}
		Object result = null;
		// text editor
		if (ITextEditor.class.equals(required)) {
			result = this;
		} else if (IWorkbenchSiteProgressService.class.equals(required)) {
			return getEditorPart().getSite().getAdapter(IWorkbenchSiteProgressService.class);
		}
		// content outline page
		else if (IContentOutlinePage.class.equals(required)) {
			if (fOutlinePage == null || fOutlinePage.getControl() == null || fOutlinePage.getControl().isDisposed()) {
				ContentOutlineConfiguration cfg = createContentOutlineConfiguration();
				if (cfg != null) {
					if (cfg instanceof StructuredContentOutlineConfiguration) {
						((StructuredContentOutlineConfiguration) cfg).setEditor(this);
					}
					StructuredTextEditorContentOutlinePage outlinePage = new StructuredTextEditorContentOutlinePage();
					outlinePage.setConfiguration(cfg);
					outlinePage.setViewerSelectionManager(getViewerSelectionManager());
					outlinePage.setModel(getModel());
					fOutlinePage = outlinePage;
				}
			}
			result = fOutlinePage;
		}
		// property sheet page, but only if the input's editable
		else if (IPropertySheetPage.class.equals(required) && isEditable()) {
			if (fPropertySheetPage == null || fPropertySheetPage.getControl() == null || fPropertySheetPage.getControl().isDisposed()) {
				PropertySheetConfiguration cfg = createPropertySheetConfiguration();
				if (cfg != null) {
					if (cfg instanceof StructuredPropertySheetConfiguration) {
						((StructuredPropertySheetConfiguration) cfg).setEditor(this);
					}
					ConfigurablePropertySheetPage propertySheetPage = new ConfigurablePropertySheetPage();
					propertySheetPage.setConfiguration(cfg);
					propertySheetPage.setViewerSelectionManager(getViewerSelectionManager());
					propertySheetPage.setModel(getModel());
					fPropertySheetPage = propertySheetPage;
				}
			}
			result = fPropertySheetPage;
		} else if (ViewerSelectionManager.class.equals(required)) {
			result = getViewerSelectionManager();
		} else if (SourceEditingTextTools.class.equals(required)) {
			result = createSourceEditingTextTools();
		} else if (IToggleBreakpointsTarget.class.equals(required)) {
			result = ToggleBreakpointsTarget.getInstance();
		} else if (IShowInTargetList.class.equals(required)) {
			return new ShowInTargetListAdapter();
		} else {
			Document document = getDOMDocument();
			if (document != null && document instanceof INodeNotifier) {
				result = ((INodeNotifier) document).getAdapterFor(required);
			}
			if (result == null) {
				if (getModel() != null) {
					result = getModel().getAdapter(required);
				} else {
					result = super.getAdapter(required);
				}
			}
			// others
			if (result == null)
				result = super.getAdapter(required);
		}
		if (org.eclipse.wst.sse.core.util.Debug.perfTestAdapterClassLoading) {
			long stop = System.currentTimeMillis();
			adapterRequests++;
			adapterTime += (stop - startPerfTime);
		}
		if (org.eclipse.wst.sse.core.util.Debug.perfTestAdapterClassLoading) {
			System.out.println("Total calls to getAdapter: " + adapterRequests); //$NON-NLS-1$
			System.out.println("Total time in getAdapter: " + adapterTime); //$NON-NLS-1$
			System.out.println("Average time per call: " + (adapterTime / adapterRequests)); //$NON-NLS-1$
		}
		return result;
	}

	/**
	 * IExtendedMarkupEditor method
	 */
	public Node getCaretNode() {
		IStructuredModel model = getModel();
		if (model == null)
			return null;
		int pos = getCaretPosition();
		IndexedRegion inode = model.getIndexedRegion(pos);
		if (inode == null)
			inode = model.getIndexedRegion(pos - 1);
		return (inode instanceof Node) ? (Node) inode : null;
	}

	/**
	 * IExtendedSimpleEditor method
	 */
	public int getCaretPosition() {
		ViewerSelectionManager vsm = getViewerSelectionManager();
		if (vsm == null)
			return -1;
		// nsd_TODO: are we being overly paranoid?
		StructuredTextViewer stv = getTextViewer();
		if (stv != null && stv.getControl() != null && !stv.getControl().isDisposed()) {
			return stv.widgetOffset2ModelOffset(vsm.getCaretPosition());
		}
		return vsm.getCaretPosition();
	}

	protected String[] getConfigurationPoints() {
		String contentTypeIdentifierID = null;
		if (getModel() != null)
			contentTypeIdentifierID = getModel().getContentTypeIdentifier();
		return ConfigurationPointCalculator.getConfigurationPoints(this, contentTypeIdentifierID, ConfigurationPointCalculator.SOURCE, StructuredTextEditor.class);
	}

	/**
	 * @deprecated - will be removed in M4
	 */
	public Node getCursorNode() {
		if (getModel() != null)
			return (Node) getModel().getIndexedRegion(getCursorOffset());
		else
			return null;
	}

	/**
	 * @deprecated - will be removed in M4
	 */
	public int getCursorOffset() {
		if (hoverX >= 0 && hoverY >= 0)
			return getOffsetAtLocation(hoverX, hoverY);
		return getCaretPosition();
	}

	/**
	 * added checks to overcome bug such that if we are shutting down in an
	 * error condition, then viewer will have already been disposed.
	 */
	protected String getCursorPosition() {
		String result = null;
		// this may be too expensive in terms of
		// performance, to do this check
		// every time, just to gaurd against error
		// condition.
		// perhaps there's a better way?
		if (getSourceViewer() != null && getSourceViewer().getTextWidget() != null && !getSourceViewer().getTextWidget().isDisposed()) {
			result = super.getCursorPosition();
		} else {
			result = "0:0"; //$NON-NLS-1$
		}
		return result;
	}

	Display getDisplay() {
		return PlatformUI.getWorkbench().getDisplay();
	}

	/**
	 * IExtendedSimpleEditor method
	 */
	public IDocument getDocument() {
		// ITextViewer tv = getTextViewer();
		// return (tv != null) ? tv.getDocument() : null;
		// The TextViewer may not be available at init
		// time.
		// The right way to get the document is thru
		// DocumentProvider.
		IDocumentProvider dp = getDocumentProvider();
		return (dp != null) ? dp.getDocument(getEditorInput()) : null;
	}

	/**
	 * IExtendedMarkupEditor method
	 */
	public Document getDOMDocument() {
		IStructuredModel model = getModel();
		if (model != null) {
			return (Document) model.getAdapter(Document.class);
		}
		return null;
	}

	/**
	 * @see com.ibm.sed.edit.extension.IExtendedSimpleEditor#getEditorPart()
	 */
	public IEditorPart getEditorPart() {
		if (fEditorPart == null)
			return this;
		return fEditorPart;
	}

	/**
	 * @deprecated - will be removed in M4
	 * 
	 * used only by Search and there are alternate means besides making this
	 * API
	 * @return the IFile from the currently active editor
	 */
	public IFile getFileInEditor() {
		IStructuredModel model = getModel();
		return ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(model.getBaseLocation()));
		// (pa) this changed because FileBuffers don't use absolute location
		// plain old getFile(...) should work now (for the relative URL)
		// return
		// ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(new
		// Path(model.getBaseLocation()));
	}

	/**
	 * @deprecated - will be removed in M4
	 * @return
	 */
	protected String[] getFindOccurrencesRegionTypes() {
		return new String[0];
	}

	private InternalModelStateListener getInternalModelStateListener() {
		if (fInternalModelStateListener == null) {
			fInternalModelStateListener = new InternalModelStateListener();
		}
		return fInternalModelStateListener;
	}

	/**
	 * @deprecated - may be made protected in M4 This value is set in
	 *             initialize from input
	 */
	public IStructuredModel getModel() {
		if (getDocumentProvider() == null) {
			// this indicated an error in startup sequence
			Logger.trace(getClass().getName(), "Program Info Only: document provider was null when model requested"); //$NON-NLS-1$ //$NON-NLS-2$
		}
		boolean initialModelNull = false;
		if (fStructuredModel == null)
			initialModelNull = true;
		if (fStructuredModel == null) {
			if (getDocumentProvider() instanceof IModelProvider) {
				fStructuredModel = ((IModelProvider) getDocumentProvider()).getModel(getEditorInput());
			}
			else {
				IDocument doc = getDocument();
				if (doc instanceof IStructuredDocument) {
					IStructuredModel model = StructuredModelManager.getModelManager().getExistingModelForEdit(doc);
					if (model == null) {
						model = StructuredModelManager.getModelManager().getModelForEdit((IStructuredDocument) doc);
					}
					EditorModelUtil.addFactoriesTo(model);
					fStructuredModel = model;
				}
			}
			if (initialModelNull && fStructuredModel != null) {
				/*
				 * DMW: 9/1/2002 -- why is update called here? No change has
				 * been indicated? I'd like to remove, but will leave for now
				 * to avoid breaking this hack. Should measure/breakpoint to
				 * see how large the problem is. May cause performance
				 * problems.
				 * 
				 * DMW: 9/8/2002 -- not sure why this was here initially, but
				 * the intent/hack must have been to call update if this was
				 * the first time fStructuredModel was set. So, I added the
				 * logic to check for that "first time" case. It would appear
				 * we don't really need. may remove in future when can test
				 * more.
				 */
				update();
			}
		}
		return fStructuredModel;
	}

	/**
	 * Computes the document offset underlying the given text widget graphics
	 * coordinates.
	 * 
	 * @deprecated - only used by methods meant to be removed in M4
	 * 
	 * this method will be removed in M4
	 * 
	 * @param x
	 *            the x coordinate inside the text widget
	 * @param y
	 *            the y coordinate inside the text widget
	 * @return the document offset corresponding to the given point
	 */
	protected int getOffsetAtLocation(int x, int y) {
		StyledText styledText = getSourceViewer().getTextWidget();
		if (styledText != null && !styledText.isDisposed()) {
			try {
				int widgetOffset = styledText.getOffsetAtLocation(new Point(x, y));
				if (getSourceViewer() instanceof ITextViewerExtension5) {
					ITextViewerExtension5 extension = (ITextViewerExtension5) getSourceViewer();
					return extension.widgetOffset2ModelOffset(widgetOffset);
				}
				return widgetOffset + getSourceViewer().getVisibleRegion().getOffset();
			} catch (IllegalArgumentException e) {
				return getSourceViewer().getVisibleRegion().getLength();
			}
		}
		return getCaretPosition();
	}

	/**
	 * @deprecated - will be removed in M4
	 * 
	 * used only by Search and there are alternate means besides making this
	 * API
	 * 
	 * @return the IStructuredDocumentRegion that the text selection in the
	 *         editor resolves to, or <code>null</code> if the range covers
	 *         more than one region.
	 */
	public IStructuredDocumentRegion getSelectedDocumentRegion() {
		Point p = getSelectionRange();
		int start = p.x;
		int end = p.x + p.y;

		IDocument doc = getDocument();
		if (doc instanceof IStructuredDocument) {
			IStructuredDocument structuredDocument = (IStructuredDocument) doc;
			IStructuredDocumentRegion firstSdRegion = structuredDocument.getRegionAtCharacterOffset(start);
			IStructuredDocumentRegion secondSdRegion = structuredDocument.getRegionAtCharacterOffset(end);
			if (firstSdRegion != null && secondSdRegion != null) {
				if (firstSdRegion.equals(secondSdRegion) || firstSdRegion.getEndOffset() == end) {
					// the selection is on the same region or
					// the selection ends right on the end of the first region
					return firstSdRegion;
				}
			}
		}
		return null;
	}

	/**
	 * IExtendedMarkupEditor method
	 */
	public List getSelectedNodes() {
		ViewerSelectionManager vsm = getViewerSelectionManager();
		return (vsm != null) ? vsm.getSelectedNodes() : null;
	}

	/**
	 * @deprecated
	 * 
	 * used only by Search and there are alternate means besides making this
	 * API
	 * 
	 * will be removed in M4
	 * 
	 * @param sdRegion
	 *            the IStructuredDocumentRegion that you want to check
	 *            selection on
	 * @return the ITextRegion that the text selection in the editor resolves
	 *         to, or <code>null</code> if the range covers more than one
	 *         region or none.
	 */
	public ITextRegion getSelectedTextRegion(IStructuredDocumentRegion sdRegion) {
		Assert.isNotNull(sdRegion);

		Point p = getSelectionRange();
		int start = p.x;
		int end = p.x + p.y;

		ITextRegion first = sdRegion.getRegionAtCharacterOffset(start);
		ITextRegion second = sdRegion.getRegionAtCharacterOffset(end);
		if (first != null && second != null) {
			if (first.equals(second) || sdRegion.getEndOffset(first) == end) {
				// the selection is on the same region
				// the selection ends right on the end of the first region
				return first;
			}
		}
		return null;
	}

	/**
	 * IExtendedSimpleEditor method
	 */
	public Point getSelectionRange() {
		ITextViewer tv = getSourceViewer();
		if (tv == null)
			return new Point(-1, -1);
		else
			return tv.getSelectedRange();
	}

	/**
	 * @deprecated - will be removed in M4
	 */
	public SpellCheckTarget getSpellCheckTarget() {
		return null;
	}

	private IStatusLineManager getStatusLineManager() {
		IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
		if (window == null)
			return null;
		IWorkbenchPage page = window.getActivePage();
		if (page == null)
			return null;
		IEditorPart editor = page.getActiveEditor();
		if (editor == null)
			return null;
		IEditorActionBarContributor contributor = editor.getEditorSite().getActionBarContributor();
		if (contributor instanceof EditorActionBarContributor) {
			return ((EditorActionBarContributor) contributor).getActionBars().getStatusLineManager();
		}
		return null;
	}

	/**
	 * Returns the editor's source viewer. This method was created to expose
	 * the protected final getSourceViewer() method.
	 * 
	 * @return the editor's source viewer
	 */
	public StructuredTextViewer getTextViewer() {
		return (StructuredTextViewer) getSourceViewer();
	}

	/**
	 * @deprecated
	 * 
	 * will be made protected or removed in M4
	 * 
	 * @return
	 */
	public ViewerSelectionManager getViewerSelectionManager() {
		if (getTextViewer() != null)
			return getTextViewer().getViewerSelectionManager();
		return null;
	}

	protected void handleCursorPositionChanged() {
		super.handleCursorPositionChanged();
		updateStatusField(StructuredTextEditorActionConstants.STATUS_CATEGORY_OFFSET);
	}

	protected void handleElementContentAboutToBeReplaced(Object element) {
		// do nothing
	}

	protected void handleElementContentReplaced(Object element) {
		// do nothing, the model provider should reload the
		// model
	}

	protected void handleElementDeleted(Object element) {
		// do nothing, the superclass will close() us
	}

	protected void handleElementDirtyStateChanged(Object element, boolean isDirty) {
		// do nothing, the superclass will fire a proeprty
		// change
	}

	protected void handleElementMoved(Object oldElement, Object newElement) {
		// do nothing, the editor input will be changed
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.texteditor.AbstractTextEditor#handlePreferenceStoreChanged(org.eclipse.jface.util.PropertyChangeEvent)
	 */
	protected void handlePreferenceStoreChanged(PropertyChangeEvent event) {
		String property = event.getProperty();

		if (EditorPreferenceNames.EDITOR_TEXT_HOVER_MODIFIERS.equals(property)) {
			updateHoverBehavior();
		}

		if (IStructuredTextFoldingProvider.FOLDING_ENABLED.equals(property)) {
			if (getSourceViewer() instanceof ProjectionViewer) {
				// install projection support if it has not even been
				// installed yet
				if (isFoldingEnabled() && (fProjectionSupport == null) && (fProjectionModelUpdater == null)) {
					installProjectionSupport();
				}
				ProjectionViewer pv = (ProjectionViewer) getSourceViewer();
				if (pv.isProjectionMode() != isFoldingEnabled()) {
					if (pv.canDoOperation(ProjectionViewer.TOGGLE))
						pv.doOperation(ProjectionViewer.TOGGLE);
				}
			}
			return;
		}
		super.handlePreferenceStoreChanged(event);
	}

	/**
	 * @return
	 */
	private boolean inBusyState() {
		return fBusyState;
	}

	public void init(IEditorSite site, IEditorInput input) throws PartInitException {
		// if we've gotten an error elsewhere, before
		// we've actually opened, then don't open.
		if (shouldClose) {
			setSite(site);
			close(false);
		} else {
			super.init(site, input);
		}
	}

	public void initializeDocumentProvider(IDocumentProvider documentProvider) {
		if (getDocumentProvider() != null)
			getDocumentProvider().removeElementStateListener(internalElementStateListener);
		if (documentProvider != null) {
			setDocumentProvider(documentProvider);
		}
		if (documentProvider != null)
			documentProvider.addElementStateListener(internalElementStateListener);
	}

	protected void initializeDrop(ITextViewer textViewer) {
		int operations = DND.DROP_COPY | DND.DROP_MOVE;
		fDropTarget = new DropTarget(textViewer.getTextWidget(), operations);
		fDropAdapter = new ReadOnlyAwareDropTargetAdapter();
		fDropAdapter.setTargetEditor(this);
		fDropAdapter.setTargetIDs(getConfigurationPoints());
		fDropAdapter.setTextViewer(textViewer);
		fDropTarget.setTransfer(fDropAdapter.getTransfers());
		fDropTarget.addDropListener(fDropAdapter);
	}

	protected void initializeEditor() {
		super.initializeEditor();
		// FIXME: here's where to add back in our custom encoding support
		fEncodingSupport = null;
		setPreferenceStore(createCombinedPreferenceStore());

		setRangeIndicator(new DefaultRangeIndicator());
		setEditorContextMenuId(EDITOR_CONTEXT_MENU_ID);
		initializeDocumentProvider(null);
		// set the infopop for source viewer
		String helpId = getHelpContextId();
		// no infopop set or using default text editor help, use default
		if (helpId == null || ITextEditorHelpContextIds.TEXT_EDITOR.equals(helpId))
			helpId = IHelpContextIds.XML_SOURCE_VIEW_HELPID;
		setHelpContextId(helpId);
		// defect 203158 - disable ruler context menu for
		// beta
		// setRulerContextMenuId(RULER_CONTEXT_MENU_ID);
		configureInsertMode(SMART_INSERT, true);

		// enable the base source editor activity when editor opens
		try {
			// FIXME: - commented out to avoid minor dependancy during
			// transition to org.eclipse
			// WTPActivityBridge.getInstance().enableActivity(CORE_SSE_ACTIVITY_ID,
			// true);
		} catch (Exception t) {
			// if something goes wrong with enabling activity, just log the
			// error but dont
			// have it break the editor
			Logger.log(Logger.WARNING_DEBUG, t.getMessage(), t);
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.editors.text.TextEditor#initializeKeyBindingScopes()
	 */
	protected void initializeKeyBindingScopes() {
		setKeyBindingScopes(new String[]{EDITOR_KEYBINDING_SCOPE_ID});
	}

	/**
	 * Initializes the editor's source viewer and other items that were source
	 * viewer-dependent.
	 */
	private void initializeSourceViewer() {
		if (getViewerSelectionManager() != null)
			getViewerSelectionManager().setModel(getModel());

		computeAndSetDoubleClickAction(getModel());

		IAction contentAssistAction = getAction(StructuredTextEditorActionConstants.ACTION_NAME_CONTENTASSIST_PROPOSALS);
		if (contentAssistAction instanceof IUpdate) {
			((IUpdate) contentAssistAction).update();
		}
		IAction openHyperlinkAction = getAction(StructuredTextEditorActionConstants.ACTION_NAME_OPEN_FILE);
		if (openHyperlinkAction instanceof OpenHyperlinkAction) {
			((OpenHyperlinkAction) openHyperlinkAction).setHyperlinkDetectors(getSourceViewerConfiguration().getHyperlinkDetectors(getSourceViewer()));
		}

		// do not even install projection support until folding is actually
		// enabled
		if (isFoldingEnabled()) {
			installProjectionSupport();
		}
	}

	/**
	 * Performs any necessary setup for a new or unconfigured
	 * StructuredTextViewerConfiguration
	 * 
	 * @param configuration
	 */
	void initializeSourceViewerConfiguration(StructuredTextViewerConfiguration configuration) {
		configuration.setEditorPart(this);
		configuration.setPreferenceStore(getPreferenceStore());

		IResource resource = null;
		IFile file = (IFile) getEditorInput().getAdapter(IFile.class);
		if (file != null) {
			resource = file.getProject();
		}
		configuration.configureOn(resource);
	}

	protected void initSourceViewer(StructuredTextViewer sourceViewer) {
		// ensure decoration support is configured
		getSourceViewerDecorationSupport(sourceViewer);
		fMouseTracker = new MouseTracker();
		fMouseTracker.start(sourceViewer.getTextWidget());
		initializeDrop(sourceViewer);
	}


	protected void installEncodingSupport() {
		// TODO: install our custom support that can
		// update document appropriately
		// super.installEncodingSupport();
	}

	/**
	 * Install everything necessary to get document folding working and enable
	 * document folding
	 */
	private void installProjectionSupport() {
		ProjectionViewer projectionViewer = (ProjectionViewer) getSourceViewer();

		fProjectionSupport = new ProjectionSupport(projectionViewer, getAnnotationAccess(), getSharedColors());
		fProjectionSupport.addSummarizableAnnotationType("org.eclipse.ui.workbench.texteditor.error"); //$NON-NLS-1$
		fProjectionSupport.addSummarizableAnnotationType("org.eclipse.ui.workbench.texteditor.warning"); //$NON-NLS-1$
		fProjectionSupport.setHoverControlCreator(new IInformationControlCreator() {
			public IInformationControl createInformationControl(Shell parent) {
				return new DefaultInformationControl(parent);
			}
		});
		fProjectionSupport.install();

		IStructuredTextFoldingProvider updater = null;
		ExtendedConfigurationBuilder builder = ExtendedConfigurationBuilder.getInstance();
		String[] ids = getConfigurationPoints();
		for (int i = 0; updater == null && i < ids.length; i++) {
			updater = (IStructuredTextFoldingProvider) builder.getConfiguration(IStructuredTextFoldingProvider.ID, ids[i]);
		}

		fProjectionModelUpdater = updater;
		if (fProjectionModelUpdater != null)
			fProjectionModelUpdater.install(projectionViewer);

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

	/**
	 * @deprecated - will be removed in M4
	 * @param type
	 * @return
	 */
	public boolean isFindOccurrencesRegionType(String type) {
		String[] accept = getFindOccurrencesRegionTypes();
		for (int i = 0; i < accept.length; i++) {
			if (accept[i].equals(type))
				return true;
		}
		return false;
	}


	/**
	 * Return whether document folding should be enabled according to the
	 * preference store settings.
	 * 
	 * @return <code>true</code> if document folding should be enabled
	 */
	private boolean isFoldingEnabled() {
		IPreferenceStore store = getPreferenceStore();
		// check both preference store and vm argument
		return (store.getBoolean(IStructuredTextFoldingProvider.FOLDING_ENABLED) && (System.getProperty("org.eclipse.wst.sse.ui.foldingenabled") != null)); //$NON-NLS-1$
	}

	/**
	 * Returns whether the given annotation type is configured as a target
	 * type for the "Go to Next/Previous Annotation" actions. Copied from
	 * org.eclipse.jdt.internal.ui.javaeditor.JavaEditor
	 * 
	 * @param type
	 *            the annotation type
	 * @return <code>true</code> if this is a target type,
	 *         <code>false</code> otherwise
	 * @since 3.0
	 */
	protected boolean isNavigationTargetType(Annotation annotation) {
		Preferences preferences = EditorsUI.getPluginPreferences();
		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 && preferences.getBoolean(key));
	}

	/*
	 * @see IEditorPart#isSaveOnCloseNeeded()
	 */
	public boolean isSaveOnCloseNeeded() {
		if (getModel() == null)
			return false;
		return getModel().isSaveNeeded();
	}

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

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

			super.performRevert();

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

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

	/**
	 * This method was made public for use by editors that use
	 * StructuredTextEditor (like PageDesigner)
	 * 
	 * @see org.eclipse.ui.texteditor.AbstractTextEditor#rememberSelection()
	 */
	public void rememberSelection() {
		super.rememberSelection();
	}

	/**
	 * both starts and resets the busy state timer
	 */
	private void resetBusyState() {
		// reset the "busy" timeout
		if (fBusyTimer != null) {
			fBusyTimer.cancel();
		}
		startBusyTimer();
	}

	/**
	 * This method was made public for use by editors that use
	 * StructuredTextEditor (like PageDesigner)
	 * 
	 * @see org.eclipse.ui.texteditor.AbstractTextEditor#restoreSelection()
	 */
	public void restoreSelection() {
		// catch odd case where source viewer has no text
		// widget (defect
		// 227670)
		if ((getSourceViewer() != null) && (getSourceViewer().getTextWidget() != null))
			super.restoreSelection();
	}

	protected void rulerContextMenuAboutToShow(IMenuManager menu) {
		boolean debuggingAvailable = BreakpointProviderBuilder.getInstance().isAvailable(getModel().getContentTypeIdentifier(), BreakpointRulerAction.getFileExtension(getEditorInput()));
		if (debuggingAvailable) {
			menu.add(getAction(ActionDefinitionIds.TOGGLE_BREAKPOINTS));
			menu.add(getAction(ActionDefinitionIds.MANAGE_BREAKPOINTS));
			menu.add(getAction(ActionDefinitionIds.EDIT_BREAKPOINTS));
			menu.add(new Separator());
		}
		super.rulerContextMenuAboutToShow(menu);
		addExtendedRulerContextMenuActions(menu);
	}

	/**
	 * Overridden to expose part activation handling for multi-page editors
	 * 
	 * @see org.eclipse.ui.texteditor.AbstractTextEditor#safelySanityCheckState(org.eclipse.ui.IEditorInput)
	 */
	public void safelySanityCheckState(IEditorInput input) {
		super.safelySanityCheckState(input);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.texteditor.AbstractTextEditor#selectAndReveal(int,
	 *      int, int, int)
	 */
	protected void selectAndReveal(int selectionStart, int selectionLength, int revealStart, int revealLength) {
		super.selectAndReveal(selectionStart, selectionLength, revealStart, revealLength);
		getTextViewer().notifyViewerSelectionManager(selectionStart, selectionLength);
	}

	/**
	 * Ensure that the correct IDocumentProvider is used. For direct models, a
	 * special provider is used. For StorageEditorInputs, use a custom
	 * provider that creates a usable ResourceAnnotationModel. For everything
	 * else, use the base support.
	 * 
	 * @see org.eclipse.ui.texteditor.AbstractDecoratedTextEditor#setDocumentProvider(org.eclipse.ui.IEditorInput)
	 */
	protected void setDocumentProvider(IEditorInput input) {
		if (input instanceof IStructuredModel) {
			// largely untested
			setDocumentProvider(StructuredModelDocumentProvider.getInstance());
		} else if (input instanceof IStorageEditorInput && !(input instanceof IFileEditorInput)) {
			setDocumentProvider(StorageModelProvider.getInstance());
		} else {
			super.setDocumentProvider(input);
		}
	}

	public void setEditorPart(IEditorPart editorPart) {
		fEditorPart = editorPart;
	}

	/**
	 * @deprecated - Clients should use .getAdapter(Control) to get the text
	 *             viewer control and set its help context. Will be removed in
	 *             M4.
	 * 
	 * We expose this normally protected method so clients can provide their
	 * own help.
	 * 
	 * @param helpContextId
	 *            the help context id
	 */
	public void setHelpContextId(String helpContextId) {
		// used by (requested by) WSED
		super.setHelpContextId(helpContextId);
		// allows help to be set at any time (not just on AbstractTextEditor's
		// creation)
		if ((getHelpContextId() != null) && (getSourceViewer() != null) && (getSourceViewer().getTextWidget() != null)) {
			IWorkbenchHelpSystem helpSystem = SSEUIPlugin.getDefault().getWorkbench().getHelpSystem();
			helpSystem.setHelp(getSourceViewer().getTextWidget(), getHelpContextId());
		}
	}

	/**
	 * @deprecated - use setInput as if we were a text editor
	 * 
	 * Note: this weird API, setModel which takes input as parameter. Is
	 * provided for those editors which don't otherwise have to know about
	 * models's. (Is hard/impossible to override the setInput method.)
	 */
	public void setModel(IFileEditorInput input) {
		// Assert.isNotNull(getDocumentProvider());
		// if (fStructuredModel != null) {
		// if (getDocument() != null) {
		// getDocument().removeDocumentListener(this);
		// fStructuredModel.removeModelStateListener(getInternalModelStateListener());
		// }
		// }
		// if (!(getDocumentProvider() instanceof FileModelProvider)) {
		// initializeDocumentProvider(FileModelProvider.getInstance());
		// }
		// // ((FileModelProvider)
		// // getDocumentProvider()).createModelInfo(input);
		// // fStructuredModel = ((FileModelProvider)
		// // getDocumentProvider()).getModel(input);
		// // model will be null in some error conditions.
		// if (fStructuredModel == null) {
		// close(false);
		// }
		// // DMW: checked for site after moving to 3/22
		// // (2.1M4) Eclipse base.
		// /// Later code in super classes were causing NPE's
		// // because site, etc.,
		// // hasn't been
		// // initialized yet. If site is still null at this
		// // point, we are
		// // assuming
		// // setInput and update are called later, perhaps
		// // elsewhere.
		// // But if site is not null (such as in DTD Editor)
		// // then setInput and
		// // update must
		// // be called here.
		// // if (getSite() != null) {
		// setInput(input);
		// fStructuredModel = ((FileModelProvider)
		// getDocumentProvider()).getModel(input);
		// if (fStructuredModel != null) {
		// getDocument().addDocumentListener(this);
		// fStructuredModel.addModelStateListener(getInternalModelStateListener());
		// }
		// // update() should be called whenever the model is
		// // set or changed
		// update();
		// // }
		setInput(input);
	}

	/**
	 * Sets the model field within this editor, use only when: 1) there is no
	 * IEditorInput (very special case, not well tested) 2) there is an
	 * IEditorInput but the corresponding model needs to be set separately
	 * 
	 * @deprecated - this is a laregely untested usage
	 */
	public void setModel(IStructuredModel newModel) {
		Assert.isNotNull(getDocumentProvider());
		if (fStructuredModel != null) {
			if (fStructuredModel.getStructuredDocument() != null) {
				fStructuredModel.getStructuredDocument().removeDocumentListener(this);
			}
			fStructuredModel.removeModelStateListener(getInternalModelStateListener());
		}
		fStructuredModel = newModel;
		if (fStructuredModel != null) {
			if (fStructuredModel.getStructuredDocument() != null) {
				fStructuredModel.getStructuredDocument().addDocumentListener(this);
			}
			fStructuredModel.addModelStateListener(getInternalModelStateListener());
		}
		// update() should be called whenever the model is
		// set or changed
		update();
	}

	/**
	 * @deprecated - initialize with a document provider and use setInput or
	 *             setModel(IStructuredModel)
	 * @param newModel
	 * @param input
	 */
	public void setModel(IStructuredModel newModel, IFileEditorInput input) {
		// _setAnnotationModel(input);
		// setModel(newModel);
		Assert.isNotNull(getDocumentProvider());
		if (fStructuredModel != null) {
			fStructuredModel.removeModelStateListener(getInternalModelStateListener());
			if (fStructuredModel.getStructuredDocument() != null) {
				fStructuredModel.getStructuredDocument().removeDocumentListener(this);
			}
		}
		fStructuredModel = newModel;
		// setInput in super will allow titles to be
		// updated, etc.
		setInput(input);
		if (fStructuredModel != null) {
			if (fStructuredModel.getStructuredDocument() != null) {
				fStructuredModel.getStructuredDocument().addDocumentListener(this);
			}
			fStructuredModel.addModelStateListener(getInternalModelStateListener());
		}
		// update() should be called whenever the model is
		// set or changed
		update();
	}

	/**
	 * Sets the editor's source viewer configuration which it uses to
	 * configure it's internal source viewer. This method was overwritten so
	 * that viewer configuration could be set after editor part was created.
	 */
	protected void setSourceViewerConfiguration(SourceViewerConfiguration config) {
		super.setSourceViewerConfiguration(config);
		StructuredTextViewer stv = getTextViewer();
		if (stv != null) {
			// there should be no need to unconfigure
			// before configure because
			// configure will
			// also unconfigure before configuring
			stv.unconfigure();
			stv.configure(config);
		}
	}

	/**
	 * Overridden to allow custom tab title for multi-page editors
	 * 
	 * @see org.eclipse.ui.part.WorkbenchPart#setTitle(java.lang.String)
	 */
	public void setTitle(String title) {
		super.setTitle(title);
	}

	public void showBusy(boolean busy) {
		if (busy) {
			fRememberTitle = getPartName();
			// update title and/or fonts and/or background
			//
			// temp solution, for testing, uses "busy"
			setPartName("busy");
		} else {
			// reset to what it was
			setPartName(fRememberTitle);
		}
	}

	private void startBusyTimer() {
		// TODO: we need a resetable timer, so not so
		// many created
		fBusyTimer = new Timer(true);
		fBusyTimer.schedule(new TimeOutExpired(), BUSY_STATE_DELAY);
	}


	private void statusError(IStatus status) {
		statusError(status.getMessage());
		ErrorDialog.openError(getSite().getShell(), null, null, status);
	}

	private void statusError(String message) {
		IStatusLineManager manager = getStatusLineManager();
		if (manager == null)
			return;
		manager.setErrorMessage(message);
		getSite().getShell().getDisplay().beep();
	}

	/**
	 * update() should be called whenever the model is set or changed (as in
	 * swapped)
	 */
	public void update() {
		if (fOutlinePage != null && fOutlinePage instanceof StructuredTextEditorContentOutlinePage) {
			ContentOutlineConfiguration cfg = createContentOutlineConfiguration();
			if (cfg instanceof StructuredContentOutlineConfiguration) {
				((StructuredContentOutlineConfiguration) cfg).setEditor(this);
			}
			((StructuredTextEditorContentOutlinePage) fOutlinePage).setModel(getModel());
			((StructuredTextEditorContentOutlinePage) fOutlinePage).setViewerSelectionManager(getViewerSelectionManager());
			((StructuredTextEditorContentOutlinePage) fOutlinePage).setConfiguration(cfg);
		}
		if (fPropertySheetPage != null && fPropertySheetPage instanceof ConfigurablePropertySheetPage) {
			PropertySheetConfiguration cfg = createPropertySheetConfiguration();
			if (cfg instanceof StructuredPropertySheetConfiguration) {
				((StructuredPropertySheetConfiguration) cfg).setEditor(this);
			}
			((ConfigurablePropertySheetPage) fPropertySheetPage).setModel(getModel());
			((ConfigurablePropertySheetPage) fPropertySheetPage).setViewerSelectionManager(getViewerSelectionManager());
			((ConfigurablePropertySheetPage) fPropertySheetPage).setConfiguration(cfg);
		}
		if (getViewerSelectionManager() != null)
			getViewerSelectionManager().setModel(getModel());
		disposeModelDependentFields();

		fShowInTargetIds = createShowInTargetIds();

		// setSourceViewerConfiguration() was called once
		// in
		// StructuredTextMultiPageEditorPart.createSourcePage()
		// to set the SourceViewerConfiguration first so
		// the text editor won't
		// use the default configuration first
		// and switch to the
		// StructuredTextViewerConfiguration later.
		// However, the source viewer was not created yet
		// at the time. Need to
		// call setSourceViewerConfiguration() again here
		// so getSourceViewer().configure(configuration) in
		// setSourceViewerConfiguration() will be called.
		// DMW: removed setSouceViewerConfiguration since
		// shouldn't need the
		// general case
		// an longer, but added 'updateConfiguration' so it
		// can still be
		// sensitive
		// to resource/model changes.
		// setSourceViewerConfiguration();
		updateSourceViewerConfiguration();
		// (nsd) we never change it, so why null it out?
		// else {
		// super.setPreferenceStore(null);
		// }
		createModelDependentFields();
		computeAndSetDoubleClickAction(getModel());
	}

	/**
	 * Updates all content dependent actions.
	 */
	protected void updateContentDependentActions() {
		super.updateContentDependentActions();
		// super.updateContentDependentActions only updates
		// the enable/disable
		// state of all
		// the content dependent actions.
		// StructuredTextEditor's undo and redo actions
		// have a detail label and
		// description.
		// They needed to be updated.
		if (!fEditorDisposed)
			updateMenuText();
	}

	private void updateEncodingMemento() {
		boolean failed = false;
		if (getModel() != null) {
			IStructuredDocument doc = getModel().getStructuredDocument();
			EncodingMemento memento = doc.getEncodingMemento();
			IDocumentCharsetDetector detector = getModel().getModelHandler().getEncodingDetector();
			if (memento != null && detector != null)
				detector.set(doc);
			try {
				detector.getEncoding();
			} catch (IOException e) {
				failed = true;
			}
			// be sure to use the new instance
			// but only if no exception occurred.
			// (we may find cases we need to do more error recover there)
			// should be near impossible to get IOException from processing
			// the
			// *document*
			if (!failed) {
				doc.setEncodingMemento(memento);
			}
		}
	}

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

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

			String t = types[i];

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

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

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


	protected void updateMenuText() {
		if (fStructuredModel != null && !fStructuredModel.isModelStateChanging() && getTextViewer().getTextWidget() != null) {
			// performance: don't force an update of the action bars unless
			// required as it is expensive
			String previousUndoText = null;
			String previousUndoDesc = null;
			String previousRedoText = null;
			String previousRedoDesc = null;
			boolean updateActions = false;
			IAction undoAction = getAction(ITextEditorActionConstants.UNDO);
			IAction redoAction = getAction(ITextEditorActionConstants.REDO);
			if (undoAction != null) {
				previousUndoText = undoAction.getText();
				previousUndoDesc = undoAction.getDescription();
				updateActions = updateActions || previousUndoText == null || previousUndoDesc == null;
				undoAction.setText(UNDO_ACTION_TEXT_DEFAULT);
				undoAction.setDescription(UNDO_ACTION_DESC_DEFAULT);
			}
			if (redoAction != null) {
				previousRedoText = redoAction.getText();
				previousRedoDesc = redoAction.getDescription();
				updateActions = updateActions || previousRedoText == null || previousRedoDesc == null;
				redoAction.setText(REDO_ACTION_TEXT_DEFAULT);
				redoAction.setDescription(REDO_ACTION_DESC_DEFAULT);
			}
			if (fStructuredModel.getUndoManager() != null) {
				IStructuredTextUndoManager undoManager = fStructuredModel.getUndoManager();
				// get undo command
				Command undoCommand = undoManager.getUndoCommand();
				// set undo label and description
				undoAction.setEnabled(undoManager.undoable());
				if (undoCommand != null) {
					String label = undoCommand.getLabel();
					if (label != null) {
						String customText = MessageFormat.format(UNDO_ACTION_TEXT, new String[]{label});
						updateActions = updateActions || customText == null || previousUndoText == null || !customText.equals(previousUndoText);
						undoAction.setText(customText);
					}
					String desc = undoCommand.getDescription();
					if (desc != null) {
						String customDesc = MessageFormat.format(UNDO_ACTION_DESC, new String[]{desc});
						updateActions = updateActions || customDesc == null || previousRedoDesc == null || !customDesc.equals(previousUndoDesc);
						undoAction.setDescription(customDesc);
					}
				}
				// get redo command
				Command redoCommand = undoManager.getRedoCommand();
				// set redo label and description
				redoAction.setEnabled(undoManager.redoable());
				if (redoCommand != null) {
					String label = redoCommand.getLabel();
					if (label != null) {
						String customText = MessageFormat.format(REDO_ACTION_TEXT, new String[]{label});
						updateActions = updateActions || customText == null || previousRedoText == null || !customText.equals(previousRedoText);
						redoAction.setText(customText);
					}
					String desc = redoCommand.getDescription();
					if (desc != null) {
						String customDesc = MessageFormat.format(REDO_ACTION_DESC, new String[]{desc});
						updateActions = updateActions || customDesc == null || previousRedoDesc == null || !customDesc.equals(previousRedoDesc);
						redoAction.setDescription(customDesc);
					}
				}
			}
			// tell the action bars to update
			if (updateActions) {
				if (getEditorSite().getActionBars() != null) {
					getEditorSite().getActionBars().updateActionBars();
				} else if (getEditorPart() != null && getEditorPart().getEditorSite().getActionBars() != null) {
					getEditorPart().getEditorSite().getActionBars().updateActionBars();
				}
			}
		}
	}

	protected void updateSourceViewerConfiguration() {
		SourceViewerConfiguration configuration = getSourceViewerConfiguration();
		// no need to update source viewer configuration if one does not exist
		// yet
		if (configuration == null) {
			return;
		}

		// structuredtextviewer only works with
		// structuredtextviewerconfiguration
		if (!(configuration instanceof StructuredTextViewerConfiguration)) {
			configuration = createSourceViewerConfiguration();
			setSourceViewerConfiguration(configuration);
		} else {
			StructuredTextViewerConfiguration newViewerConfiguration = createSourceViewerConfiguration();
			if (!((StructuredTextViewerConfiguration) configuration).getDeclaringID().equals(newViewerConfiguration.getDeclaringID())) {
				// d282894 use newViewerConfiguration
				configuration = newViewerConfiguration;
				setSourceViewerConfiguration(configuration);
			}

			// update the configuration's resource
			IResource resource = null;
			if (getEditorInput() instanceof IFileEditorInput) {
				resource = ((IFileEditorInput) getEditorInput()).getFile();
				if (resource.getType() != IResource.PROJECT)
					resource = resource.getProject();
				((StructuredTextViewerConfiguration) configuration).configureOn(resource);
			}
		}

		if (getSourceViewer() != null) {
			getSourceViewer().configure(configuration);
			IAction contentAssistAction = getAction(StructuredTextEditorActionConstants.ACTION_NAME_CONTENTASSIST_PROPOSALS);
			if (contentAssistAction instanceof IUpdate) {
				((IUpdate) contentAssistAction).update();
			}
			IAction openHyperlinkAction = getAction(StructuredTextEditorActionConstants.ACTION_NAME_OPEN_FILE);
			if (openHyperlinkAction instanceof OpenHyperlinkAction) {
				((OpenHyperlinkAction) openHyperlinkAction).setHyperlinkDetectors(getSourceViewerConfiguration().getHyperlinkDetectors(getSourceViewer()));
			}
		}
		// eventually will replace above with something
		// like what follows
		// it, but some of our "processors" require too
		// much initialization
		// during configuration.
		// SourceViewerConfiguration configuration =
		// getSourceViewerConfiguration();
		//
		// // should always be an instance of our special
		// configuration, but
		// just in case
		// // not, we'll do nothing if it isn't.
		// if (configuration!= null && configuration
		// instanceof
		// StructuredTextViewerConfiguration) {
		//
		// IResource resource = null;
		// if (getEditorInput() instanceof
		// IFileEditorInput) {
		// resource = ((IFileEditorInput)
		// getEditorInput()).getFile();
		// if (resource.getType() != IResource.PROJECT)
		// resource = resource.getProject();
		// // note: configureOn is responsible for updating
		// what ever
		// // in our configuration is sensitive to resource
		// ((StructuredTextViewerConfiguration)
		// configuration).configureOn(resource);
		// }
		//
		// }
	}

	protected void updateStatusField(String category) {
		super.updateStatusField(category);

		if (category == null)
			return;

		if (StructuredTextEditorActionConstants.STATUS_CATEGORY_OFFSET.equals(category)) {
			IStatusField field = getStatusField(category);
			if (field != null) {
				Point selection = getTextViewer().getTextWidget().getSelection();
				int offset1 = widgetOffset2ModelOffset(getSourceViewer(), selection.x);
				int offset2 = widgetOffset2ModelOffset(getSourceViewer(), selection.y);
				String text = null;
				if (offset1 != offset2)
					text = "[" + offset1 + "-" + offset2 + "]";
				else
					text = "[ " + offset1 + " ]";
				field.setText(text == null ? fErrorLabel : text);
			}
		}
	}

	/**
	 * @deprecated - will be removed in M4 Use getDocumentProvider and
	 *             IDocumentProviderExtension instead
	 */
	public IStatus validateEdit(Shell context) {
		IStatus status = STATUS_OK;
		IEditorInput input = getEditorInput();
		if (input instanceof IFileEditorInput) {
			if (input == null) {
				String msg = SSEUIPlugin.getResourceString("%Error_opening_file_UI_"); //$NON-NLS-1$
				status = new Status(IStatus.ERROR, SSEUIPlugin.ID, IStatus.INFO, msg, null);
			} else {
				validateState(input);
				sanityCheckState(input);
				if (isEditorInputReadOnly()) {
					String fname = input.getName();
					if (input instanceof IStorageEditorInput) {
						try {
							IStorage s = ((IStorageEditorInput) input).getStorage();
							if (s != null) {
								IPath path = s.getFullPath();
								if (path != null) {
									fname += path.toString();
								} else {
									fname += s.getName();
								}
							}
						} catch (CoreException e) { // IStorage is just for
							// file name,
							// and it's an optional,
							// therefore
							// it is safe to ignore this
							// exception.
						}
					}
					String msg = SSEUIPlugin.getResourceString("%_UI_File_is_read_only", new Object[]{fname}); //$NON-NLS-1$ = "File {0}is read-only."
					status = new Status(IStatus.ERROR, SSEUIPlugin.ID, IStatus.INFO, msg, null);
				}
			}
		}
		return status;
	}

	protected void validateState(IEditorInput input) {
		IDocumentProvider provider = getDocumentProvider();
		if (provider instanceof IDocumentProviderExtension) {
			IDocumentProviderExtension extension = (IDocumentProviderExtension) provider;
			try {
				boolean wasReadOnly = isEditorInputReadOnly();
				extension.validateState(input, getSite().getShell());
				if (getSourceViewer() != null)
					getSourceViewer().setEditable(isEditable());
				if (wasReadOnly != isEditorInputReadOnly())
					updateStateDependentActions();
			} catch (CoreException x) {
				ILog log = Platform.getLog(Platform.getBundle(PlatformUI.PLUGIN_ID));
				log.log(x.getStatus());
				statusError(x.getStatus());
			}
		}
	}
}
