/*******************************************************************************
 * Copyright (c) 2005, 2018 IBM Corporation and others.
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 *******************************************************************************/
package org.eclipse.dltk.internal.ui.editor;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.URI;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.eclipse.core.filesystem.EFS;
import org.eclipse.core.filesystem.IFileStore;
import org.eclipse.core.filesystem.URIUtil;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IMarkerDelta;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.resources.IStorage;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.ISafeRunnable;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.ListenerList;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.SafeRunner;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.core.runtime.jobs.ISchedulingRule;
import org.eclipse.dltk.compiler.problem.CategorizedProblem;
import org.eclipse.dltk.compiler.problem.DefaultProblem;
import org.eclipse.dltk.compiler.problem.IProblem;
import org.eclipse.dltk.compiler.problem.IProblemFactory;
import org.eclipse.dltk.compiler.problem.IProblemIdentifier;
import org.eclipse.dltk.compiler.problem.IProblemIdentifierExtension;
import org.eclipse.dltk.core.DLTKCore;
import org.eclipse.dltk.core.IBuffer;
import org.eclipse.dltk.core.IBuildpathEntry;
import org.eclipse.dltk.core.IModelElement;
import org.eclipse.dltk.core.IProblemRequestor;
import org.eclipse.dltk.core.IScriptModel;
import org.eclipse.dltk.core.IScriptProject;
import org.eclipse.dltk.core.ISourceModule;
import org.eclipse.dltk.core.ModelException;
import org.eclipse.dltk.core.ScriptModelUtil;
import org.eclipse.dltk.core.WorkingCopyOwner;
import org.eclipse.dltk.internal.core.BufferManager;
import org.eclipse.dltk.internal.ui.IDLTKStatusConstants;
import org.eclipse.dltk.internal.ui.text.IProblemRequestorExtension;
import org.eclipse.dltk.internal.ui.text.spelling.ScriptSpellingProblem;
import org.eclipse.dltk.internal.ui.text.spelling.SpellingProblems;
import org.eclipse.dltk.launching.ScriptRuntime;
import org.eclipse.dltk.ui.DLTKPluginImages;
import org.eclipse.dltk.ui.DLTKUIPlugin;
import org.eclipse.dltk.ui.PreferenceConstants;
import org.eclipse.dltk.ui.editor.IScriptAnnotation;
import org.eclipse.dltk.ui.editor.ScriptMarkerAnnotation;
import org.eclipse.dltk.ui.editor.SourceModuleAnnotationModelEvent;
import org.eclipse.dltk.ui.editor.saveparticipant.IPostSaveListener;
import org.eclipse.dltk.ui.editor.saveparticipant.SaveParticipantRegistry;
import org.eclipse.dltk.ui.text.ScriptAnnotationUtils;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.DefaultLineTracker;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.ILineTracker;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ISynchronizable;
import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.quickassist.IQuickFixableAnnotation;
import org.eclipse.jface.text.source.Annotation;
import org.eclipse.jface.text.source.AnnotationModel;
import org.eclipse.jface.text.source.AnnotationModelEvent;
import org.eclipse.jface.text.source.IAnnotationAccessExtension;
import org.eclipse.jface.text.source.IAnnotationModel;
import org.eclipse.jface.text.source.IAnnotationModelListener;
import org.eclipse.jface.text.source.IAnnotationModelListenerExtension;
import org.eclipse.jface.text.source.IAnnotationPresentation;
import org.eclipse.jface.text.source.ImageUtilities;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.IStorageEditorInput;
import org.eclipse.ui.IURIEditorInput;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.editors.text.EditorsUI;
import org.eclipse.ui.editors.text.TextFileDocumentProvider;
import org.eclipse.ui.ide.FileStoreEditorInput;
import org.eclipse.ui.ide.IDE.SharedImages;
import org.eclipse.ui.internal.editors.text.NonExistingFileEditorInput;
import org.eclipse.ui.texteditor.AbstractMarkerAnnotationModel;
import org.eclipse.ui.texteditor.AnnotationPreference;
import org.eclipse.ui.texteditor.AnnotationPreferenceLookup;
import org.eclipse.ui.texteditor.IDocumentProvider;
import org.eclipse.ui.texteditor.MarkerAnnotation;
import org.eclipse.ui.texteditor.MarkerUtilities;
import org.eclipse.ui.texteditor.ResourceMarkerAnnotationModel;
import org.eclipse.ui.texteditor.spelling.SpellingAnnotation;

public class SourceModuleDocumentProvider extends TextFileDocumentProvider implements ISourceModuleDocumentProvider {

	/** Indicates whether the save has been initialized by this provider */
	private boolean fIsAboutToSave = false;

	/** Preference key for temporary problems */
	private final static String HANDLE_TEMPORARY_PROBLEMS = PreferenceConstants.EDITOR_EVALUTE_TEMPORARY_PROBLEMS;

	/** The save policy used by this provider */
	private ISavePolicy fSavePolicy;

	/** Internal property changed listener */
	private IPropertyChangeListener fPropertyListener;
	/** Annotation model listener added to all created CU annotation models */
	private GlobalAnnotationModelListener fGlobalAnnotationModelListener;

	@Override
	public boolean isModifiable(Object element) {
		if (element instanceof FileStoreEditorInput) {
			ISourceModule module = DLTKUIPlugin.resolveSourceModule((FileStoreEditorInput) element);
			if (module != null) {
				return !module.isReadOnly();
			}
		}

		return super.isModifiable(element);
	}

