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

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.text.IDocumentExtension3;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.ITextViewerExtension5;
import org.eclipse.jface.text.ITypedRegion;
import org.eclipse.jface.text.Region;
import org.eclipse.jface.text.TextUtilities;
import org.eclipse.jface.text.source.projection.ProjectionViewer;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.swt.custom.LineStyleEvent;
import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
import org.eclipse.wst.sse.core.internal.util.Debug;
import org.eclipse.wst.sse.ui.internal.ExtendedConfigurationBuilder;
import org.eclipse.wst.sse.ui.internal.Logger;
import org.eclipse.wst.sse.ui.internal.SSEUIPlugin;
import org.eclipse.wst.sse.ui.internal.preferences.EditorPreferenceNames;
import org.eclipse.wst.sse.ui.internal.util.EditorUtility;

/**
 * This class is to directly mediate between the Structured Document data
 * structure and the text widget's text and events. It assumes there only the
 * model is interested in text events, and all other views will work from that
 * model. Changes to the text widgets input can cause changes in the model,
 * which in turn cause changes to the widget's display.
 * 
 */
public class Highlighter implements IHighlighter {

	/**
	 * A utility class to do various color manipulations
	 */
	private class YUV_RGBConverter {
		/**
		 * This class "holds" the YUV values corresponding to RGB color
		 */
		private class YUV {

			class NormalizedRGB {
				double blue;
				double green;
				private final double maxRGB = 256.0;
				double red;

				public NormalizedRGB(RGB rgb) {
					// first normalize to between 0 - 1
					red = rgb.red / maxRGB;
					green = rgb.green / maxRGB;
					blue = rgb.blue / maxRGB;

					red = gammaNormalized(red);
					green = gammaNormalized(green);
					blue = gammaNormalized(blue);

				}
			}

			private NormalizedRGB normalizedRGB;

			RGB originalRGB;
			private double u = -1;
			private double v = -1;
			private double y = -1;

			private YUV() {
				super();
			}

			public YUV(double y, double u, double v) {
				this();
				this.y = y;
				this.u = u;
				this.v = v;
			}

			public YUV(RGB rgb) {
				this();
				originalRGB = rgb;
				normalizedRGB = new NormalizedRGB(rgb);
				// force calculations
				getY();
				getV();
				getU();
			}

			/**
			 * normalize to "average" gamma 2.2222 or 1/0.45
			 */
			double gammaNormalized(double colorComponent) {
				if (colorComponent < 0.018) {
					return colorComponent * 0.45;
				} else {
					return 1.099 * Math.pow(colorComponent, 0.45) - 0.099;
				}
			}

			/**
			 * @return RGB based on original RGB and current YUV values;
			 */
			public RGB getRGB() {
				RGB result = null;
				double r = getY() + 1.14 * getV();
				double g = getY() - 0.395 * getU() - 0.58 * getV();
				double b = getY() + 2.032 * getU();

				int red = (int) (inverseGammaNormalized(r) * 256);
				int green = (int) (inverseGammaNormalized(g) * 256);
				int blue = (int) (inverseGammaNormalized(b) * 256);
				if (red < 0)
					red = 0;
				else if (red > 255)
					red = 255;
				if (green < 0)
					green = 0;
				else if (green > 255)
					green = 255;
				if (blue < 0)
					blue = 0;
				else if (blue > 255)
					blue = 255;

				result = new RGB(red, green, blue);
				return result;
			}

			public double getU() {
				if (u == -1) {
					u = 0.4949 * (normalizedRGB.blue - getY());
				}
				return u;

			}

			public double getV() {
				if (v == -1) {
					v = 0.877 * (normalizedRGB.red - getY());
				}
				return v;
			}

			public double getY() {
				if (y == -1) {
					y = 0.299 * normalizedRGB.red + 0.587 * normalizedRGB.green + 0.114 * normalizedRGB.blue;
				}
				return y;
			}

			double inverseGammaNormalized(double colorComponent) {
				if (colorComponent < 0.018) {
					return colorComponent * .222;
				} else {
					return Math.pow(((.9099 * colorComponent + 0.09)), 2.22);
				}
			}

		}

		public YUV_RGBConverter() {
			super();
		}

