/*******************************************************************************
 * Copyright (c) 2005, 2017 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
 *
 *******************************************************************************/
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;
			else
				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);
			} else {
				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);

			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) {
			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);
				}

				/*
				 * @see org.eclipse.ui.editors.text.TextFileDocumentProvider.
				 * DocumentProviderOperation#getSchedulingRule()
				 */
				@Override
				public ISchedulingRule getSchedulingRule() {

					if (info.fElement instanceof IFileEditorInput) {
						IFile file = ((IFileEditorInput) info.fElement)
								.getFile();
						return computeSchedulingRule(file);
					} else
						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()));
				StringBuffer buffer = new StringBuffer(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);
		}
	}
}