	/**
	 * Annotation representing an <code>IProblem</code>.
	 */
	static public class ProblemAnnotation extends Annotation
			implements IScriptAnnotation, IAnnotationPresentation, IQuickFixableAnnotation {

		public static final String SPELLING_ANNOTATION_TYPE = SpellingAnnotation.TYPE;

		// XXX: To be fully correct these constants should be non-static
		/**
		 * The layer in which task problem annotations are located.
		 */
		private static final int TASK_LAYER;
		/**
		 * The layer in which info problem annotations are located.
		 */
		private static final int INFO_LAYER;
		/**
		 * The layer in which warning problem annotations representing are located.
		 */
		private static final int WARNING_LAYER;
		/**
		 * The layer in which error problem annotations representing are located.
		 */
		private static final int ERROR_LAYER;

		static {
			final AnnotationPreferenceLookup lookup = EditorsUI.getAnnotationPreferenceLookup();
			TASK_LAYER = computeLayer(ScriptMarkerAnnotation.TASK_ANNOTATION_TYPE, lookup);
			INFO_LAYER = computeLayer(ScriptMarkerAnnotation.INFO_ANNOTATION_TYPE, lookup);
			WARNING_LAYER = computeLayer(ScriptMarkerAnnotation.WARNING_ANNOTATION_TYPE, lookup);
			ERROR_LAYER = computeLayer(ScriptMarkerAnnotation.ERROR_ANNOTATION_TYPE, lookup);
		}

		private static int computeLayer(String annotationType, AnnotationPreferenceLookup lookup) {
			Annotation annotation = new Annotation(annotationType, false, null);
			AnnotationPreference preference = lookup.getAnnotationPreference(annotation);
			if (preference != null) {
				return preference.getPresentationLayer() + 1;
			}
			return IAnnotationAccessExtension.DEFAULT_LAYER + 1;
		}

		private static Image fgQuickFixImage;
		private static Image fgQuickFixErrorImage;

		private static Image fgTaskImage;
		private static Image fgInfoImage;
		private static Image fgWarningImage;
		private static Image fgErrorImage;
		private static boolean fgImagesInitialized = false;

		private final ISourceModule fSourceModule;
		private List<IScriptAnnotation> fOverlaids;
		private final IProblem fProblem;
		private Image fImage;
		private boolean fImageInitialized = false;
		private int fLayer = IAnnotationAccessExtension.DEFAULT_LAYER;
		private boolean fIsQuickFixable;
		private boolean fIsQuickFixableStateSet = false;

		public ProblemAnnotation(IProblem problem, ISourceModule cu) {

			fProblem = problem;
			fSourceModule = cu;

			if (SpellingProblems.SPELLING_PROBLEM == fProblem.getID()) {
				setType(SPELLING_ANNOTATION_TYPE);
				fLayer = WARNING_LAYER;
			} else if (fProblem.isTask()) {
				setType(ScriptMarkerAnnotation.TASK_ANNOTATION_TYPE);
				fLayer = TASK_LAYER;
			} else if (fProblem.isWarning()) {
				setType(ScriptMarkerAnnotation.WARNING_ANNOTATION_TYPE);
				fLayer = WARNING_LAYER;
			} else if (fProblem.isError()) {
				setType(ScriptMarkerAnnotation.ERROR_ANNOTATION_TYPE);
				fLayer = ERROR_LAYER;
			} else {
				setType(ScriptMarkerAnnotation.INFO_ANNOTATION_TYPE);
				fLayer = INFO_LAYER;
			}
		}

		@Override
		public int getLayer() {
			return fLayer;
		}

		/**
		 * delayed image loading - to be sure it is called on the UI thread
		 */
		private void initializeImage() {
			if (!fImageInitialized) {
				initializeImages();
				if (!isQuickFixableStateSet()) {
					setQuickFixable(isProblem() && ScriptAnnotationUtils.hasCorrections(this));
				}
				if (isQuickFixable()) {
					if (ScriptMarkerAnnotation.ERROR_ANNOTATION_TYPE.equals(getType()))
						fImage = fgQuickFixErrorImage;
					else
						fImage = fgQuickFixImage;
				} else {
					final String type = getType();
					if (ScriptMarkerAnnotation.TASK_ANNOTATION_TYPE.equals(type))
						fImage = fgTaskImage;
					else if (ScriptMarkerAnnotation.INFO_ANNOTATION_TYPE.equals(type))
						fImage = fgInfoImage;
					else if (ScriptMarkerAnnotation.WARNING_ANNOTATION_TYPE.equals(type))
						fImage = fgWarningImage;
					else if (ScriptMarkerAnnotation.ERROR_ANNOTATION_TYPE.equals(type))
						fImage = fgErrorImage;
				}
				fImageInitialized = true;
			}
		}

		private static void initializeImages() {
			if (fgImagesInitialized)
				return;

			fgQuickFixImage = DLTKPluginImages.get(DLTKPluginImages.IMG_OBJS_FIXABLE_PROBLEM);
			fgQuickFixErrorImage = DLTKPluginImages.get(DLTKPluginImages.IMG_OBJS_FIXABLE_ERROR);

			final ISharedImages sharedImages = PlatformUI.getWorkbench().getSharedImages();
			fgTaskImage = sharedImages.getImage(SharedImages.IMG_OBJS_TASK_TSK);
			fgInfoImage = sharedImages.getImage(ISharedImages.IMG_OBJS_INFO_TSK);
			fgWarningImage = sharedImages.getImage(ISharedImages.IMG_OBJS_WARN_TSK);
			fgErrorImage = sharedImages.getImage(ISharedImages.IMG_OBJS_ERROR_TSK);

			fgImagesInitialized = true;
		}

		@Override
		public void paint(GC gc, Canvas canvas, Rectangle r) {
			initializeImage();
			if (fImage != null)
				ImageUtilities.drawImage(fImage, gc, canvas, r, SWT.CENTER, SWT.TOP);
		}

		public Image getImage(Display display) {
			initializeImage();
			return fImage;
		}

		@Override
		public String getText() {
			String[] arguments = getArguments();
			if (arguments != null) {
				for (int i = 0; i < arguments.length; i++) {
					String ar = arguments[i];
					if (ar.startsWith(IProblem.DESCRIPTION_ARGUMENT_PREFIX)) {
						return fProblem.getMessage() + '\n'
								+ ar.substring(IProblem.DESCRIPTION_ARGUMENT_PREFIX.length());
					}
				}
			}
			return fProblem.getMessage();
		}

		@Override
		public String[] getArguments() {
			return isProblem() ? fProblem.getArguments() : null;
		}

		@Override
		public IProblemIdentifier getId() {
			return fProblem.getID();
		}

		@Override
		public boolean isProblem() {
			String type = getType();
			return ScriptMarkerAnnotation.WARNING_ANNOTATION_TYPE.equals(type)
					|| ScriptMarkerAnnotation.ERROR_ANNOTATION_TYPE.equals(type)
					|| SPELLING_ANNOTATION_TYPE.equals(type);
		}

		@Override
		public boolean hasOverlay() {
			return false;
		}

		@Override
		public IScriptAnnotation getOverlay() {
			return null;
		}

		@Override
		public void addOverlaid(IScriptAnnotation annotation) {
			if (fOverlaids == null)
				fOverlaids = new ArrayList<>(1);
			fOverlaids.add(annotation);
		}

		@Override
		public void removeOverlaid(IScriptAnnotation annotation) {
			if (fOverlaids != null) {
				fOverlaids.remove(annotation);
				if (fOverlaids.size() == 0)
					fOverlaids = null;
			}
		}

		@Override
		public Iterator<IScriptAnnotation> getOverlaidIterator() {
			if (fOverlaids != null)
				return fOverlaids.iterator();
			return null;
		}

		@Override
		public ISourceModule getSourceModule() {
			return fSourceModule;
		}

		public IProblem getProblem() {
			return fProblem;
		}

		@Override
		public String getMarkerType() {
			if (fProblem.getID() instanceof IProblemIdentifierExtension) {
				return ((IProblemIdentifierExtension) fProblem.getID()).getMarkerType();
			}
			if (fProblem instanceof CategorizedProblem) {
				return ((CategorizedProblem) fProblem).getMarkerType();
			}
			return null;
		}

		/*
		 * @seeorg.eclipse.jface.text.quickassist.IQuickFixableAnnotation#
		 * setQuickFixable(boolean)
		 *
		 * @since 3.2
		 */
		@Override
		public void setQuickFixable(boolean state) {
			fIsQuickFixable = state;
			fIsQuickFixableStateSet = true;
		}

		/*
		 * @seeorg.eclipse.jface.text.quickassist.IQuickFixableAnnotation#
		 * isQuickFixableStateSet()
		 *
		 * @since 3.2
		 */
		@Override
		public boolean isQuickFixableStateSet() {
			return fIsQuickFixableStateSet;
		}

		/*
		 * @see org.eclipse.jface.text.quickassist.IQuickFixableAnnotation#
		 * isQuickFixable ()
		 *
		 * @since 3.2
		 */
		@Override
		public boolean isQuickFixable() {
			Assert.isTrue(isQuickFixableStateSet());
			return fIsQuickFixable;
		}

		@Override
		public int getSourceStart() {
			return fProblem.getSourceStart();
		}

		@Override
		public int getSourceEnd() {
			return fProblem.getSourceEnd();
		}
	}