		public double calculateYComponent(Color targetColor) {
			return new YUV(targetColor.getRGB()).getY();
		}

		public RGB transformRGB(RGB originalRGB, double scaleFactor, double target) {
			RGB transformedRGB = null;
			// CCIR601 yuv = new CCIR601(originalRGB);
			YUV yuv = new YUV(originalRGB);
			double y = yuv.getY();
			// zero is black, one is white
			if (y < target) {
				// is "dark" make lighter
				y = y + ((target - y) * scaleFactor);
			} else {
				// is "light" make darker
				y = y - ((y - target) * scaleFactor);
			}
			// yuv.setY(y);
			YUV newYUV = new YUV(y, yuv.getU(), yuv.getV());
			// CCIR601 newYUV = new CCIR601(y, yuv.getCb601(),
			// yuv.getCr601());
			transformedRGB = newYUV.getRGB();
			return transformedRGB;
		}

		public RGB transformRGBToGrey(RGB originalRGB, double scaleFactor, double target) {
			RGB transformedRGB = null;
			// we left the "full" API method signature, but this
			// version does not take into account originalRGB, though
			// it might someday.
			// for now, we'll simply make the new RGB grey, either a little
			// lighter, or a little darker than background.
			double y = 0;
			double mid = 0.5;
			// zero is black, one is white
			if (target < mid) {
				// is "dark" make lighter
				y = target + scaleFactor;
			} else {
				// is "light" make darker
				y = target - scaleFactor;
			}
			int c = (int) Math.round(y * 255);
			// just to gaurd against mis-use, or scale's values greater
			// than mid point (and possibly rounding error)
			if (c > 255)
				c = 255;
			if (c < 0)
				c = 0;
			transformedRGB = new RGB(c, c, c);
			return transformedRGB;
		}
	}

	private final boolean DEBUG = false;
	private final StyleRange[] EMPTY_STYLE_RANGE = new StyleRange[0];
	private static final String LINE_STYLE_PROVIDER_EXTENDED_ID = "linestyleprovider"; //$NON-NLS-1$

	private IPropertyChangeListener fForegroundScaleListener = new IPropertyChangeListener() {
		public void propertyChange(PropertyChangeEvent event) {
			if (EditorPreferenceNames.READ_ONLY_FOREGROUND_SCALE.equals(event.getProperty())) {
				IPreferenceStore editorStore = SSEUIPlugin.getDefault().getPreferenceStore();
				readOnlyForegroundScaleFactor = editorStore.getInt(EditorPreferenceNames.READ_ONLY_FOREGROUND_SCALE);
				disposeColorTable();
				refreshDisplay();
			}
		}
	};
	private List fHoldStyleResults;
	private String fPartitioning = IDocumentExtension3.DEFAULT_PARTITIONING;

	private int fSavedLength = -1;
	private int fSavedOffset = -1;
	private StyleRange[] fSavedRanges = null;

	private IStructuredDocument fStructuredDocument;
	private Map fTableOfProviders;

	private Map fExtendedProviders;

	protected final LineStyleProvider NOOP_PROVIDER = new LineStyleProviderForNoOp();

	private double readOnlyBackgroundScaleFactor = 10;
	private Hashtable readOnlyColorTable;
	double readOnlyForegroundScaleFactor = 30;

	private YUV_RGBConverter rgbConverter;
	private ITextViewer textViewer;
	private StyledText textWidget;

	public Highlighter() {
		super();
	}

	protected void addEmptyRange(int start, int length, Collection holdResults) {
		StyleRange result = new StyleRange();
		result.start = start;
		result.length = length;
		holdResults.add(result);
	}

	/**
	 * Registers a given line style provider for a particular partition type.
	 * If there is already a line style provider registered for this type, the
	 * new line style provider is registered instead of the old one.
	 * 
	 * @param partitionType
	 *            the partition type under which to register
	 * @param the
	 *            line style provider to register, or <code>null</code> to
	 *            remove an existing one
	 */
	public void addProvider(String partitionType, LineStyleProvider provider) {
		getTableOfProviders().put(partitionType, provider);
	}

