/*******************************************************************************
 * 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.internal;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IAutoEditStrategy;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IDocumentAdapter;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextViewerExtension2;
import org.eclipse.jface.text.Region;
import org.eclipse.jface.text.TextSelection;
import org.eclipse.jface.text.contentassist.IContentAssistant;
import org.eclipse.jface.text.formatter.FormattingContext;
import org.eclipse.jface.text.formatter.FormattingContextProperties;
import org.eclipse.jface.text.formatter.IContentFormatterExtension;
import org.eclipse.jface.text.formatter.IFormattingContext;
import org.eclipse.jface.text.hyperlink.IHyperlinkDetector;
import org.eclipse.jface.text.information.IInformationPresenter;
import org.eclipse.jface.text.projection.ProjectionDocument;
import org.eclipse.jface.text.reconciler.IReconciler;
import org.eclipse.jface.text.source.IAnnotationModel;
import org.eclipse.jface.text.source.IOverviewRuler;
import org.eclipse.jface.text.source.IVerticalRuler;
import org.eclipse.jface.text.source.SourceViewerConfiguration;
import org.eclipse.jface.text.source.projection.ProjectionViewer;
import org.eclipse.jface.viewers.ContentViewer;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.VerifyEvent;
import org.eclipse.swt.events.VerifyListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Event;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.texteditor.IEditorStatusLine;
import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
import org.eclipse.wst.sse.core.internal.cleanup.StructuredContentCleanupHandler;
import org.eclipse.wst.sse.core.internal.provisional.IndexedRegion;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
import org.eclipse.wst.sse.core.internal.undo.IDocumentSelectionMediator;
import org.eclipse.wst.sse.core.internal.undo.IStructuredTextUndoManager;
import org.eclipse.wst.sse.core.internal.undo.UndoDocumentEvent;
import org.eclipse.wst.sse.ui.internal.provisional.StructuredTextViewerConfiguration;
import org.eclipse.wst.sse.ui.internal.provisional.style.IHighlighter;
import org.eclipse.wst.sse.ui.internal.reconcile.StructuredRegionProcessor;
import org.eclipse.wst.sse.ui.internal.util.PlatformStatusLineUtil;
import org.eclipse.wst.sse.ui.internal.view.events.INodeSelectionListener;
import org.eclipse.wst.sse.ui.internal.view.events.NodeSelectionChangedEvent;
import org.w3c.dom.Attr;
import org.w3c.dom.Node;

public class StructuredTextViewer extends ProjectionViewer implements IDocumentSelectionMediator {

	/**
	 * Internal verify listener.
	 */
	class TextVerifyListener implements VerifyListener {

		/**
		 * Indicates whether verify events are forwarded or ignored.
		 * 
		 * @plannedfor 2.0
		 */
		private boolean fForward = true;

		/**
		 * Tells the listener to forward received events.
		 * 
		 * @param forward
		 *            <code>true</code> if forwarding should be enabled.
		 * @plannedfor 2.0
		 */
		public void forward(boolean forward) {
			fForward = forward;
		}

		/*
		 * @see VerifyListener#verifyText(VerifyEvent)
		 */
		public void verifyText(VerifyEvent e) {
			if (fForward) {
				handleVerifyEvent(e);
			}
		}
	}

	/**
	 * A private delegate class to move INodeSelectionListener and
	 * IDoubleClickListener off of the viewer's APIs
	 */
	private class InternalSelectionListener implements INodeSelectionListener, IDoubleClickListener {
		public void doubleClick(DoubleClickEvent event) {
			handleDoubleClick(event);
		}

		public void nodeSelectionChanged(NodeSelectionChangedEvent event) {
			handleNodeSelectionChanged(event);
		}
	}

	/** Text operation codes */
	private static final int BASE = ProjectionViewer.EXPAND_ALL; // see
	// ProjectionViewer.EXPAND_ALL
	public static final int CLEANUP_DOCUMENT = BASE + 1;
	public static final int FORMAT_ACTIVE_ELEMENTS = BASE + 3;

	private static final String FORMAT_ACTIVE_ELEMENTS_TEXT = SSEUIMessages.Format_Active_Elements_UI_; //$NON-NLS-1$
	public static final int FORMAT_DOCUMENT = BASE + 2;
	private static final String FORMAT_DOCUMENT_TEXT = SSEUIMessages.Format_Document_UI_; //$NON-NLS-1$
	public static final int QUICK_FIX = BASE + 4;
	private static final String TEXT_CUT = SSEUIMessages.Text_Cut_UI_; //$NON-NLS-1$
	private static final String TEXT_PASTE = SSEUIMessages.Text_Paste_UI_; //$NON-NLS-1$
	private static final String TEXT_SHIFT_LEFT = SSEUIMessages.Text_Shift_Left_UI_; //$NON-NLS-1$ = "Text Shift Left"
	private static final String TEXT_SHIFT_RIGHT = SSEUIMessages.Text_Shift_Right_UI_; //$NON-NLS-1$ = "Text Shift Right"
	private boolean fBackgroundupdateInProgress;
	protected StructuredContentCleanupHandler fContentCleanupHandler = null;
	protected IContentAssistant fCorrectionAssistant;
	protected boolean fCorrectionAssistantInstalled;
	private IDocumentAdapter fDocAdapter;

	private InternalSelectionListener fSelectionListener = null;

	/**
	 * TODO Temporary workaround for BUG44665
	 */
	/** The most recent widget modification as document command */
	private StructuredDocumentCommand fDocumentCommand = new StructuredDocumentCommand();
	private IHighlighter fHighlighter;
	// TODO: never read locally
	boolean fRememberedStateContentAssistInstalled;

	/**
	 * TODO Temporary workaround for BUG44665
	 */
	/** Verify listener */
	private TextVerifyListener fVerifyListener = new TextVerifyListener();

	private ViewerSelectionManager fViewerSelectionManager;
	private SourceViewerConfiguration fConfiguration;

	/**
	 * @see org.eclipse.jface.text.source.SourceViewer#SourceViewer(Composite,
	 *      IVerticalRuler, IOverviewRuler, boolean, int)
	 */
	public StructuredTextViewer(Composite parent, IVerticalRuler verticalRuler, IOverviewRuler overviewRuler, boolean showAnnotationsOverview, int styles) {
		super(parent, verticalRuler, overviewRuler, showAnnotationsOverview, styles);
		fSelectionListener = new InternalSelectionListener();
	}

	/**
	 * 
	 */
	private void beep() {
		getTextWidget().getDisplay().beep();
	}

	void beginBackgroundUpdate() {
		fBackgroundupdateInProgress = true;
		disableRedrawing();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jface.text.ITextOperationTarget#canDoOperation(int)
	 */
	public boolean canDoOperation(int operation) {
		if (fBackgroundupdateInProgress) {
			return false;
		}
		switch (operation) {
			case CONTENTASSIST_PROPOSALS : {
				// (pa) if position isn't READ_ONLY (containsReadOnly()
				// returns false),
				// Otherwise, you DO want content assist (return true)
				IDocument doc = getDocument();
				if (doc != null && doc instanceof IStructuredDocument) {
					return isEditable() && (!((IStructuredDocument) doc).containsReadOnly(getSelectedRange().x, 0));
				}
				break;
			}
			case QUICK_FIX : {
				return isEditable();
			}
			case CLEANUP_DOCUMENT : {
				return (fContentCleanupHandler != null && isEditable());
			}
			case FORMAT_DOCUMENT :
			case FORMAT_ACTIVE_ELEMENTS : {
				return (fContentFormatter != null && isEditable());
			}
		}
		return super.canDoOperation(operation);
	}

	/**
	 * Should be identical to superclass version. Plus, we get our own special
	 * Highlighter. Plus we uninstall before installing.
	 */
	public void configure(SourceViewerConfiguration configuration) {

		if (getTextWidget() == null)
			return;

		setDocumentPartitioning(configuration.getConfiguredDocumentPartitioning(this));

		if (configuration instanceof StructuredTextViewerConfiguration) {
			if (fHighlighter != null) {
				fHighlighter.uninstall();
			}
			fHighlighter = ((StructuredTextViewerConfiguration) configuration).getHighlighter(this);
			fHighlighter.install(this);
		}

		// install content type independent plugins
		if (fPresentationReconciler != null)
			fPresentationReconciler.uninstall();
		fPresentationReconciler = configuration.getPresentationReconciler(this);
		if (fPresentationReconciler != null)
			fPresentationReconciler.install(this);

		IReconciler newReconciler = configuration.getReconciler(this);

		if (newReconciler != fReconciler || newReconciler == null || fReconciler == null) {

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

			fReconciler = newReconciler;

			if (fReconciler != null) {
				fReconciler.install(this);
				// https://w3.opensource.ibm.com/bugzilla/show_bug.cgi?id=3858
				// still need set document on the reconciler (strategies)
				((StructuredRegionProcessor) fReconciler).setDocument(getDocument());
			}
		}

		if (fContentAssistant != null)
			fContentAssistant.uninstall();
		fContentAssistant = configuration.getContentAssistant(this);
		if (fContentAssistant != null) {
			fContentAssistant.install(this);
			fContentAssistantInstalled = true;
		} else {
			// 248036
			// disable the content assist operation if no content assistant
			enableOperation(CONTENTASSIST_PROPOSALS, false);
		}

		// correction assistant
		if (configuration instanceof StructuredTextViewerConfiguration) {
			if (fCorrectionAssistant != null)
				fCorrectionAssistant.uninstall();
			fCorrectionAssistant = ((StructuredTextViewerConfiguration) configuration).getCorrectionAssistant(this);
			if (fCorrectionAssistant != null) {
				fCorrectionAssistant.install(this);
				fCorrectionAssistantInstalled = true;
			} else {
				// disable the correction assist operation if no correction
				// assistant
				enableOperation(QUICK_FIX, false);
			}
		}

		fContentFormatter = configuration.getContentFormatter(this);

		// do not uninstall old information presenter if it's the same
		IInformationPresenter newInformationPresenter = configuration.getInformationPresenter(this);
		if (newInformationPresenter == null || fInformationPresenter == null || !(newInformationPresenter.equals(fInformationPresenter))) {
			if (fInformationPresenter != null)
				fInformationPresenter.uninstall();
			fInformationPresenter = newInformationPresenter;
			if (fInformationPresenter != null)
				fInformationPresenter.install(this);
		}

		// disconnect from the old undo manager before setting the new one
		if (fUndoManager != null) {
			fUndoManager.disconnect();
		}
		setUndoManager(configuration.getUndoManager(this));

		// TODO: compare with ?new? V2 configure re:
		// getTextWidget().setTabs(configuration.getTabWidth(this));
		// see if it can replace following
		// Set tab width to configuration setting first.
		// Then override if model type is XML or HTML.
		getTextWidget().setTabs(configuration.getTabWidth(this));
		setAnnotationHover(configuration.getAnnotationHover(this));
		setOverviewRulerAnnotationHover(configuration.getOverviewRulerAnnotationHover(this));
		// added for V2
		setHoverControlCreator(configuration.getInformationControlCreator(this));

		// if hyperlink manager has already been created, uninstall it
		if (fHyperlinkManager != null) {
			setHyperlinkDetectors(null, SWT.NONE);
		}
		setHyperlinkPresenter(configuration.getHyperlinkPresenter(this));
		IHyperlinkDetector[] hyperlinkDetectors = configuration.getHyperlinkDetectors(this);
		int eventStateMask = configuration.getHyperlinkStateMask(this);
		setHyperlinkDetectors(hyperlinkDetectors, eventStateMask);

		// install content type specific plugins
		String[] types = configuration.getConfiguredContentTypes(this);

		// clear autoindent/autoedit strategies
		fAutoIndentStrategies = null;
		for (int i = 0; i < types.length; i++) {
			String t = types[i];
			setAutoEditStrategies(configuration.getAutoEditStrategies(this, t), t);
			setTextDoubleClickStrategy(configuration.getDoubleClickStrategy(this, t), t);

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

			String[] prefixes = configuration.getIndentPrefixes(this, t);
			if (prefixes != null && prefixes.length > 0)
				setIndentPrefixes(prefixes, t);

			prefixes = configuration.getDefaultPrefixes(this, t);
			if (prefixes != null && prefixes.length > 0)
				setDefaultPrefixes(prefixes, t);
		}
		activatePlugins();

		fConfiguration = configuration;
	}

	/**
	 * @param document
	 * @param startOffset
	 * @param endOffset
	 * @return
	 */
	private boolean containsReadOnly(IDocument document, int startOffset, int endOffset) {

		int start = startOffset;
		int end = endOffset;
		IStructuredDocument structuredDocument = null;
		if (document instanceof IStructuredDocument) {
			structuredDocument = (IStructuredDocument) document;
		} else {
			if (document instanceof ProjectionDocument) {
				IDocument doc = ((ProjectionDocument) document).getMasterDocument();
				if (doc instanceof IStructuredDocument) {
					structuredDocument = (IStructuredDocument) doc;
					int adjust = ((ProjectionDocument) document).getProjectionMapping().getCoverage().getOffset();
					start = adjust + start;
					end = adjust + end;
				}
			}
		}
		if (structuredDocument == null) {
			return false;
		} else {
			int length = end - start;
			return structuredDocument.containsReadOnly(start, length);
		}
	}

	protected IDocumentAdapter createDocumentAdapter() {

		fDocAdapter = new StructuredDocumentToTextAdapter(getTextWidget());
		return fDocAdapter;
	}

	/**
	 * TODO Temporary workaround for BUG44665
	 */
	protected void customizeDocumentCommand(StructuredDocumentCommand command) {
		if (isIgnoringAutoEditStrategies())
			return;

		List strategies = (List) selectContentTypePlugin(command.offset, fAutoIndentStrategies);
		if (strategies == null)
			return;

		switch (strategies.size()) {
			// optimization
			case 0 :
				break;

			case 1 :
				((IAutoEditStrategy) strategies.iterator().next()).customizeDocumentCommand(getDocument(), command);
				break;

			// make iterator robust against adding/removing strategies from
			// within
			// strategies
			default :
				strategies = new ArrayList(strategies);

				IDocument document = getDocument();
				for (final Iterator iterator = strategies.iterator(); iterator.hasNext();)
					((IAutoEditStrategy) iterator.next()).customizeDocumentCommand(document, command);

				break;
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jface.text.ITextOperationTarget#doOperation(int)
	 */
	public void doOperation(int operation) {

		Point selection = getTextWidget().getSelection();
		int cursorPosition = selection.x;
		int selectionLength = selection.y - selection.x;
		switch (operation) {
			case UNDO : {
				IExtendedSimpleEditor editor = getActiveExtendedSimpleEditor();
				if (editor != null) {
					IStatus status = editor.validateEdit(getControl().getShell());
					if (status != null && status.isOK())
						undo();
				} else
					undo();
				break;
			}
			case REDO : {
				IExtendedSimpleEditor editor = getActiveExtendedSimpleEditor();
				if (editor != null) {
					IStatus status = editor.validateEdit(getControl().getShell());
					if (status != null && status.isOK())
						redo();
				} else
					redo();
				break;
			}
			case CUT :
				beginRecording(TEXT_CUT, TEXT_CUT, cursorPosition, selectionLength);
				super.doOperation(operation);
				selection = getTextWidget().getSelection();
				cursorPosition = selection.x;
				selectionLength = selection.y - selection.x;
				endRecording(cursorPosition, selectionLength);
				break;
			case PASTE :
				beginRecording(TEXT_PASTE, TEXT_PASTE, cursorPosition, selectionLength);
				super.doOperation(operation);
				selection = getTextWidget().getSelection();
				cursorPosition = selection.x;
				selectionLength = selection.y - selection.x;
				endRecording(cursorPosition, selectionLength);
				break;
			case CONTENTASSIST_PROPOSALS :
				// maybe not configured?
				if (fContentAssistant != null && isEditable()) {
					// CMVC 263269
					// need an explicit check here because the
					// contentAssistAction is no longer being updated on
					// cursor
					// position
					if (canDoOperation(CONTENTASSIST_PROPOSALS)) {
						String err = fContentAssistant.showPossibleCompletions();
						if (err != null) {
							// don't wanna beep if there is no error
							PlatformStatusLineUtil.displayErrorMessage(err);
						}
						PlatformStatusLineUtil.addOneTimeClearListener();
					} else
						beep();
				}
				break;
			case CONTENTASSIST_CONTEXT_INFORMATION :
				if (fContentAssistant != null) {
					String err = fContentAssistant.showContextInformation();
					PlatformStatusLineUtil.displayErrorMessage(err);
					PlatformStatusLineUtil.addOneTimeClearListener();
					// setErrorMessage(err);
					// new OneTimeListener(getTextWidget(), new
					// ClearErrorMessage());
				}
				break;
			case QUICK_FIX :
				if (isEditable()) {
					String msg = fCorrectionAssistant.showPossibleCompletions();
					setErrorMessage(msg);
				}
				break;
			case SHIFT_RIGHT :
				beginRecording(TEXT_SHIFT_RIGHT, TEXT_SHIFT_RIGHT, cursorPosition, selectionLength);
				updateIndentationPrefixes();
				super.doOperation(SHIFT_RIGHT);
				selection = getTextWidget().getSelection();
				cursorPosition = selection.x;
				selectionLength = selection.y - selection.x;
				endRecording(cursorPosition, selectionLength);
				break;
			case SHIFT_LEFT :
				beginRecording(TEXT_SHIFT_LEFT, TEXT_SHIFT_LEFT, cursorPosition, selectionLength);
				updateIndentationPrefixes();
				super.doOperation(SHIFT_LEFT);
				selection = getTextWidget().getSelection();
				cursorPosition = selection.x;
				selectionLength = selection.y - selection.x;
				endRecording(cursorPosition, selectionLength);
				break;
			case FORMAT_DOCUMENT :
				try {
					// begin recording
					beginRecording(FORMAT_DOCUMENT_TEXT, FORMAT_DOCUMENT_TEXT, cursorPosition, selectionLength);

					// format
					IRegion region = getModelCoverage();
					if (fContentFormatter instanceof IContentFormatterExtension) {
						IContentFormatterExtension extension = (IContentFormatterExtension) fContentFormatter;
						IFormattingContext context = new FormattingContext();
						context.setProperty(FormattingContextProperties.CONTEXT_DOCUMENT, Boolean.TRUE);
						context.setProperty(FormattingContextProperties.CONTEXT_REGION, region);
						extension.format(getDocument(), context);
					} else {
						fContentFormatter.format(getDocument(), region);
					}
				} finally {
					// end recording
					selection = getTextWidget().getSelection();
					cursorPosition = selection.x;
					selectionLength = selection.y - selection.x;
					endRecording(cursorPosition, selectionLength);
				}
				break;
			case FORMAT_ACTIVE_ELEMENTS :
				try {
					// begin recording
					beginRecording(FORMAT_ACTIVE_ELEMENTS_TEXT, FORMAT_ACTIVE_ELEMENTS_TEXT, cursorPosition, selectionLength);

					// format
					Point s = getSelectedRange();
					IRegion region = new Region(s.x, s.y);
					fContentFormatter.format(getDocument(), region);
				} finally {
					// end recording
					selection = getTextWidget().getSelection();
					cursorPosition = selection.x;
					selectionLength = selection.y - selection.x;
					endRecording(cursorPosition, selectionLength);
				}
				break;
			default :
				super.doOperation(operation);
		}
	}

	private void endRecording(int cursorPosition, int selectionLength) {
		IDocument doc = getDocument();
		if (doc instanceof IStructuredDocument) {
			IStructuredDocument structuredDocument = (IStructuredDocument) doc;
			IStructuredTextUndoManager undoManager = structuredDocument.getUndoManager();
			undoManager.endRecording(this, cursorPosition, selectionLength);
		} else {
			// TODO: how to handle other document types?
		}
	}

	private void beginRecording(String label, String description, int cursorPosition, int selectionLength) {
		IDocument doc = getDocument();
		if (doc instanceof IStructuredDocument) {
			IStructuredDocument structuredDocument = (IStructuredDocument) doc;
			IStructuredTextUndoManager undoManager = structuredDocument.getUndoManager();
			undoManager.beginRecording(this, label, description, cursorPosition, selectionLength);
		} else {
			// TODO: how to handle other document types?
		}
	}

	void endBackgroundUpdate() {
		fBackgroundupdateInProgress = false;
		enabledRedrawing();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jface.text.TextViewer#findAndSelect(int,
	 *      java.lang.String, boolean, boolean, boolean, boolean)
	 */
	protected int findAndSelect(int startPosition, String findString, boolean forwardSearch, boolean caseSensitive, boolean wholeWord, boolean regExSearch) {
		int result = super.findAndSelect(startPosition, findString, forwardSearch, caseSensitive, wholeWord, regExSearch);

		// findAndSelect calls fTextWidget.setSelectionRange(widgetPos,
		// length) to set selection,
		// which does not fire text widget selection event.
		// Need to notify ViewerSelectionManager here.
		notifyViewerSelectionManager(getSelectedRange().x, getSelectedRange().y);

		return result;
	}

	protected IExtendedSimpleEditor getActiveExtendedSimpleEditor() {
		IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
		if (window != null) {
			IWorkbenchPage page = window.getActivePage();
			if (page != null) {
				IEditorPart editor = page.getActiveEditor();
				if (editor != null && editor instanceof IExtendedSimpleEditor) {
					return (IExtendedSimpleEditor) editor;
				}
			}
		}
		return null;
	}


	protected ViewerSelectionManager getDefaultViewerSelectionManager() {
		return new ViewerSelectionManagerImpl(this);
	}

	/**
	 * @deprecated
	 * @return the current ViewerSelectionManager
	 */
	public ViewerSelectionManager getViewerSelectionManager() {
		if (fViewerSelectionManager == null) {
			ViewerSelectionManager viewerSelectionManager = getDefaultViewerSelectionManager();
			// use setter instead of field directly, so it get initialized
			// properly
			setViewerSelectionManager(viewerSelectionManager);
		}
		return fViewerSelectionManager;
	}

	protected void handleDispose() {
		Logger.trace("Source Editor", "StructuredTextViewer::handleDispose entry"); //$NON-NLS-1$ //$NON-NLS-2$

		// before we dispose, we set a special "empty" selection, to prevent
		// the "leak one document" that
		// otherwise occurs when editor closed (since last selection stays in
		// SelectedResourceManager.
		// the occurance of the "leak" isn't so bad, but makes debugging other
		// leaks very hard.
		setSelection(TextSelection.emptySelection());

		if (fViewerSelectionManager != null) {
			fViewerSelectionManager.removeNodeDoubleClickListener(fSelectionListener);
			fViewerSelectionManager.removeNodeSelectionListener(fSelectionListener);
			fViewerSelectionManager.release();
		}

		if (fHighlighter != null) {
			fHighlighter.uninstall();
		}
		super.handleDispose();

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

	void handleDoubleClick(DoubleClickEvent event) {
		IStructuredSelection selection = (IStructuredSelection) event.getSelection();
		int selectionSize = selection.size();
		List selectedNodes = selection.toList();
		IndexedRegion doubleClickedNode = null;
		int selectionStart = 0;
		int selectionEnd = 0;
		if (selectionSize > 0) {
			// something selected
			// only one node can be double-clicked at a time
			// so, we get the first one
			Object o = selectedNodes.get(0);
			if(o instanceof IndexedRegion) {
				doubleClickedNode = (IndexedRegion) o;
				selectionStart = doubleClickedNode.getStartOffset();
				selectionEnd = doubleClickedNode.getEndOffset();
				// set new selection
				setSelectedRange(selectionStart, selectionEnd - selectionStart);
			}
		}
	}

	void handleNodeSelectionChanged(NodeSelectionChangedEvent event) {

		// Skip NodeSelectionChanged processing if this is the source of the
		// event.
		if (event.getSource().equals(this))
			return;
		List selectedNodes = new Vector(event.getSelectedNodes());
		boolean attrOrTextNodeSelected = false;
		int attrOrTextNodeStartOffset = 0;
		for (int i = 0; i < selectedNodes.size(); i++) {
			Object eachNode = selectedNodes.get(i);
			// replace attribute node with its parent
			if (eachNode instanceof Attr) {
				attrOrTextNodeSelected = true;
				attrOrTextNodeStartOffset = ((IndexedRegion) eachNode).getStartOffset();
				selectedNodes.set(i, ((Attr) eachNode).getOwnerElement());
			}
			// replace TextNode with its parent
			if ((eachNode instanceof Node) && (((Node) eachNode).getNodeType() == Node.TEXT_NODE)) {
				attrOrTextNodeSelected = true;
				attrOrTextNodeStartOffset = ((IndexedRegion) eachNode).getStartOffset();
				selectedNodes.set(i, ((Node) eachNode).getParentNode());
			}
		}
		if (nothingToSelect(selectedNodes)) {
			removeRangeIndication();
		} else {
			IndexedRegion startNode = (IndexedRegion) selectedNodes.get(0);
			IndexedRegion endNode = (IndexedRegion) selectedNodes.get(selectedNodes.size() - 1);
			int startOffset = startNode.getStartOffset();
			int endOffset = endNode.getEndOffset();
			// if end node is a child node of start node
			if (startNode.getEndOffset() > endNode.getEndOffset()) {
				endOffset = startNode.getEndOffset();
			}
			int length = endOffset - startOffset;
			// Move cursor only if the original source really came from
			// a ContentViewer (for example, the SourceEditorTreeViewer or the
			// XMLTableTreeViewer)
			// or a ContentOutlinePage (for example, the XSDTreeViewer).
			// Do not move the cursor if the source is a textWidget (which
			// means the selection came from the text viewer) or
			// if the source is the ViewerSelectionManager (which means the
			// selection was set programmatically).
			boolean moveCursor = (event.getSource() instanceof ContentViewer) || (event.getSource() instanceof IContentOutlinePage);
			// 20031012 (pa)
			// Changed moveCursor to "false" because it was causing the cursor
			// to jump to the beginning of the parent node in the case that a
			// child of the parent is deleted.
			// We really only want to set the range indicator on the left to
			// the range of the parent, but not move the cursor
			// setRangeIndication(startOffset, length, false);
			// 20040714 (nsd) Chnaged back to tru given that selection
			// problems
			// caused by the Outline view appear fixed.
			setRangeIndication(startOffset, length, moveCursor);
			if ((moveCursor) && (attrOrTextNodeSelected)) {
				setSelectedRange(attrOrTextNodeStartOffset, 0);
				revealRange(attrOrTextNodeStartOffset, 0);
			}
			// if(moveCursor) {
			// System.out.print("moving");
			// }
			// else {
			// System.out.print("not moving");
			// }
			// System.out.println(" on NodeSelectionEvent: " +
			// event.getSource());
		}
	}

	/**
	 * TODO Temporary workaround for BUG44665
	 */
	/**
	 * @see VerifyListener#verifyText(VerifyEvent)
	 */
	protected void handleVerifyEvent(VerifyEvent e) {
		IRegion modelRange = event2ModelRange(e);
		if (exposeModelRange(modelRange)) {
			e.doit = false;
			return;
		}

		if (fEventConsumer != null) {
			fEventConsumer.processEvent(e);
			if (!e.doit)
				return;
		}
		if (fBackgroundupdateInProgress) {
			e.doit = false;
			beep();
			return;
		}
		// for read-only support
		if (containsReadOnly(getVisibleDocument(), e.start, e.end)) {
			e.doit = false;
			beep();
			return;
		}

		fDocumentCommand.setEventStructuredDocumentEvent(e, modelRange);
		customizeDocumentCommand(fDocumentCommand);
		int widgetCaret = 0;
		if (!fDocumentCommand.fillEventStructuredDocumentCommand(e, modelRange)) {

			boolean compoundChange = fDocumentCommand.getCommandCount() > 1;
			try {

				fVerifyListener.forward(false);

				if (compoundChange && fUndoManager != null)
					fUndoManager.beginCompoundChange();

				if (getSlaveDocumentManager() != null) {
					IDocument visible = getVisibleDocument();
					try {
						getSlaveDocumentManager().setAutoExpandMode(visible, true);
						fDocumentCommand.executeStructuredDocumentCommand(getDocument());
					} finally {
						getSlaveDocumentManager().setAutoExpandMode(visible, false);
					}
				} else {
					fDocumentCommand.executeStructuredDocumentCommand(getDocument());
				}

				if (getTextWidget() != null) {
					int documentCaret = fDocumentCommand.caretOffset;
					if (documentCaret == -1) {
						// old behavior of document command
						documentCaret = fDocumentCommand.offset + (fDocumentCommand.text == null ? 0 : fDocumentCommand.text.length());
					}

					widgetCaret = modelOffset2WidgetOffset(documentCaret);
					if (widgetCaret == -1) {
						// try to move it to the closest spot
						IRegion region = getModelCoverage();
						if (documentCaret <= region.getOffset())
							widgetCaret = 0;
						else if (documentCaret >= region.getOffset() + region.getLength())
							widgetCaret = getVisibleRegion().getLength();
					}

				}
			} catch (BadLocationException x) {

				if (TRACE_ERRORS)
					System.out.println("TextViewer.error.bad_location.verifyText"); //$NON-NLS-1$

			} finally {

				if (compoundChange && fUndoManager != null)
					fUndoManager.endCompoundChange();

				if (widgetCaret != -1) {
					// there is a valid widget caret
					getTextWidget().setCaretOffset(widgetCaret);
				}

				getTextWidget().showSelection();

				fVerifyListener.forward(true);

			}
		}
	}

	public int modelLine2WidgetLine(int modelLine) {
		/**
		 * need to override this method as a workaround for Bug 85709
		 */
		if (fInformationMapping == null) {
			IDocument document = getDocument();
			if (document != null) {
				try {
					IRegion modelLineRegion = getDocument().getLineInformation(modelLine);
					IRegion region = getModelCoverage();
					if (modelLineRegion != null && region != null) {
						int modelEnd = modelLineRegion.getOffset() + modelLineRegion.getLength();
						int regionEnd = region.getOffset() + region.getLength();
						// returns -1 if modelLine is invalid
						if ((modelLineRegion.getOffset() < region.getOffset()) || (modelEnd > regionEnd))
							return -1;
					}
				} catch (BadLocationException e) {
					// returns -1 if modelLine is invalid
					return -1;
				}
			}
		}
		return super.modelLine2WidgetLine(modelLine);
	}

	public int modelOffset2WidgetOffset(int modelOffset) {
		/**
		 * need to override this method as a workaround for Bug 85709
		 */
		if (fInformationMapping == null) {
			IRegion region = getModelCoverage();
			if (region != null) {
				// returns -1 if modelOffset is invalid
				if (modelOffset < region.getOffset() || modelOffset > (region.getOffset() + region.getLength()))
					return -1;
			}
		}
		return super.modelOffset2WidgetOffset(modelOffset);
	}

	public IRegion modelRange2WidgetRange(IRegion modelRange) {
		// need to override this method as workaround for Bug85709
		if (fInformationMapping == null) {
			IRegion region = getModelCoverage();
			if (region != null && modelRange != null) {
				int modelEnd = modelRange.getOffset() + modelRange.getLength();
				int regionEnd = region.getOffset() + region.getLength();
				// returns null if modelRange is invalid
				if ((modelRange.getOffset() < region.getOffset()) || (modelEnd > regionEnd))
					return null;
			}
		}
		return super.modelRange2WidgetRange(modelRange);
	}

	/**
	 * TODO Temporary workaround for BUG44665
	 */
	/**
	 * overridden for read-only support
	 */
	/*
	 * protected void handleVerifyEvent(VerifyEvent e) { // for now, we'll let
	 * super have a shot first // (may mess up undo stack, or something?)
	 * 
	 * super.handleVerifyEvent(e); if (containsReadOnly(getVisibleDocument(),
	 * e.start, e.end)) { e.doit = false; beep(); } }
	 */

	/**
	 * @param selectedNodes
	 * @return whether the IndexedNodes within the list should form a
	 *         selectionrange
	 */
	private boolean nothingToSelect(List selectedNodes) {
		if (selectedNodes == null || selectedNodes.isEmpty() || selectedNodes.get(0) == null) // empty
			// selections
			return true;
		if (getDocument() == null) // viewer shutdown
			return true;
		// if the range would be the entire document's length, there's nothing
		// to show
		Object o = selectedNodes.get(0);
		if (o instanceof IndexedRegion) {
			IndexedRegion firstIndexedNode = (IndexedRegion) o;
			return firstIndexedNode.getEndOffset() - firstIndexedNode.getStartOffset() >= getDocument().getLength();
		}
		return true;
	}

	/**
	 * Notify the ViewerSelectionManager when text is selected
	 * programmatically, for example, by double-click processing or an editor
	 * action like Edit->SelectAll
	 */
	protected void notifyViewerSelectionManager(int offset, int length) {
		if (fViewerSelectionManager != null) {
			Event event = new Event();
			event.widget = getTextWidget();
			// sometimes null while closing
			if (event.widget != null) {
				SelectionEvent selectionEvent = new SelectionEvent(event);
				selectionEvent.x = offset;
				selectionEvent.y = offset + length;
				fViewerSelectionManager.widgetSelected(selectionEvent);
			}
		}
	}

	private void redo() {
		ignoreAutoEditStrategies(true);
		fUndoManager.redo();
		ignoreAutoEditStrategies(false);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jface.text.source.ISourceViewer#setDocument(org.eclipse.jface.text.IDocument,
	 *      org.eclipse.jface.text.source.IAnnotationModel, int, int)
	 */
	public void setDocument(IDocument document, IAnnotationModel annotationModel, int modelRangeOffset, int modelRangeLength) {
		// partial fix for:
		// https://w3.opensource.ibm.com/bugzilla/show_bug.cgi?id=1970
		// when our document is set, especially to null during close,
		// immediately uninstall the reconciler.
		// this is to avoid an unnecessary final "reconcile"
		// that blocks display thread
		if (document == null) {
			if (fReconciler != null) {
				fReconciler.uninstall();
			}
		}

		super.setDocument(document, annotationModel, modelRangeOffset, modelRangeLength);

		if (document instanceof IStructuredDocument) {
			IStructuredDocument structuredDocument = (IStructuredDocument) document;

			// notify highlighter
			if (fHighlighter != null) {
				fHighlighter.setDocument(structuredDocument);
			}

			// set document in the viewer-based undo manager
			if (fUndoManager != null) {
				fUndoManager.disconnect();
				fUndoManager.connect(this);
			}
			// CaretEvent is not sent to ViewerSelectionManager after Save As.
			// Need to notify ViewerSelectionManager here.
			notifyViewerSelectionManager(getSelectedRange().x, getSelectedRange().y);
		}
	}

	/**
	 * Use the active editor to set a status line message
	 * 
	 * @param msg
	 */
	protected void setErrorMessage(String msg) {
		IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
		if (window != null) {
			IWorkbenchPage page = window.getActivePage();
			if (page != null) {
				IEditorPart editor = page.getActiveEditor();
				if (editor != null) {
					IEditorStatusLine statusLine = (IEditorStatusLine) editor.getAdapter(IEditorStatusLine.class);
					if (statusLine != null)
						statusLine.setMessage(true, msg, null);
				}
			}
		}
	}

	public void setViewerSelectionManager(ViewerSelectionManager viewerSelectionManager) {
		// disconnect from old one
		if (fViewerSelectionManager != null) {
			fViewerSelectionManager.removeNodeDoubleClickListener(fSelectionListener);
			fViewerSelectionManager.removeNodeSelectionListener(fSelectionListener);
			fViewerSelectionManager.release();
			// No need to removeSelectionChangedListener here. Done when
			// editor
			// calls "new ViewerSelectionManagerImpl(ITextViewer)".
			// removeSelectionChangedListener(fViewerSelectionManager);
		}
		fViewerSelectionManager = viewerSelectionManager;
		// connect to new one
		if (fViewerSelectionManager != null) {
			fViewerSelectionManager.addNodeDoubleClickListener(fSelectionListener);
			fViewerSelectionManager.addNodeSelectionListener(fSelectionListener);
			// No need to addSelectionChangedListener here. Done when editor
			// calls "new ViewerSelectionManagerImpl(ITextViewer)".
			// addSelectionChangedListener(fViewerSelectionManager);
		}
	}

	/**
	 * Uninstalls anything that was installed by configure
	 */
	public void unconfigure() {
		Logger.trace("Source Editor", "StructuredTextViewer::unconfigure entry"); //$NON-NLS-1$ //$NON-NLS-2$
		if (fHighlighter != null) {
			fHighlighter.uninstall();
		}

		// doesn't seem to be handled elsewhere, so we'll be sure error
		// messages's are cleared.
		setErrorMessage(null);

		super.unconfigure();
		fConfiguration = null;
		Logger.trace("Source Editor", "StructuredTextViewer::unconfigure exit"); //$NON-NLS-1$ //$NON-NLS-2$
	}

	private void undo() {
		ignoreAutoEditStrategies(true);
		fUndoManager.undo();
		ignoreAutoEditStrategies(false);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.wst.sse.core.undo.IDocumentSelectionMediator#undoOperationSelectionChanged(org.eclipse.wst.sse.core.undo.UndoDocumentEvent)
	 */
	public void undoOperationSelectionChanged(UndoDocumentEvent event) {
		if (event.getRequester() != null && event.getRequester().equals(this) && event.getDocument().equals(getDocument()))
			setSelectedRange(event.getOffset(), event.getLength());
	}

	/**
	 * Make sure indentation is correct before using.
	 */
	private void updateIndentationPrefixes() {
		SourceViewerConfiguration configuration = fConfiguration;
		if (fConfiguration != null) {
			String[] types = configuration.getConfiguredContentTypes(this);
			for (int i = 0; i < types.length; i++) {
				String[] prefixes = configuration.getIndentPrefixes(this, types[i]);
				if (prefixes != null && prefixes.length > 0)
					setIndentPrefixes(prefixes, types[i]);
			}
		}
	}
}