	/**
	 * Internal structure for mapping positions to some value. The reason for this
	 * specific structure is that positions can change over time. Thus a lookup is
	 * based on value and not on hash value.
	 */
	protected static class ReverseMap {

		static class Entry {
			Position fPosition;
			Object fValue;
		}

		private List<Entry> fList = new ArrayList<>(2);
		private int fAnchor = 0;

		public ReverseMap() {
		}

		public Object get(Position position) {

			Entry entry;

			// behind anchor
			int length = fList.size();
			for (int i = fAnchor; i < length; i++) {
				entry = fList.get(i);
				if (entry.fPosition.equals(position)) {
					fAnchor = i;
					return entry.fValue;
				}
			}

			// before anchor
			for (int i = 0; i < fAnchor; i++) {
				entry = fList.get(i);
				if (entry.fPosition.equals(position)) {
					fAnchor = i;
					return entry.fValue;
				}
			}

			return null;
		}

		private int getIndex(Position position) {
			Entry entry;
			int length = fList.size();
			for (int i = 0; i < length; i++) {
				entry = fList.get(i);
				if (entry.fPosition.equals(position))
					return i;
			}
			return -1;
		}

		public void put(Position position, Object value) {
			int index = getIndex(position);
			if (index == -1) {
				Entry entry = new Entry();
				entry.fPosition = position;
				entry.fValue = value;
				fList.add(entry);
			} else {
				Entry entry = fList.get(index);
				entry.fValue = value;
			}
		}

		public void remove(Position position) {
			int index = getIndex(position);
			if (index > -1)
				fList.remove(index);
		}

		public void clear() {
			fList.clear();
		}
	}

	/**
	 * Annotation model dealing with java marker annotations and temporary problems.
	 * Also acts as problem requester for its compilation unit. Initially inactive.
	 * Must explicitly be activated.
	 */
	public static class SourceModuleAnnotationModel extends ResourceMarkerAnnotationModel
			implements IProblemRequestor, IProblemRequestorExtension {

		private static class ProblemRequestorState {
			boolean fInsideReportingSequence = false;
			List<IProblem> fReportedProblems;
		}

		private ThreadLocal<ProblemRequestorState> fProblemRequestorState = new ThreadLocal<>();
		private int fStateCount = 0;

		private ISourceModule fSourceModule;
		private List<Annotation> fGeneratedAnnotations = new ArrayList<>();
		private IProgressMonitor fProgressMonitor;
		private boolean fIsActive = false;
		private boolean fIsHandlingTemporaryProblems;

		private ReverseMap fReverseMap = new ReverseMap();
		private List<ScriptMarkerAnnotation> fPreviouslyOverlaid = null;
		private List<ScriptMarkerAnnotation> fCurrentlyOverlaid = new ArrayList<>();
		protected IProblemFactory problemFactory;

		public SourceModuleAnnotationModel(IResource resource) {
			super(resource);
		}

		public void setSourceModule(ISourceModule unit) {
			fSourceModule = unit;
		}

		@Override
		protected MarkerAnnotation createMarkerAnnotation(IMarker marker) {
			if (isScriptMarker(marker))
				return new ScriptMarkerAnnotation(marker);
			return super.createMarkerAnnotation(marker);
		}

		private boolean isScriptMarker(IMarker marker) {
			if (problemFactory != null) {
				return problemFactory.isValidMarker(marker);
			}
			return MarkerUtilities.isMarkerType(marker, DefaultProblem.MARKER_TYPE_PROBLEM)
					|| MarkerUtilities.isMarkerType(marker, DefaultProblem.MARKER_TYPE_TASK);
		}

		@Override
		protected AnnotationModelEvent createAnnotationModelEvent() {
			return new SourceModuleAnnotationModelEvent(this, getResource());
		}

		protected Position createPositionFromProblem(IProblem problem) {
			int start = problem.getSourceStart();
			int end = problem.getSourceEnd();
			if (start <= 0 && end <= 0)
				return new Position(0);
			if (start < 0)
				return new Position(end);
			if (end < 0)
				return new Position(start);
			int length = end - start;
			if (length < 0)
				return null;
			if (fDocument != null) {
				final int documentLength = fDocument.getLength();
				if (start > documentLength)
					start = documentLength;
				if (start + length > documentLength) {
					length = documentLength - start;
				}
			}
			return new Position(start, length);
		}

		@Override
		public void beginReporting() {
			ProblemRequestorState state = fProblemRequestorState.get();
			if (state == null)
				internalBeginReporting(false);
		}

		@Override
		public void beginReportingSequence() {
			ProblemRequestorState state = fProblemRequestorState.get();
			if (state == null)
				internalBeginReporting(true);
		}

		/**
		 * Sets up the infrastructure necessary for problem reporting.
		 *
		 * @param insideReportingSequence <code>true</code> if this method call is
		 *                                issued from inside a reporting sequence
		 */
		private void internalBeginReporting(boolean insideReportingSequence) {

			// the same behavior as in
			// AbstractSourceModule.getAccumulatingProblemReporter
			if (fSourceModule != null && !fSourceModule.isReadOnly()) {
				ProblemRequestorState state = new ProblemRequestorState();
				state.fInsideReportingSequence = insideReportingSequence;
				state.fReportedProblems = new ArrayList<>();
				synchronized (getLockObject()) {
					fProblemRequestorState.set(state);
					++fStateCount;
				}
			}
		}

		@Override
		public void acceptProblem(IProblem problem) {
			if (fIsHandlingTemporaryProblems || problem.getID() == SpellingProblems.SPELLING_PROBLEM) {
				ProblemRequestorState state = fProblemRequestorState.get();
				if (state != null)
					state.fReportedProblems.add(problem);
			}
		}

		@Override
		public void endReporting() {
			ProblemRequestorState state = fProblemRequestorState.get();
			if (state != null && !state.fInsideReportingSequence)
				internalEndReporting(state);
		}

		@Override
		public void endReportingSequence() {
			ProblemRequestorState state = fProblemRequestorState.get();
			if (state != null && state.fInsideReportingSequence)
				internalEndReporting(state);
		}

		private void internalEndReporting(ProblemRequestorState state) {
			int stateCount = 0;
			synchronized (getLockObject()) {
				--fStateCount;
				stateCount = fStateCount;
				fProblemRequestorState.set(null);
			}

			if (stateCount == 0)
				reportProblems(state.fReportedProblems);
		}

		/**
		 * Signals the end of problem reporting.
		 */
		private void reportProblems(List<IProblem> reportedProblems) {
			if (fProgressMonitor != null && fProgressMonitor.isCanceled())
				return;

			boolean temporaryProblemsChanged = false;

			synchronized (getLockObject()) {

				boolean isCanceled = false;

				fPreviouslyOverlaid = fCurrentlyOverlaid;
				fCurrentlyOverlaid = new ArrayList<>();

				if (fGeneratedAnnotations.size() > 0) {
					temporaryProblemsChanged = true;
					removeAnnotations(fGeneratedAnnotations, false, true);
					fGeneratedAnnotations.clear();
				}

				if (reportedProblems != null && reportedProblems.size() > 0) {

					Iterator<IProblem> e = reportedProblems.iterator();
					while (e.hasNext()) {

						if (fProgressMonitor != null && fProgressMonitor.isCanceled()) {
							isCanceled = true;
							break;
						}

						IProblem problem = e.next();
						Position position = createPositionFromProblem(problem);
						if (position != null) {

							try {
								if (problem instanceof ScriptSpellingProblem) {
									SpellingAnnotation annotation = new SpellingAnnotation(
											((ScriptSpellingProblem) problem).getSpellingProblem());
									addAnnotation(annotation, position, false);
									fGeneratedAnnotations.add(annotation);
								}
								ProblemAnnotation annotation = new ProblemAnnotation(problem, fSourceModule);
								overlayMarkers(position, annotation);

								addAnnotation(annotation, position, false);
								fGeneratedAnnotations.add(annotation);

								temporaryProblemsChanged = true;
							} catch (BadLocationException x) {
								// ignore invalid position
							}
						}
					}
				}

				removeMarkerOverlays(isCanceled);
				fPreviouslyOverlaid = null;
			}

			if (temporaryProblemsChanged)
				fireModelChanged();
		}

		private void removeMarkerOverlays(boolean isCanceled) {
			if (isCanceled) {
				fCurrentlyOverlaid.addAll(fPreviouslyOverlaid);
			} else if (fPreviouslyOverlaid != null) {
				for (ScriptMarkerAnnotation annotation : fPreviouslyOverlaid) {
					annotation.setOverlay(null);
				}
			}
		}

		/**
		 * Overlays value with problem annotation.
		 *
		 * @param problemAnnotation
		 */
		private void setOverlay(Object value, ProblemAnnotation problemAnnotation) {
			if (value instanceof ScriptMarkerAnnotation) {
				ScriptMarkerAnnotation annotation = (ScriptMarkerAnnotation) value;
				if (annotation.isProblem()) {
					annotation.setOverlay(problemAnnotation);
					fPreviouslyOverlaid.remove(annotation);
					fCurrentlyOverlaid.add(annotation);
				}
			} else {
			}
		}

		private void overlayMarkers(Position position, ProblemAnnotation problemAnnotation) {
			Object value = getAnnotations(position);
			if (value instanceof List<?>) {
				List<?> list = (List<?>) value;
				for (Iterator<?> e = list.iterator(); e.hasNext();)
					setOverlay(e.next(), problemAnnotation);
			} else {
				setOverlay(value, problemAnnotation);
			}
		}

		/**
		 * Tells this annotation model to collect temporary problems from now on.
		 */
		private void startCollectingProblems() {
			fGeneratedAnnotations.clear();
		}

		/**
		 * Tells this annotation model to no longer collect temporary problems.
		 */
		private void stopCollectingProblems() {
			if (fGeneratedAnnotations != null)
				removeAnnotations(fGeneratedAnnotations, true, true);
			fGeneratedAnnotations.clear();
		}

		/*
		 * @see IProblemRequestor#isActive()
		 */
		@Override
		public boolean isActive() {
			return fIsActive;
		}

		/*
		 * @see IProblemRequestorExtension#setProgressMonitor(IProgressMonitor)
		 */
		@Override
		public void setProgressMonitor(IProgressMonitor monitor) {
			fProgressMonitor = monitor;
		}

		/*
		 * @see IProblemRequestorExtension#setIsActive(boolean)
		 */
		@Override
		public void setIsActive(boolean isActive) {
			fIsActive = isActive;
		}

		/*
		 * @see IProblemRequestorExtension#setIsHandlingTemporaryProblems(boolean)
		 *
		 * @since 3.1
		 */
		@Override
		public void setIsHandlingTemporaryProblems(boolean enable) {
			if (fIsHandlingTemporaryProblems != enable) {
				fIsHandlingTemporaryProblems = enable;
				if (fIsHandlingTemporaryProblems)
					startCollectingProblems();
				else
					stopCollectingProblems();
			}

		}

		private Object getAnnotations(Position position) {
			synchronized (getLockObject()) {
				return fReverseMap.get(position);
			}
		}

		@Override
		protected void addAnnotation(Annotation annotation, Position position, boolean fireModelChanged)
				throws BadLocationException {
			super.addAnnotation(annotation, position, fireModelChanged);

			if (annotation instanceof ProblemAnnotation || annotation instanceof MarkerAnnotation) {
				synchronized (getLockObject()) {
					Object cached = fReverseMap.get(position);
					if (cached == null)
						fReverseMap.put(position, annotation);
					else if (cached instanceof List<?>) {
						@SuppressWarnings("unchecked")
						List<Annotation> list = (List<Annotation>) cached;
						list.add(annotation);
					} else if (cached instanceof Annotation) {
						List<Annotation> list = new ArrayList<>(2);
						list.add((Annotation) cached);
						list.add(annotation);
						fReverseMap.put(position, list);
					}
				}
			}
		}

		/*
		 * @see AnnotationModel#removeAllAnnotations(boolean)
		 */
		@Override
		protected void removeAllAnnotations(boolean fireModelChanged) {
			super.removeAllAnnotations(fireModelChanged);
			synchronized (getLockObject()) {
				fReverseMap.clear();
			}
		}

		@Override
		protected void removeAnnotation(Annotation annotation, boolean fireModelChanged) {
			if (annotation instanceof ProblemAnnotation || annotation instanceof MarkerAnnotation) {
				Position position = getPosition(annotation);
				synchronized (getLockObject()) {
					Object cached = fReverseMap.get(position);
					if (cached instanceof List<?>) {
						List<?> list = (List<?>) cached;
						list.remove(annotation);
						if (list.size() == 1) {
							fReverseMap.put(position, list.get(0));
							list.clear();
						}
					} else if (cached instanceof Annotation) {
						fReverseMap.remove(position);
					}
				}
			}
			super.removeAnnotation(annotation, fireModelChanged);
		}
	}