	/**
	 * Adjust the style ranges' start and length so that they refer to the
	 * textviewer widget's range instead of the textviewer's document range.
	 * 
	 * @param ranges
	 * @param adjustment
	 */
	protected void adjust(StyleRange[] ranges, int adjustment) {
		ITextViewer viewer = getTextViewer();
		ITextViewerExtension5 extension = null;
		if (viewer instanceof ITextViewerExtension5) {
			extension = (ITextViewerExtension5) viewer;
		}

		// convert document regions back to widget regions
		for (int i = 0; i < ranges.length; i++) {
			if (extension != null) {
				// get document range, taking into account folding regions in
				// viewer
				IRegion region = extension.modelRange2WidgetRange(new Region(ranges[i].start, ranges[i].length));
				if (region != null) {
					ranges[i].start = region.getOffset();
					ranges[i].length = region.getLength();
				} // else what happens if region is not found?!
			} else {
				// just adjust the range using the given adjustment
				ranges[i].start += adjustment;
			}
		}
	}


	/**
	 * @deprecated - Read Only areas have unchanged background colors
	 */
	void adjustBackground(StyleRange styleRange) {
		RGB oldRGB = null;
		Color oldColor = styleRange.background;
		if (oldColor == null) {
			oldColor = getTextWidget().getBackground();
		}
		oldRGB = oldColor.getRGB();
		Color newColor = getCachedColorFor(oldRGB);
		if (newColor == null) {
			double target = getRGBConverter().calculateYComponent(oldColor);
			// if background is "light" make it darker, and vice versa
			if (target < 0.5)
				target = 1.0;
			else
				target = 0.0;
			RGB newRGB = getRGBConverter().transformRGB(oldRGB, readOnlyBackgroundScaleFactor / 100.0, target);

			cacheColor(oldRGB, newRGB);
			newColor = getCachedColorFor(oldRGB);
		}
		styleRange.background = newColor;
	}

	private void adjustForeground(StyleRange styleRange) {
		RGB oldRGB = null;
		// Color oldColor = styleRange.foreground;
		Color oldColor = styleRange.background;
		if (oldColor == null) {
			// oldRGB = getTextWidget().getForeground().getRGB();
			oldColor = getTextWidget().getBackground();
			oldRGB = oldColor.getRGB();
		} else {
			oldRGB = oldColor.getRGB();
		}
		Color newColor = getCachedColorFor(oldRGB);
		if (newColor == null) {
			// make text "closer to" background lumanence
			double target = getRGBConverter().calculateYComponent(oldColor);
			RGB newRGB = getRGBConverter().transformRGBToGrey(oldRGB, readOnlyForegroundScaleFactor / 100.0, target);

			// save conversion, so calculations only need to be done once
			cacheColor(oldRGB, newRGB);
			newColor = getCachedColorFor(oldRGB);
		}
		styleRange.foreground = newColor;
	}

	/**
	 * Cache read-only color.
	 * 
	 * @param oldRGB
	 * @param newColor
	 */
	private void cacheColor(RGB oldRGB, RGB newColor) {
		if (readOnlyColorTable == null) {
			readOnlyColorTable = new Hashtable();
		}
		readOnlyColorTable.put(oldRGB, newColor);
	}

	/**
	 * @param result
	 * @return
	 */
	private StyleRange[] convertReadOnlyRegions(StyleRange[] result, int start, int length) {
		IStructuredDocument structuredDocument = getDocument();

		/**
		 * (dmw) For client/provider simplicity (and consistent look and feel)
		 * we'll handle readonly regions in one spot, here in the Highlighter.
		 * Currently it is a fair assumption that each readonly region will be
		 * on an ITextRegion boundary, so we combine consecutive styles when
		 * found to be equivalent. Plus, for now, we'll just adjust
		 * foreground. Eventually will use a "dimming" algrorithm to adjust
		 * color's satuation/brightness.
		 */
		if (structuredDocument.containsReadOnly(start, length)) {
			// something is read-only in the line, so go through each style,
			// and adjust
			for (int i = 0; i < result.length; i++) {
				StyleRange styleRange = result[i];
				if (structuredDocument.containsReadOnly(styleRange.start, styleRange.length)) {
					adjustForeground(styleRange);
				}
			}
		}
		return result;
	}

	/**
	 * Clear out the readOnlyColorTable
	 */
	void disposeColorTable() {
		if (readOnlyColorTable != null) {
			readOnlyColorTable.clear();
		}
		readOnlyColorTable = null;
	}

	/**
	 * This method is just to get existing read-only colors.
	 */
	private Color getCachedColorFor(RGB oldRGB) {
		Color result = null;

		if (readOnlyColorTable != null) {
			RGB readOnlyRGB = (RGB) readOnlyColorTable.get(oldRGB);
			result = EditorUtility.getColor(readOnlyRGB);
		}

		return result;
	}

	protected IStructuredDocument getDocument() {
		return fStructuredDocument;
	}

	/**
	 * Adjust the given widget offset and length so that they are the
	 * textviewer document's offset and length, taking into account what is
	 * actually visible in the document.
	 * 
	 * @param offset
	 * @param length
	 * @return a region containing the offset and length within the
	 *         textviewer's document or null if the offset is not within the
	 *         document
	 */
	private IRegion getDocumentRangeFromWidgetRange(int offset, int length) {
		IRegion styleRegion = null;
		ITextViewer viewer = getTextViewer();
		if (viewer instanceof ITextViewerExtension5) {
			// get document range, taking into account folding regions in
			// viewer
			ITextViewerExtension5 extension = (ITextViewerExtension5) viewer;
			styleRegion = extension.widgetRange2ModelRange(new Region(offset, length));
		} else {
			// get document range, taking into account viewer visible region
			// get visible region in viewer
			IRegion vr = null;
			if (viewer != null)
				vr = viewer.getVisibleRegion();
			else
				vr = new Region(0, getDocument().getLength());

			// if offset is not within visible region, then we don't really
			// care
			if (offset <= vr.getLength()) {
				// Adjust the offset to be within visible region
				styleRegion = new Region(offset + vr.getOffset(), length);
			}
		}
		return styleRegion;
	}


	private Map getExtendedProviders() {
		if (fExtendedProviders == null) {
			fExtendedProviders = new HashMap(3);
		}
		return fExtendedProviders;
	}

	/**
	 * Method getProviderFor.
	 * 
	 * @param typedRegion
	 * @return LineStyleProvider
	 */
	private LineStyleProvider getProviderFor(ITypedRegion typedRegion) {
		String type = typedRegion.getType();
		LineStyleProvider result = (LineStyleProvider) fTableOfProviders.get(type);
		if (result == null) {
			// NOT YET FINALIZED - DO NOT CONSIDER AS API
			synchronized (getExtendedProviders()) {
				if (!getExtendedProviders().containsKey(type)) {
					LineStyleProvider provider = (LineStyleProvider) ExtendedConfigurationBuilder.getInstance().getConfiguration(LINE_STYLE_PROVIDER_EXTENDED_ID, type);
					getExtendedProviders().put(type, provider);
					if (provider != null) {
						provider.init(getDocument(), this);
					}
					result = provider;
				} else {
					result = (LineStyleProvider) getExtendedProviders().get(type);
				}
			}
		}
		if (result == null) {
			result = NOOP_PROVIDER;
		}
		return result;
	}

	private YUV_RGBConverter getRGBConverter() {
		if (rgbConverter == null) {
			rgbConverter = new YUV_RGBConverter();
		}
		return rgbConverter;
	}

	private Map getTableOfProviders() {
		if (fTableOfProviders == null) {
			fTableOfProviders = new HashMap();
		}
		return fTableOfProviders;
	}

	/**
	 * Returns the textViewer.
	 * 
	 * @return ITextViewer
	 */
	public ITextViewer getTextViewer() {
		return textViewer;
	}

	/**
	 * @return
	 */
	protected StyledText getTextWidget() {
		return textWidget;
	}

	/**
	 * Installs highlighter support on the given text viewer.
	 * 
	 * @param textViewer
	 *            the text viewer on which content assist will work
	 */
	public void install(ITextViewer newTextViewer) {
		this.textViewer = newTextViewer;

		IPreferenceStore editorStore = SSEUIPlugin.getDefault().getPreferenceStore();
		editorStore.addPropertyChangeListener(fForegroundScaleListener);
		readOnlyForegroundScaleFactor = editorStore.getInt(EditorPreferenceNames.READ_ONLY_FOREGROUND_SCALE);

		if (textWidget != null) {
			textWidget.removeLineStyleListener(this);
		}
		textWidget = newTextViewer.getTextWidget();
		if (textWidget != null) {
			textWidget.addLineStyleListener(this);
		}

		refreshDisplay();
	}