	/**
	 * Annotation model dealing with java marker annotations and temporary problems.
	 * Also acts as problem requester for its compilation unit. Initially inactive.
	 * Must explicitly be activated.
	 */
	protected static class ExternalSourceModuleAnnotationModel extends SourceModuleAnnotationModel {
		private final IPath location;

		public ExternalSourceModuleAnnotationModel(IPath location) {
			super(ResourcesPlugin.getWorkspace().getRoot());
			this.location = location;
		}

		/*
		 * @see AbstractMarkerAnnotationModel#retrieveMarkers()
		 */
		@Override
		protected IMarker[] retrieveMarkers() throws CoreException {
			String moduleLocation = location.toPortableString();
			IMarker[] markers = super.retrieveMarkers();
			List<IMarker> locationMarkers = new LinkedList<>();
			for (int i = 0; i < markers.length; i++) {
				IMarker marker = markers[i];
				String markerLocation = (String) marker.getAttribute(IMarker.LOCATION);
				if (moduleLocation.equals(markerLocation)) {
					locationMarkers.add(marker);
				}
			}
			return locationMarkers.toArray(new IMarker[locationMarkers.size()]);
		}

		/**
		 * Updates this model to the given marker deltas.
		 *
		 * @param markerDeltas the array of marker deltas
		 */
		@Override
		protected void update(IMarkerDelta[] markerDeltas) {

			if (markerDeltas.length == 0)
				return;

			String moduleLocation = location.toPortableString();

			for (int i = 0; i < markerDeltas.length; i++) {
				IMarkerDelta delta = markerDeltas[i];
				IMarker marker = delta.getMarker();

				if (moduleLocation.equals(marker.getAttribute(IMarker.LOCATION, moduleLocation))) {
					switch (delta.getKind()) {
					case IResourceDelta.ADDED:
						addMarkerAnnotation(marker);
						break;
					case IResourceDelta.REMOVED:
						removeMarkerAnnotation(marker);
						break;
					case IResourceDelta.CHANGED:
						modifyMarkerAnnotation(marker);
						break;
					}
				}
			}

			fireModelChanged();
		}
	}