	public StyleRange[] lineGetStyle(int eventLineOffset, int eventLineLength) {
		StyleRange[] eventStyles = EMPTY_STYLE_RANGE;
		try {
			if (getDocument() == null || eventLineLength == 0) {
				// getDocument() == null
				// during initialization, this is sometimes called before our
				// structured
				// is set, in which case we set styles to be the empty style
				// range
				// (event.styles can not be null)

				// eventLineLength == 0
				// we sometimes get odd requests from the very last CRLF in
				// the
				// document
				// it has no length, and there is no node for it!
				eventStyles = EMPTY_STYLE_RANGE;
			} else {
				/*
				 * LineStyleProviders work using absolute document offsets. To
				 * support visible regions, adjust the requested range up to
				 * the full document offsets.
				 */
				IRegion styleRegion = getDocumentRangeFromWidgetRange(eventLineOffset, eventLineLength);
				if (styleRegion != null) {
					int start = styleRegion.getOffset();
					int length = styleRegion.getLength();

					ITypedRegion[] partitions = TextUtilities.computePartitioning(getDocument(), fPartitioning, start, length, false);
					eventStyles = prepareStyleRangesArray(partitions, start, length);

					// If there is a subtext offset, the style ranges must be
					// adjusted to the expected
					// offsets
					// just check if eventLineOffset is different than start
					// then adjust, otherwise u can leave it alone
					// unless there is special handling for
					// itextviewerextension5?
					if (start != eventLineOffset) {
						int offset = 0;
						// figure out visible region to use for adjustment
						// only adjust if need to
						if (!(getTextViewer() instanceof ITextViewerExtension5)) {
							IRegion vr = getTextViewer().getVisibleRegion();
							if (vr != null) {
								offset = vr.getOffset();
								if (offset > 0)
									adjust(eventStyles, -offset);
							}
						} else {
							if (getTextViewer() instanceof ProjectionViewer) {
								if (((ProjectionViewer) getTextViewer()).isProjectionMode())
									adjust(eventStyles, -offset);
							}
						}

					}

					// for debugging only
					if (DEBUG) {
						if (!valid(eventStyles, eventLineOffset, eventLineLength)) {
							Logger.log(Logger.WARNING, "Highlighter::lineGetStyle found invalid styles at offset " + eventLineOffset); //$NON-NLS-1$
						}
					}
				}

			}

		} catch (Exception e) {
			// if ANY exception occurs during highlighting,
			// just return "no highlighting"
			eventStyles = EMPTY_STYLE_RANGE;
			if (Debug.syntaxHighlighting) {
				System.out.println("Exception during highlighting!"); //$NON-NLS-1$
			}
		}

		return eventStyles;
	}

	/**
	 * A passthrough method that extracts relevant data from the
	 * LineStyleEvent and passes it along. This method was separated for
	 * performance testing purposes.
	 * 
	 * @see org.eclipse.swt.custom.LineStyleListener#lineGetStyle(LineStyleEvent)
	 */
	public void lineGetStyle(LineStyleEvent event) {
		int offset = event.lineOffset;
		int length = event.lineText.length();

		/*
		 * For some reason, we are sometimes asked for the same style range
		 * over and over again. This was found to happen during 'revert' of a
		 * file with one line in it that is 40K long! So, while we don't know
		 * root cause, caching the styled ranges in case the exact same
		 * request is made multiple times seems like cheap insurance.
		 */
		if (offset == fSavedOffset && length == fSavedLength && fSavedRanges != null) {
			event.styles = fSavedRanges;
		} else {
			// need to assign this array here, or else the field won't get
			// updated
			event.styles = lineGetStyle(offset, length);
			// now saved "cached data" for repeated requests which are exaclty
			// same
			fSavedOffset = offset;
			fSavedLength = length;
			fSavedRanges = event.styles;
		}
	}

	/**
	 * Note: its very important this method never return null, which is why
	 * the final null check is in a finally clause
	 */