	protected static class GlobalAnnotationModelListener
			implements IAnnotationModelListener, IAnnotationModelListenerExtension {

		private ListenerList<IAnnotationModelListener> fListenerList;

		public GlobalAnnotationModelListener() {
			fListenerList = new ListenerList<>(ListenerList.IDENTITY);
		}

		/**
		 * @see IAnnotationModelListener#modelChanged(IAnnotationModel)
		 */
		@Override
		public void modelChanged(IAnnotationModel model) {
			for (IAnnotationModelListener listener : fListenerList) {
				listener.modelChanged(model);
			}
		}

		/**
		 * @see IAnnotationModelListenerExtension#modelChanged(AnnotationModelEvent)
		 */
		@Override
		public void modelChanged(AnnotationModelEvent event) {
			for (IAnnotationModelListener curr : fListenerList) {
				if (curr instanceof IAnnotationModelListenerExtension) {
					((IAnnotationModelListenerExtension) curr).modelChanged(event);
				}
			}
		}

		public void addListener(IAnnotationModelListener listener) {
			fListenerList.add(listener);
		}

		public void removeListener(IAnnotationModelListener listener) {
			fListenerList.remove(listener);
		}
	}

	/**
	 * Element information of all connected elements with a fake CU but no file
	 * info.
	 *
	 *
	 */
	private final Map<Object, SourceModuleInfo> fFakeCUMapForMissingInfo = new HashMap<>();

	public SourceModuleDocumentProvider() {

		IDocumentProvider provider = new TextFileDocumentProvider();
		provider = new SourceForwardingDocumentProvider(provider);
		setParentDocumentProvider(provider);

		fGlobalAnnotationModelListener = new GlobalAnnotationModelListener();
		fPropertyListener = event -> {
			if (HANDLE_TEMPORARY_PROBLEMS.equals(event.getProperty()))
				enableHandlingTemporaryProblems();
		};
		DLTKUIPlugin.getDefault().getPreferenceStore().addPropertyChangeListener(fPropertyListener);
	}

	/**
	 * Bundle of all required informations to allow working copy management.
	 */
	static protected class SourceModuleInfo extends FileInfo {

		public SourceModuleInfo() {
		}

		public ISourceModule fCopy;

		public IProblemRequestor getProblemRequestor() {
			return fModel instanceof IProblemRequestor ? (IProblemRequestor) fModel : null;
		}
	}

	@Override
	public void shutdown() {
		DLTKUIPlugin.getDefault().getPreferenceStore().removePropertyChangeListener(fPropertyListener);

		Iterator<?> e = getConnectedElementsIterator();
		while (e.hasNext()) {
			disconnect(e.next());
		}
	}

	@Override
	public ISourceModule getWorkingCopy(Object element) {
		FileInfo fileInfo = getFileInfo(element);
		if (fileInfo instanceof SourceModuleInfo) {
			SourceModuleInfo info = (SourceModuleInfo) fileInfo;
			return info.fCopy;
		}
		SourceModuleInfo cuInfo = fFakeCUMapForMissingInfo.get(element);
		if (cuInfo != null)
			return cuInfo.fCopy;

		return null;
	}

	@Override
	public void saveDocumentContent(IProgressMonitor monitor, Object element, IDocument document, boolean overwrite)
			throws CoreException {

		if (!fIsAboutToSave) {
			return;
		}
		super.saveDocument(monitor, element, document, overwrite);
	}

	@Override
	public ILineTracker createLineTracker(Object element) {
		return new DefaultLineTracker();
	}

	/**
	 * Returns the preference whether handling temporary problems is enabled.
	 */
	protected boolean isHandlingTemporaryProblems() {
		IPreferenceStore store = DLTKUIPlugin.getDefault().getPreferenceStore();
		return store.getBoolean(HANDLE_TEMPORARY_PROBLEMS);
	}

	/**
	 * Switches the state of problem acceptance according to the value in the
	 * preference store.
	 */
	protected void enableHandlingTemporaryProblems() {
		boolean enable = isHandlingTemporaryProblems();
		for (Iterator<FileInfo> iter = getFileInfosIterator(); iter.hasNext();) {
			FileInfo info = iter.next();
			if (info.fModel instanceof IProblemRequestorExtension) {
				IProblemRequestorExtension extension = (IProblemRequestorExtension) info.fModel;
				extension.setIsHandlingTemporaryProblems(enable);
			}
		}
	}

	@Override
	public void setSavePolicy(ISavePolicy savePolicy) {
		fSavePolicy = savePolicy;
	}

	@Override
	public void addGlobalAnnotationModelListener(IAnnotationModelListener listener) {
		fGlobalAnnotationModelListener.addListener(listener);
	}

	@Override
	public void removeGlobalAnnotationModelListener(IAnnotationModelListener listener) {
		fGlobalAnnotationModelListener.removeListener(listener);
	}

	/**
	 * Creates a source module from the given file.
	 *
	 * @param file the file from which to create the source module
	 */
	protected ISourceModule createSourceModule(IFile file) {

		Object element = DLTKCore.create(file);
		if (element instanceof ISourceModule) {
			return (ISourceModule) element;
		}
		return null;
	}

	@Override
	protected FileInfo createEmptyFileInfo() {

		return new SourceModuleInfo();
	}

	private void setUpSynchronization(SourceModuleInfo cuInfo) {

		IDocument document = cuInfo.fTextFileBuffer.getDocument();
		IAnnotationModel model = cuInfo.fModel;

		if (document instanceof ISynchronizable && model instanceof ISynchronizable) {
			Object lock = ((ISynchronizable) document).getLockObject();
			((ISynchronizable) model).setLockObject(lock);
		}
	}

	@Override
	protected IAnnotationModel createAnnotationModel(IFile file) {
		return new SourceModuleAnnotationModel(file);
	}

	static class DelegatingRequestor implements IProblemRequestor {

		IProblemRequestor fRequestor;

		@Override
		public void acceptProblem(IProblem problem) {
			if (fRequestor != null)
				fRequestor.acceptProblem(problem);
		}

		@Override
		public void beginReporting() {
			if (fRequestor != null)
				fRequestor.beginReporting();
		}

		@Override
		public void endReporting() {
			if (fRequestor != null)
				fRequestor.endReporting();
		}

		@Override
		public boolean isActive() {
			return fRequestor != null && fRequestor.isActive();
		}

	}

	@Override
	protected FileInfo createFileInfo(Object element) throws CoreException {

		ISourceModule original = null;

		if (element instanceof IFileEditorInput) {
			IFileEditorInput input = (IFileEditorInput) element;
			original = createSourceModule(input.getFile());
		}
		if (original == null && element instanceof IAdaptable) {
			IModelElement modelE = ((IAdaptable) element).getAdapter(IModelElement.class);
			if (modelE != null && modelE instanceof ISourceModule) {
				original = (ISourceModule) modelE;
			}
		}

		FileInfo info = super.createFileInfo(element);

		if (!(info instanceof SourceModuleInfo))
			return null;

		DelegatingRequestor delegatingRequestor = null;
		if (original == null) {
			original = createFakeSourceModule(element, false, delegatingRequestor = new DelegatingRequestor());
		}
		if (original == null)
			return null;

		if (info.fModel == null) {
			// There is no resource for this ISourceModule, so markers are set
			// to workspace root

			IPath location = original.getPath();
			info.fModel = new ExternalSourceModuleAnnotationModel(location);
		}

		SourceModuleInfo cuInfo = (SourceModuleInfo) info;
		setUpSynchronization(cuInfo);

		final IProblemRequestor requestor = cuInfo.getProblemRequestor();
		if (delegatingRequestor != null) {
			delegatingRequestor.fRequestor = requestor;
		}
		if (requestor instanceof IProblemRequestorExtension) {
			IProblemRequestorExtension extension = (IProblemRequestorExtension) requestor;
			extension.setIsActive(false);
			extension.setIsHandlingTemporaryProblems(isHandlingTemporaryProblems());
		}

		if (ScriptModelUtil.isPrimary(original))
			original.becomeWorkingCopy(requestor, getProgressMonitor());
		cuInfo.fCopy = original;

		if (cuInfo.fModel instanceof SourceModuleAnnotationModel) {
			SourceModuleAnnotationModel model = (SourceModuleAnnotationModel) cuInfo.fModel;
			model.setSourceModule(cuInfo.fCopy);
		}

		if (cuInfo.fModel != null) {
			cuInfo.fModel.addAnnotationModelListener(fGlobalAnnotationModelListener);
		}

		return cuInfo;
	}

	@Override
	protected void disposeFileInfo(Object element, FileInfo info) {

		if (info instanceof SourceModuleInfo) {
			SourceModuleInfo cuInfo = (SourceModuleInfo) info;

			try {
				cuInfo.fCopy.discardWorkingCopy();
			} catch (ModelException x) {
				handleCoreException(x, x.getMessage());
			}

			// if( cuInfo.fModel != null )
			// cuInfo.fModel.removeAnnotationModelListener(
			// fGlobalAnnotationModelListener );
		}
		super.disposeFileInfo(element, info);
	}

	/**
	 * Creates and returns a new sub-progress monitor for the given parent monitor.
	 *
	 * @param monitor the parent progress monitor
	 * @param ticks   the number of work ticks allocated from the parent monitor
	 * @return the new sub-progress monitor
	 */
	private IProgressMonitor getSubProgressMonitor(IProgressMonitor monitor, int ticks) {

		if (monitor != null)
			return new SubProgressMonitor(monitor, ticks, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK);

		return new NullProgressMonitor();
	}

	@Override
	protected DocumentProviderOperation createSaveOperation(final Object element, final IDocument document,
			final boolean overwrite) throws CoreException {

		final FileInfo info = getFileInfo(element);
		if (info instanceof SourceModuleInfo) {

			// Delegate handling of non-primary SourceModules
			ISourceModule cu = ((SourceModuleInfo) info).fCopy;
			// condition should be the same as for becomeWorkingCopy() above
			if (cu != null && !ScriptModelUtil.isPrimary(cu))
				return super.createSaveOperation(element, document, overwrite);

			if (info.fTextFileBuffer.getDocument() != document) {
				// the info exists, but not for the given document
				// -> saveAs was executed with a target that is already open
				// in another editor
				// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=85519
				System.out.println("SourceModuleDocumentProvider: need to replace with messages api"); //$NON-NLS-1$
				Status status = new Status(IStatus.WARNING, EditorsUI.PLUGIN_ID, IStatus.ERROR,
						Messages.SourceModuleDocumentProvider_saveAsTargetOpenInEditor, null);
				throw new CoreException(status);
			}

			return new DocumentProviderOperation() {
				@Override
				protected void execute(IProgressMonitor monitor) throws CoreException {

					commitWorkingCopy(monitor, element, (SourceModuleInfo) info, overwrite);
				}

				@Override
				public ISchedulingRule getSchedulingRule() {

					if (info.fElement instanceof IFileEditorInput) {
						IFile file = ((IFileEditorInput) info.fElement).getFile();
						return computeSchedulingRule(file);
					}
					return null;
				}
			};
		}
		return null;
	}

	protected void commitWorkingCopy(IProgressMonitor monitor, Object element, final SourceModuleInfo info,
			boolean overwrite) throws CoreException {

		if (monitor == null)
			monitor = new NullProgressMonitor();

		monitor.beginTask("", 100); //$NON-NLS-1$

		try {

			IDocument document = info.fTextFileBuffer.getDocument();
			boolean isSynchronized = true;

			IResource resource = info.fCopy.getResource();
			if (resource != null) {

				Assert.isTrue(resource instanceof IFile);

				isSynchronized = resource.isSynchronized(IResource.DEPTH_ZERO);
				/*
				 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=98327 Make sure file gets save
				 * in commit() if the underlying file has been deleted
				 */
				if (!isSynchronized && isDeleted(element))
					info.fTextFileBuffer.setDirty(true);

				if (!resource.exists()) {
					// underlying resource has been deleted, just recreate
					// file,
					// ignore the rest
					createFileFromDocument(monitor, (IFile) resource, document);
					return;
				}

			}

			if (fSavePolicy != null)
				fSavePolicy.preSave(info.fCopy);

			IProgressMonitor subMonitor = null;
			try {
				fIsAboutToSave = true;

				IPostSaveListener[] listeners = DLTKUIPlugin.getDefault().getSaveParticipantRegistry()
						.getEnabledPostSaveListeners(info.fCopy);

				CoreException changedRegionException = null;
				boolean needsChangedRegions = false;
				try {
					if (listeners.length > 0)
						needsChangedRegions = SaveParticipantRegistry.isChangedRegionsRequired(info.fCopy, listeners);
				} catch (CoreException ex) {
					changedRegionException = ex;
				}

				IRegion[] changedRegions = null;
				if (needsChangedRegions) {
					try {
						changedRegions = EditorUtility.calculateChangedLineRegions(info.fTextFileBuffer,
								getSubProgressMonitor(monitor, 20));
					} catch (CoreException ex) {
						changedRegionException = ex;
					} finally {
						subMonitor = getSubProgressMonitor(monitor, 50);
					}
				} else
					subMonitor = getSubProgressMonitor(monitor, listeners.length > 0 ? 70 : 100);

				info.fCopy.commitWorkingCopy(isSynchronized || overwrite, subMonitor);
				if (listeners.length > 0)
					notifyPostSaveListeners(info, changedRegions, listeners, getSubProgressMonitor(monitor, 30));

				if (changedRegionException != null) {
					throw changedRegionException;
				}

				info.fCopy.commitWorkingCopy(isSynchronized || overwrite, subMonitor);
			} catch (CoreException x) {
				// inform about the failure
				fireElementStateChangeFailed(element);
				throw x;
			} catch (RuntimeException x) {
				// inform about the failure
				fireElementStateChangeFailed(element);
				throw x;
			} finally {
				fIsAboutToSave = false;
				if (subMonitor != null)
					subMonitor.done();
			}

			// If here, the dirty state of the editor will change to "not
			// dirty".
			// Thus, the state changing flag will be reset.
			if (info.fModel instanceof AbstractMarkerAnnotationModel) {
				AbstractMarkerAnnotationModel model = (AbstractMarkerAnnotationModel) info.fModel;
				model.updateMarkers(document);
			}

			if (fSavePolicy != null) {
				ISourceModule unit = fSavePolicy.postSave(info.fCopy);
				if (unit != null && info.fModel instanceof AbstractMarkerAnnotationModel) {
					IResource r = unit.getResource();
					if (r != null) {
						IMarker[] markers = r.findMarkers(IMarker.MARKER, true, IResource.DEPTH_ZERO);
						if (markers != null && markers.length > 0) {
							AbstractMarkerAnnotationModel model = (AbstractMarkerAnnotationModel) info.fModel;
							for (int i = 0; i < markers.length; i++)
								model.updateMarker(document, markers[i], null);
						}
					}
				}
			}
		} finally {
			monitor.done();
		}
	}