	protected StyleRange[] prepareStyleRangesArray(ITypedRegion[] partitions, int start, int length) {

		StyleRange[] result = EMPTY_STYLE_RANGE;

		if (fHoldStyleResults == null) {
			fHoldStyleResults = new ArrayList(partitions.length);
		} else {
			fHoldStyleResults.clear();
		}

		// TODO: make some of these instance variables to prevent creation on
		// stack
		LineStyleProvider currentLineStyleProvider = null;
		boolean handled = false;
		for (int i = 0; i < partitions.length; i++) {
			ITypedRegion currentPartition = partitions[i];
			currentLineStyleProvider = getProviderFor(currentPartition);
			currentLineStyleProvider.init(getDocument(), this);
			handled = currentLineStyleProvider.prepareRegions(currentPartition, currentPartition.getOffset(), currentPartition.getLength(), fHoldStyleResults);
			if (Debug.syntaxHighlighting && !handled) {
				System.out.println("Did not handle highlighting in Highlighter inner while"); //$NON-NLS-1$
			}
		}

		int resultSize = fHoldStyleResults.size();
		if (resultSize > 0) {
			result = (StyleRange[]) fHoldStyleResults.toArray(new StyleRange[fHoldStyleResults.size()]);
		} else {
			result = EMPTY_STYLE_RANGE;
		}
		result = convertReadOnlyRegions(result, start, length);
		return result;
	}

	public void refreshDisplay() {
		if (textWidget != null && !textWidget.isDisposed())
			textWidget.redraw();
	}

	/**
	 */
	public void refreshDisplay(int start, int length) {
		if (textWidget != null && !textWidget.isDisposed())
			textWidget.redrawRange(start, length, true);
	}

	public void removeProvider(String partitionType) {
		getTableOfProviders().remove(partitionType);
	}

	public void setDocument(IStructuredDocument structuredDocument) {
		fStructuredDocument = structuredDocument;
	}

	public void setDocumentPartitioning(String partitioning) {
		if (partitioning != null) {
			fPartitioning = partitioning;
		} else {
			fPartitioning = IDocumentExtension3.DEFAULT_PARTITIONING;
		}
	}

	/**
	 * Uninstalls highlighter support from the text viewer it has previously
	 * be installed on.
	 */
	public void uninstall() {
		if (textWidget != null && !textWidget.isDisposed()) {
			textWidget.removeLineStyleListener(this);
		}
		textWidget = null;

		Collection providers = getTableOfProviders().values();
		Iterator iterator = providers.iterator();
		while (iterator.hasNext()) {
			LineStyleProvider lineStyleProvider = (LineStyleProvider) iterator.next();
			lineStyleProvider.release();
			// this remove probably isn't strictly needed, since
			// typically highlighter instance as a whole will go
			// away ... but in case that ever changes, this seems like
			// a better style.
			iterator.remove();
		}

		synchronized (getExtendedProviders()) {
			providers = new ArrayList(getExtendedProviders().values());
			getExtendedProviders().clear();
		}
		iterator = providers.iterator();
		while (iterator.hasNext()) {
			LineStyleProvider lineStyleProvider = (LineStyleProvider) iterator.next();
			if (lineStyleProvider != null) {
				lineStyleProvider.release();
				iterator.remove();
			}
		}

		IPreferenceStore editorStore = SSEUIPlugin.getDefault().getPreferenceStore();
		editorStore.removePropertyChangeListener(fForegroundScaleListener);
		disposeColorTable();

		// clear out cached variables (d282894)
		fSavedOffset = -1;
		fSavedLength = -1;
		fSavedRanges = null;
	}

	/**
	 * Purely a debugging aide.
	 */
	private boolean valid(StyleRange[] eventStyles, int startOffset, int lineLength) {
		boolean result = false;
		if (eventStyles != null) {
			if (eventStyles.length > 0) {
				StyleRange first = eventStyles[0];
				StyleRange last = eventStyles[eventStyles.length - 1];
				if (startOffset > first.start) {
					result = false;
				} else {
					int lineEndOffset = startOffset + lineLength;
					int lastOffset = last.start + last.length;
					if (lastOffset > lineEndOffset) {
						result = false;
					} else {
						result = true;
					}
				}
			} else {
				// a zero length array is ok
				result = true;
			}
		}
		return result;
	}
}