	@Override
	public void connect(Object element) throws CoreException {
		super.connect(element);
		if (getFileInfo(element) != null)
			return;

		SourceModuleInfo info = fFakeCUMapForMissingInfo.get(element);
		if (info == null) {
			ISourceModule cu = null;
			if (element instanceof IAdaptable) {
				IModelElement e = ((IAdaptable) element).getAdapter(IModelElement.class);
				if (e != null && e instanceof ISourceModule) {
					cu = (ISourceModule) e;
				}
			}
			DelegatingRequestor delegatingRequestor = null;
			if (cu == null) {
				cu = createFakeSourceModule(element, true, delegatingRequestor = new DelegatingRequestor());
			}
			if (cu == null)
				return;
			info = new SourceModuleInfo();
			info.fCopy = cu;
			info.fElement = element;
			info.fModel = createAnnotationModel(element);
			if (delegatingRequestor != null) {
				delegatingRequestor.fRequestor = info.getProblemRequestor();
			}
			fFakeCUMapForMissingInfo.put(element, info);
		}
		info.fCount++;
	}

	private IAnnotationModel createAnnotationModel(Object element) {
		if (element instanceof ExternalStorageEditorInput) {
			final IModelElement modelElement = ((ExternalStorageEditorInput) element).getAdapter(IModelElement.class);
			if (modelElement != null) {
				final IPath path = modelElement.getPath();
				if (path != null) {
					return new ExternalSourceModuleAnnotationModel(path);
				}
			}
		}
		return new AnnotationModel();
	}

	/*
	 * @see org.eclipse.ui.editors.text.TextFileDocumentProvider#getAnnotationModel
	 * (java.lang.Object)
	 */
	@Override
	public IAnnotationModel getAnnotationModel(Object element) {
		IAnnotationModel model = super.getAnnotationModel(element);
		if (model != null)
			return model;

		FileInfo info = fFakeCUMapForMissingInfo.get(element);
		if (info != null) {
			if (info.fModel != null)
				return info.fModel;
			if (info.fTextFileBuffer != null)
				return info.fTextFileBuffer.getAnnotationModel();
		}

		return null;
	}

	@Override
	public void disconnect(Object element) {
		SourceModuleInfo info = fFakeCUMapForMissingInfo.get(element);
		if (info != null) {
			if (info.fCount == 1) {
				fFakeCUMapForMissingInfo.remove(element);
				info.fModel = null;
				// Destroy and unregister fake working copy
				try {
					info.fCopy.discardWorkingCopy();
				} catch (ModelException ex) {
					handleCoreException(ex, ex.getMessage());
				}
			} else
				info.fCount--;
		}
		super.disconnect(element);
	}

	/**
	 * Creates a fake compilation unit.
	 *
	 * @param element     the element
	 * @param setContents tells whether to read and set the contents to the new CU
	 *
	 */
	private ISourceModule createFakeSourceModule(Object element, boolean setContents, IProblemRequestor requestor) {
		if (element instanceof IStorageEditorInput)
			return createFakeSourceModule((IStorageEditorInput) element, setContents, requestor);
		else if (element instanceof IURIEditorInput)
			return createFakeSourceModule((IURIEditorInput) element, requestor);
		else if (element instanceof NonExistingFileEditorInput)
			return createFakeSourceModule((NonExistingFileEditorInput) element, requestor);
		return null;
	}

	private ISourceModule createFakeSourceModule(NonExistingFileEditorInput editorInput, IProblemRequestor requestor) {
		try {
			final IPath path = editorInput.getPath(editorInput);
			URI uri = URIUtil.toURI(path);
			final IFileStore fileStore = EFS.getStore(uri);

			if (fileStore.getName() == null || path == null)
				return null;

			WorkingCopyOwner woc = new WorkingCopyOwner() {
				/*
				 * @see org.eclipse.jdt.core.WorkingCopyOwner#createBuffer(org. eclipse
				 * .jdt.core.ICompilationUnit)
				 *
				 * @since 3.2
				 */
				@Override
				public IBuffer createBuffer(ISourceModule workingCopy) {
					return new DocumentAdapter(workingCopy, fileStore, path);
				}
			};

			IBuildpathEntry[] cpEntries = null;
			IScriptProject jp = findScriptProject(path);
			if (jp != null)
				cpEntries = jp.getResolvedBuildpath(true);

			if (cpEntries == null || cpEntries.length == 0)
				cpEntries = new IBuildpathEntry[] { ScriptRuntime.getDefaultInterpreterContainerEntry() };

			final ISourceModule cu = woc.newWorkingCopy(fileStore.getName(), cpEntries, requestor,
					getProgressMonitor());

			if (!isModifiable(editorInput))
				ScriptModelUtil.reconcile(cu);

			return cu;
		} catch (CoreException ex) {
			return null;
		}
	}

	private ISourceModule createFakeSourceModule(final IURIEditorInput editorInput, IProblemRequestor requestor) {
		try {
			final URI uri = editorInput.getURI();
			final IFileStore fileStore = EFS.getStore(uri);
			final IPath path = URIUtil.toPath(uri);
			final String fileStoreName = fileStore.getName();
			if (fileStoreName == null || path == null)
				return null;

			WorkingCopyOwner woc = new WorkingCopyOwner() {
				/*
				 * @see org.eclipse.jdt.core.WorkingCopyOwner#createBuffer(org. eclipse
				 * .jdt.core.ICompilationUnit)
				 *
				 * @since 3.2
				 */
				@Override
				public IBuffer createBuffer(ISourceModule workingCopy) {
					return new DocumentAdapter(workingCopy, fileStore, path);
				}
			};

			IBuildpathEntry[] cpEntries = null;
			IScriptProject jp = findScriptProject(path);
			if (jp != null)
				cpEntries = jp.getResolvedBuildpath(true);

			if (cpEntries == null || cpEntries.length == 0)
				cpEntries = new IBuildpathEntry[] { ScriptRuntime.getDefaultInterpreterContainerEntry() };

			final ISourceModule cu = woc.newWorkingCopy(fileStoreName, cpEntries, requestor, getProgressMonitor());

			if (!isModifiable(editorInput))
				ScriptModelUtil.reconcile(cu);

			return cu;
		} catch (CoreException ex) {
			return null;
		}
	}

	private ISourceModule createFakeSourceModule(final IStorageEditorInput sei, boolean setContents,
			IProblemRequestor requestor) {
		try {
			final IStorage storage = sei.getStorage();
			final IPath storagePath = storage.getFullPath();
			if (storage.getName() == null || storagePath == null)
				return null;

			// final IPath documentPath;
			// if (storage instanceof IFileState)
			// documentPath = storagePath
			// .append(Long.toString(((IFileState) storage)
			// .getModificationTime()));
			// else
			// documentPath = storagePath;

			WorkingCopyOwner woc = new WorkingCopyOwner() {
				@Override
				public IBuffer createBuffer(ISourceModule workingCopy) {
					return BufferManager.createBuffer(workingCopy);
				}
			};

			IBuildpathEntry[] cpEntries = null;
			IScriptProject jp = findScriptProject(storagePath);
			if (jp != null)
				cpEntries = jp.getResolvedBuildpath(true);

			if (cpEntries == null || cpEntries.length == 0)
				cpEntries = new IBuildpathEntry[] { ScriptRuntime.getDefaultInterpreterContainerEntry() };

			final ISourceModule cu = woc.newWorkingCopy(storage.getName(), cpEntries, requestor, getProgressMonitor());
			if (setContents) {
				int READER_CHUNK_SIZE = 2048;
				int BUFFER_SIZE = 8 * READER_CHUNK_SIZE;
				Reader in = new BufferedReader(new InputStreamReader(storage.getContents()));
				StringBuilder buffer = new StringBuilder(BUFFER_SIZE);
				char[] readBuffer = new char[READER_CHUNK_SIZE];
				int n;
				try {
					n = in.read(readBuffer);
					while (n > 0) {
						buffer.append(readBuffer, 0, n);
						n = in.read(readBuffer);
					}
					in.close();
				} catch (IOException e) {
					DLTKUIPlugin.log(e);
				}
				cu.getBuffer().setContents(buffer.toString());
			}

			if (!isModifiable(sei))
				ScriptModelUtil.reconcile(cu);

			return cu;
		} catch (CoreException ex) {
			return null;
		}
	}

	/**
	 * Fuzzy search for script project in the workspace that matches the given path.
	 *
	 * @param path the path to match
	 * @return the matching script project or <code>null</code>
	 *
	 */
	private IScriptProject findScriptProject(IPath path) {
		if (path == null)
			return null;

		String[] pathSegments = path.segments();
		IScriptModel model = DLTKCore.create(DLTKUIPlugin.getWorkspace().getRoot());
		IScriptProject[] projects;
		try {
			projects = model.getScriptProjects();
		} catch (ModelException e) {
			return null; // ignore - use default RE
		}
		for (int i = 0; i < projects.length; i++) {
			IPath projectPath = projects[i].getProject().getFullPath();
			String projectSegment = projectPath.segments()[0];
			for (int j = 0; j < pathSegments.length; j++)
				if (projectSegment.equals(pathSegments[j]))
					return projects[i];
		}
		return null;
	}

	@Override
	public boolean isReadOnly(Object element) {
		if (element instanceof ExternalStorageEditorInput) {
			return true;
		}
		if (element instanceof FileStoreEditorInput) {
			ISourceModule module = DLTKUIPlugin.resolveSourceModule((FileStoreEditorInput) element);
			if (module != null) {
				return module.isReadOnly();
			}
		}
		return super.isReadOnly(element);
	}

	/**
	 * Notify post save listeners.
	 * <p>
	 * <strong>Note:</strong> Post save listeners are not allowed to save the file
	 * and they must not assumed to be called in the UI thread i.e. if they open a
	 * dialog they must ensure it ends up in the UI thread.
	 * </p>
	 *
	 * @param info           compilation unit info
	 * @param changedRegions the array with the changed regions
	 * @param listeners      the listeners to notify
	 * @param monitor        the progress monitor
	 * @throws CoreException if something goes wrong
	 * @see IPostSaveListener
	 * @since 3.0
	 */
	protected void notifyPostSaveListeners(final SourceModuleInfo info, final IRegion[] changedRegions,
			IPostSaveListener[] listeners, final IProgressMonitor monitor) throws CoreException {
		final ISourceModule unit = info.fCopy;
		final IBuffer buffer = unit.getBuffer();

		String message = DLTKEditorMessages.CompilationUnitDocumentProvider_error_saveParticipantProblem;
		final MultiStatus errorStatus = new MultiStatus(DLTKUIPlugin.PLUGIN_ID,
				IDLTKStatusConstants.EDITOR_POST_SAVE_NOTIFICATION, message, null);

		monitor.beginTask(DLTKEditorMessages.CompilationUnitDocumentProvider_progressNotifyingSaveParticipants,
				listeners.length * 5);
		try {
			for (int i = 0; i < listeners.length; i++) {
				final IPostSaveListener listener = listeners[i];
				final String participantName = listener.getName();
				SafeRunner.run(new ISafeRunnable() {
					@Override
					public void run() {
						try {
							long stamp = unit.getResource().getModificationStamp();

							listener.saved(unit, changedRegions, getSubProgressMonitor(monitor, 4));

							if (stamp != unit.getResource().getModificationStamp()) {
								String msg = NLS.bind(
										DLTKEditorMessages.CompilationUnitDocumentProvider_error_saveParticipantSavedFile,
										participantName);
								errorStatus.add(new Status(IStatus.ERROR, DLTKUIPlugin.PLUGIN_ID,
										IDLTKStatusConstants.EDITOR_POST_SAVE_NOTIFICATION, msg, null));
							}

							if (buffer.hasUnsavedChanges())
								buffer.save(getSubProgressMonitor(monitor, 1), true);

						} catch (CoreException ex) {
							handleException(ex);
						} finally {
							monitor.worked(1);
						}
					}

					@Override
					public void handleException(Throwable ex) {
						String msg = NLS.bind("The save participant ''{0}'' caused an exception: {1}", //$NON-NLS-1$
								listener.getId(), ex.toString());
						DLTKUIPlugin.log(new Status(IStatus.ERROR, DLTKUIPlugin.PLUGIN_ID,
								IDLTKStatusConstants.EDITOR_POST_SAVE_NOTIFICATION, msg, ex));

						msg = NLS.bind(DLTKEditorMessages.CompilationUnitDocumentProvider_error_saveParticipantFailed,
								participantName, ex.toString());
						errorStatus.add(new Status(IStatus.ERROR, DLTKUIPlugin.PLUGIN_ID,
								IDLTKStatusConstants.EDITOR_POST_SAVE_NOTIFICATION, msg, null));

						// Revert the changes
						if (buffer.hasUnsavedChanges()) {
							try {
								info.fTextFileBuffer.revert(getSubProgressMonitor(monitor, 1));
							} catch (CoreException e) {
								msg = NLS.bind("Error on revert after failure of save participant ''{0}''.", //$NON-NLS-1$
										participantName);
								IStatus status = new Status(IStatus.ERROR, DLTKUIPlugin.PLUGIN_ID,
										IDLTKStatusConstants.EDITOR_POST_SAVE_NOTIFICATION, msg, ex);
								DLTKUIPlugin.getDefault().getLog().log(status);
							}

							if (info.fModel instanceof AbstractMarkerAnnotationModel) {
								AbstractMarkerAnnotationModel markerModel = (AbstractMarkerAnnotationModel) info.fModel;
								markerModel.resetMarkers();
							}
						}

						// XXX: Work in progress 'Save As' case
						// else if (buffer.hasUnsavedChanges()) {
						// try {
						// buffer.save(getSubProgressMonitor(monitor, 1), true);
						// } catch (JavaModelException e) {
						// message= Messages.format("Error reverting changes
						// after failure of save participant ''{0}''.",
						// participantName); //$NON-NLS-1$
						// IStatus status= new Status(IStatus.ERROR,
						// JavaUI.ID_PLUGIN, IStatus.OK, message, ex);
						// JavaPlugin.getDefault().getLog().log(status);
						// }
						// }
					}
				});
			}
		} finally {
			monitor.done();
			if (!errorStatus.isOK())
				throw new CoreException(errorStatus);
		}
	}
}
