/*******************************************************************************
 * Copyright (c) 2001, 2004 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Jens Lukowski/Innoopract - initial renaming/restructuring
 *     
 *******************************************************************************/
package org.eclipse.wst.sse.ui;

import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.nio.charset.UnsupportedCharsetException;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Vector;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.source.IAnnotationModel;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.IStorageEditorInput;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.dialogs.ContainerGenerator;
import org.eclipse.ui.editors.text.FileDocumentProvider;
import org.eclipse.ui.texteditor.AbstractMarkerAnnotationModel;
import org.eclipse.wst.common.encoding.CodedReaderCreator;
import org.eclipse.wst.common.encoding.EncodingMemento;
import org.eclipse.wst.common.encoding.EncodingRule;
import org.eclipse.wst.common.encoding.exceptions.CharConversionErrorWithDetail;
import org.eclipse.wst.common.encoding.exceptions.MalformedInputExceptionWithDetail;
import org.eclipse.wst.common.encoding.exceptions.MalformedOutputExceptionWithDetail;
import org.eclipse.wst.common.encoding.exceptions.UnsupportedCharsetExceptionWithDetail;
import org.eclipse.wst.sse.core.IFactoryRegistry;
import org.eclipse.wst.sse.core.IModelLifecycleListener;
import org.eclipse.wst.sse.core.IModelManager;
import org.eclipse.wst.sse.core.IModelStateListenerExtended;
import org.eclipse.wst.sse.core.IStructuredModel;
import org.eclipse.wst.sse.core.ModelLifecycleEvent;
import org.eclipse.wst.sse.core.StructuredModelManager;
import org.eclipse.wst.sse.core.exceptions.SourceEditingRuntimeException;
import org.eclipse.wst.sse.core.text.IStructuredDocument;
import org.eclipse.wst.sse.core.undo.IStructuredTextUndoManager;
import org.eclipse.wst.sse.ui.internal.Logger;
import org.eclipse.wst.sse.ui.internal.SSEUIPlugin;
import org.eclipse.wst.sse.ui.registry.AdapterFactoryProvider;
import org.eclipse.wst.sse.ui.registry.AdapterFactoryRegistry;
import org.eclipse.wst.sse.ui.registry.AdapterFactoryRegistryImpl;
import org.eclipse.wst.sse.ui.util.Assert;

/**
 * This version of an IDocumentProvider is the editor side counter part to
 * IModelManager. It is responsible for providing the structuredModel, which
 * is actually deferred to the IModelManager. But other, non-deffered
 * responsibilities include providing editing related models, such as
 * annotation models, undo command stack, etc.
 * 
 * @deprecated - no longer used
 */
public class FileModelProvider extends FileDocumentProvider implements IModelProvider {

	// Ensure that the ElementInfo metadata is correct for the model
	protected class InternalModelStateListener implements IModelStateListenerExtended {
		public void modelAboutToBeChanged(IStructuredModel model) {
			if (debugModelStatelistener) {
				System.out.println("FileModelProvider: modelAboutToBeChanged: " + model.getId());
			}
		}

		public void modelAboutToBeReinitialized(IStructuredModel model) {
			if (debugModelStatelistener) {
				System.out.println("FileModelProvider: modelAboutToBeReinitialized: " + model.getId());
			}
		}

		public void modelChanged(IStructuredModel model) {
			if (debugModelStatelistener) {
				System.out.println("FileModelProvider: modelChanged: " + model.getId());
			}
		}

		public void modelDirtyStateChanged(IStructuredModel model, boolean isDirty) {
			if (debugModelStatelistener) {
				System.out.println("FileModelProvider: modelDirtyStateChanged:(" + isDirty + ") " + model.getId());
			}
			// synchronize the saveability with the dirty flag
			IFileEditorInput editorInput = (IFileEditorInput) getInputFor(model);
			if (editorInput != null) {
				FileInfo info = (FileInfo) getElementInfo(editorInput);
				if (info != null) {
					info.fCanBeSaved = isDirty;
					if (!isDirty) {
						addUnchangedElementListeners(editorInput, info);
						// This timestamp udpate is required until
						// ModelLifecycleEvent.MODEL_SAVED are received in the
						// ModelInfo
						info.fModificationStamp = computeModificationStamp(editorInput.getFile());
					}
					fireElementDirtyStateChanged(editorInput, isDirty);
				} else {
					throw new SourceEditingRuntimeException(new IllegalArgumentException("no corresponding element info found for " + model.getId()), "leftover model state listener in FileModelProvider"); //$NON-NLS-2$ //$NON-NLS-1$
				}
			}
			fireModelDirtyStateChanged(model, isDirty);
		}

		public void modelReinitialized(IStructuredModel model) {
			if (debugModelStatelistener) {
				System.out.println("FileModelProvider: modelReinitialized " + model.getId());
			}
			reinitializeFactories(model);
		}

		public void modelResourceDeleted(IStructuredModel model) {
			if (debugModelStatelistener) {
				System.out.println("FileModelProvider: modelResourceDeleted " + model.getId());
			}
			fireModelDeleted(model);
		}

		public void modelResourceMoved(IStructuredModel originalmodel, IStructuredModel movedmodel) {
			if (debugModelStatelistener) {
				System.out.println("FileModelProvider: modelResourceMoved " + originalmodel.getBaseLocation() + " --> " + movedmodel.getBaseLocation());
			}
			fireModelMoved(originalmodel, movedmodel);
		}
	}

	/**
	 * Collection of info that goes with a model. Implements
	 * IModelLifecycleListener so that there's a separate instance per
	 * IEditorInput
	 */
	protected class ModelInfo implements IModelLifecycleListener {
		public IEditorInput fElement;
		public FileSynchronizer fFileSynchronizer;
		public boolean fShouldReleaseOnInfoDispose;
		public IStructuredModel fStructuredModel;

		public ModelInfo(IStructuredModel structuredModel, IEditorInput element, boolean selfCreated) {
			fElement = element;
			fStructuredModel = structuredModel;
			fShouldReleaseOnInfoDispose = selfCreated;
			fFileSynchronizer = createModelSynchronizer(element, structuredModel);
		}

		public void processPostModelEvent(ModelLifecycleEvent event) {
			if (debugLifecyclelistener) {
				System.out.println("FileModelProvider: " + event.getModel().getId() + " " + event.toString());
			}
			if (event.getType() == ModelLifecycleEvent.MODEL_SAVED) {
				// update the recorded timestamps in the ElementInfo
				FileInfo info = (FileInfo) getElementInfo(fElement);
				if (info != null) {
					info.fModificationStamp = computeModificationStamp(((IFileEditorInput) fElement).getFile());
				} else {
					throw new SourceEditingRuntimeException(new IllegalArgumentException("no corresponding element info found for " + event.getModel().getId()), "leftover model lifecycle listener"); //$NON-NLS-2$ //$NON-NLS-1$
				}
			}
		}

		public void processPreModelEvent(ModelLifecycleEvent event) {
			if (debugLifecyclelistener) {
				System.out.println("FileModelProvider: " + event.getModel().getId() + " " + event.toString());
			}
		}
	}

	static final boolean debugLifecyclelistener = "true".equalsIgnoreCase(Platform.getDebugOption("org.eclipse.wst.sse.ui/filemodelprovider/lifecyclelistener"));
	static final boolean debugModelStatelistener = "true".equalsIgnoreCase(Platform.getDebugOption("org.eclipse.wst.sse.ui/filemodelprovider/modelstatelistener"));

	private static final boolean debugOperations = "true".equalsIgnoreCase(Platform.getDebugOption("org.eclipse.wst.sse.ui/filemodelprovider/operations"));

	private static FileModelProvider fInstance = null;
	private static IModelManager fModelManager;

	/** NLS strings */
	//    private static final String UNSUPPORTED_ENCODING_WARNING =
	// ResourceHandler.getString("1This_encoding({0})_is_not__WARN_");
	// //$NON-NLS-1$
	//$NON-NLS-1$ = "This encoding({0}) is not supported. The default encoding will be used instead."
	// CSSFileModelProvider will use this.
	protected static final String UNSUPPORTED_ENCODING_WARNING_TITLE = SSEUIPlugin.getResourceString("%Encoding_warning_UI_"); //$NON-NLS-1$ = "Encoding warning"

	public synchronized static FileModelProvider getInstance() {
		if (fInstance == null)
			fInstance = new FileModelProvider();
		return fInstance;
	}

	/**
	 * Utility method also used in subclasses
	 */
	protected static IModelManager getModelManager() {
		if (fModelManager == null) {
			fModelManager = StructuredModelManager.getModelManager();
		}
		return fModelManager;
	}

	private Shell fActiveShell;

	// workaround for save-as in C4
	private Vector fChangingElements = new Vector(1);

	private InternalModelStateListener fInternalModelStateListener;

	/** IStructuredModel information of all connected elements */
	private Map fModelInfoMap = new HashMap();

	/**
	 * @deprecated - temporary flag to change the behavior of createDocument
	 *             during revert/reset
	 */
	private boolean fReuseModelDocument = true;

	protected FileModelProvider() {
		fInternalModelStateListener = new InternalModelStateListener();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.texteditor.IDocumentProvider#aboutToChange(java.lang.Object)
	 */
	public void aboutToChange(Object element) {

		super.aboutToChange(element);

		// start recording for revert
		IStructuredModel model = getModel(element);
		if (model != null) {
			fChangingElements.add(element);
			IStructuredTextUndoManager undoMgr = model.getUndoManager();
			undoMgr.beginRecording(this, 0, 0);
		}
	}

	/**
	 * Register additional (viewer related) factories Note: this can be called
	 * twice, one for when model first created and loaded to editor. And
	 * possible later, if a model "reinit" takes place.
	 */
	protected void addProviderFactories(IStructuredModel structuredModel) {
		// its an error to call with null argument
		if (structuredModel == null)
			return;

		SSEUIPlugin plugin = ((SSEUIPlugin) Platform.getPlugin(SSEUIPlugin.ID));
		AdapterFactoryRegistry adapterRegistry = plugin.getAdapterFactoryRegistry();
		//Iterator adapterFactoryList =
		// adapterRegistry.getAdapterFactories();
		String contentTypeId = structuredModel.getModelHandler().getAssociatedContentTypeId();

		Iterator adapterFactoryList = ((AdapterFactoryRegistryImpl) adapterRegistry).getAdapterFactories(contentTypeId);
		IFactoryRegistry factoryRegistry = structuredModel.getFactoryRegistry();
		Assert.isNotNull(factoryRegistry, "model in invalid state");
		// And all those appropriate for this particular type of content
		while (adapterFactoryList.hasNext()) {
			try {
				AdapterFactoryProvider provider = (AdapterFactoryProvider) adapterFactoryList.next();
				// (pa) ContentType was already checked above
				// this check is here for backwards compatability
				// for those that still don't specify content type
				if (provider.isFor(structuredModel.getModelHandler())) {
					provider.addAdapterFactories(structuredModel);
				}
			} catch (Exception e) {
				Logger.logException(e);
			}
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.texteditor.IDocumentProvider#changed(java.lang.Object)
	 */
	public void changed(Object element) {

		super.changed(element);

		// end recording for revert
		if (fChangingElements.contains(element)) {
			fChangingElements.remove(element);
			IStructuredTextUndoManager undoMgr = getModel(element).getUndoManager();
			undoMgr.endRecording(this, 0, 0);
		}
	}

	protected IAnnotationModel createAnnotationModel(Object element) throws CoreException {
		if (debugOperations) {
			if (element instanceof IStorageEditorInput)
				System.out.println("FileModelProvider: createAnnotationModel for " + ((IStorageEditorInput) element).getStorage().getFullPath());
			else
				System.out.println("FileModelProvider: createAnnotationModel for " + element);
		}
		IAnnotationModel model = null;
		if (element instanceof IEditorInput) {
			IFile file = (IFile) ((IEditorInput) element).getAdapter(IFile.class);
			model = new StructuredResourceMarkerAnnotationModel(file);
		}
		if (model == null)
			model = super.createAnnotationModel(element);
		return model;
	}

	/**
	 * @see org.eclipse.ui.texteditor.AbstractDocumentProvider#createDocument(java.lang.Object)
	 */
	protected IDocument createDocument(Object element) {
		IDocument document = null;
		if (debugOperations) {
			if (element instanceof IFileEditorInput)
				System.out.println("FileModelProvider: createDocument for " + ((IFileEditorInput) element).getFile().getFullPath());
			else
				System.out.println("FileModelProvider: createDocument for " + element);
		}
		if (element instanceof IEditorInput) {
			// create a new IDocument for the element; should always reflect
			// the contents of the resource
			ModelInfo info = getModelInfoFor((IEditorInput) element);
			if (info == null) {
				throw new SourceEditingRuntimeException(new IllegalArgumentException("no corresponding model info found")); //$NON-NLS-1$
			}
			IStructuredModel model = info.fStructuredModel;
			if (model != null) {
				if (!fReuseModelDocument && element instanceof IFileEditorInput) {
					Reader reader = null;
					IStructuredDocument innerdocument = null;
					try {
						// update document from file contents

						IFile iFile = ((IFileEditorInput) element).getFile();
						CodedReaderCreator codedReaderCreator = new CodedReaderCreator(iFile);
						reader = codedReaderCreator.getCodedReader();

						innerdocument = model.getStructuredDocument();

						int originalLengthToReplace = innerdocument.getLength();

						//TODO_future: we could implement with sequential
						// rewrite, if we don't
						// pickup automatically from FileBuffer support, so
						// not so
						// much has to be pulled into memory (as an extra big
						// string), but
						// we need to carry that API through so that
						// StructuredModel is not
						// notified until done.

						//innerdocument.startSequentialRewrite(true);
						//innerdocument.replaceText(this, 0,
						// innerdocument.getLength(), "");


						StringBuffer stringBuffer = new StringBuffer();
						int bufferSize = 2048;
						char[] buffer = new char[bufferSize];
						int nRead = 0;
						boolean eof = false;
						while (!eof) {
							nRead = reader.read(buffer, 0, bufferSize);
							if (nRead == -1) {
								eof = true;
							} else {
								stringBuffer.append(buffer, 0, nRead);
								//innerdocument.replaceText(this,
								// innerdocument.getLength(), 0, new
								// String(buffer, 0, nRead));
							}
						}
						// ignore read-only settings if reverting whole
						// document
						innerdocument.replaceText(this, 0, originalLengthToReplace, stringBuffer.toString(), true);
						model.setDirtyState(false);

					} catch (CoreException e) {
						Logger.logException(e);
					} catch (IOException e) {
						Logger.logException(e);
					} finally {
						if (reader != null) {
							try {
								reader.close();
							} catch (IOException e1) {
								// would be highly unusual
								Logger.logException(e1);
							}
						}
						//						if (innerdocument != null) {
						//							innerdocument.stopSequentialRewrite();
						//						}
					}

				}
				if (document == null) {
					document = model.getStructuredDocument();
				}
			}
		}
		return document;
	}

	/**
	 * Also create ModelInfo - extra resource synchronization classes should
	 * be stored within the ModelInfo
	 */
	protected ElementInfo createElementInfo(Object element) throws CoreException {
		if (debugOperations) {
			if (element instanceof IFileEditorInput)
				System.out.println("FileModelProvider: createElementInfo for " + ((IFileEditorInput) element).getFile().getFullPath());
			else
				System.out.println("FileModelProvider: createElementInfo for " + element);
		}
		// create the corresponding ModelInfo if necessary
		if (getModelInfoFor((IEditorInput) element) == null) {
			createModelInfo((IEditorInput) element);
		}
		ElementInfo info = super.createElementInfo(element);
		return info;
	}

	/**
	 * NOT API
	 * 
	 * @param input
	 */
	public void createModelInfo(IEditorInput input) {
		if (debugOperations) {
			if (input instanceof IFileEditorInput)
				System.out.println("FileModelProvider: createModelInfo for " + ((IFileEditorInput) input).getFile().getFullPath());
			else
				System.out.println("FileModelProvider: createModelInfo for " + input);
		}
		if (!(input instanceof IFileEditorInput)) {
			throw new SourceEditingRuntimeException(new IllegalArgumentException("This model provider only supports IFileEditorInputs")); //$NON-NLS-1$
		}
		if (getModelInfoFor(input) == null) {
			IStructuredModel structuredModel = selfCreateModel((IFileEditorInput) input);
			createModelInfo(input, structuredModel, true);
		}
	}

	/**
	 * NOT API - setModel(IStructuredModel, IEditorInput) should be used
	 * instead to force IEditorInput to IStructuredModel associations
	 * 
	 * To be used when model is provided to us, ensures that when setInput is
	 * used on this input, the given model will be used.
	 */
	public void createModelInfo(IEditorInput input, IStructuredModel structuredModel, boolean releaseModelOnDisconnect) {
		if (!(input instanceof IFileEditorInput)) {
			throw new SourceEditingRuntimeException(new IllegalArgumentException("This model provider only supports IFileEditorInputs")); //$NON-NLS-1$
		} else if (structuredModel == null) {
			throw new SourceEditingRuntimeException(new IllegalArgumentException("No model loaded for input: " + input.getName())); //$NON-NLS-1$
		}
		// we have to make sure factories are added, whether we created or
		// not.
		if (getModelInfoFor(input) != null)
			return;
		// When a model is moved, it may be in the map for two IEditorInputs
		// for
		// a brief time. Ensure that model "setup" is only performed once.
		ModelInfo existingModelInfo = getModelInfoFor(structuredModel);
		if (existingModelInfo == null) {
			addProviderFactories(structuredModel);
		} else {
			reinitializeFactories(structuredModel);
		}
		ModelInfo modelInfo = new ModelInfo(structuredModel, input, releaseModelOnDisconnect);
		fModelInfoMap.put(input, modelInfo);
		if (modelInfo.fFileSynchronizer != null) {
			modelInfo.fFileSynchronizer.install();
		}
		modelInfo.fStructuredModel.addModelStateListener(fInternalModelStateListener);
		modelInfo.fStructuredModel.addModelLifecycleListener(modelInfo);
		// fix once approved
		// we only resetSynchronizationStamp on model if its not set already
		if (input.getAdapter(IFile.class) != null && modelInfo.fStructuredModel.getSynchronizationStamp() == IResource.NULL_STAMP) {
			modelInfo.fStructuredModel.resetSynchronizationStamp((IResource) input.getAdapter(IFile.class));
		}
	}

	protected FileSynchronizer createModelSynchronizer(IEditorInput input, IStructuredModel model) {
		return null;
	}

	protected void disposeElementInfo(Object element, ElementInfo info) {
		if (debugOperations) {
			if (element instanceof IFileEditorInput)
				System.out.println("FileModelProvider: disposeElementInfo for " + ((IFileEditorInput) element).getFile().getFullPath());
			else
				System.out.println("FileModelProvider: disposeElementInfo for " + element);
		}
		if (element instanceof IEditorInput) {
			IEditorInput input = (IEditorInput) element;
			ModelInfo modelInfo = getModelInfoFor(input);
			if (modelInfo.fFileSynchronizer != null) {
				modelInfo.fFileSynchronizer.uninstall();
			}
			disposeModelInfo(modelInfo);
		}
		super.disposeElementInfo(element, info);
	}

	/**
	 * disconnect from this model info
	 * 
	 * @param info
	 */
	public void disposeModelInfo(ModelInfo info) {
		info.fStructuredModel.removeModelLifecycleListener(info);
		info.fStructuredModel.removeModelStateListener(fInternalModelStateListener);
		if (info.fShouldReleaseOnInfoDispose) {
			if (debugOperations) {
				if (info.fElement instanceof IFileEditorInput)
					System.out.println("FileModelProvider: disposeModelInfo and releaseFromEdit for " + ((IFileEditorInput) info.fElement).getFile().getFullPath());
				else
					System.out.println("FileModelProvider: disposeModelInfo and releaseFromEdit for " + info.fElement);
			}
			info.fStructuredModel.releaseFromEdit();
		} else if (debugOperations) {
			if (info.fElement instanceof IFileEditorInput)
				System.out.println("FileModelProvider: disposeModelInfo without releaseFromEdit for " + ((IFileEditorInput) info.fElement).getFile().getFullPath());
			else
				System.out.println("FileModelProvider: disposeModelInfo without releaseFromEdit for " + info.fElement);
		}
		if (info.fFileSynchronizer != null) {
			info.fFileSynchronizer.uninstall();
		}
		fModelInfoMap.remove(info.fElement);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.texteditor.AbstractDocumentProvider#doResetDocument(java.lang.Object,
	 *      org.eclipse.core.runtime.IProgressMonitor)
	 */
	protected void doResetDocument(Object element, IProgressMonitor monitor) throws CoreException {
		fReuseModelDocument = false;
		super.doResetDocument(element, monitor);
		fReuseModelDocument = true;
	}

	public void doSaveDocument(IProgressMonitor progressMonitor, Object element, IDocument document, boolean overwrite) throws CoreException {
		//TODO: still need to "transfer" much of this logic to model level
		boolean success = false;
		Assert.isTrue(element instanceof IFileEditorInput);
		IFileEditorInput input = (IFileEditorInput) element;
		IStructuredModel model = getModel(getInputFor(document));
		Assert.isNotNull(model);
		boolean localDirtyState = model.isDirty();
		IFile resource = input.getFile();
		try {
			if (!overwrite) {
				checkSynchronizationState(((FileInfo) getElementInfo(element)).fModificationStamp, resource);
			}
			// inform about the upcoming content change
			fireElementStateChanging(element);
			try {
				model.save(resource); //, encodingname, null);
			} catch (UnsupportedCharsetException exception) {
				Shell shell = getActiveShell();
				// FYI: made this indirect chain of calls to help get rid of
				// our specific Exception, need to test
				// that all is updated in right order, even when error.
				EncodingMemento encodingMemento = model.getStructuredDocument().getEncodingMemento();
				String foundEncoding = encodingMemento.getInvalidEncoding();
				String defaultToUse = encodingMemento.getAppropriateDefault();
				boolean tryDefault = openUnsupportEncodingForSave(foundEncoding, defaultToUse, resource.getName(), shell);
				if (tryDefault) {
					model.save(resource, EncodingRule.FORCE_DEFAULT);
				} else {
					// User has canceled Save. Keep view opened
					progressMonitor.setCanceled(true);
					return;
				}
			} catch (MalformedOutputExceptionWithDetail exception) {
				Shell shell = getActiveShell();
				boolean userOK = openUnconvertableCharactersWarningForSave(exception, shell); //resource.getName()
				if (userOK) {
					model.save(resource, EncodingRule.IGNORE_CONVERSION_ERROR);
				} else {
					// User has canceled Save. Keep view opened
					progressMonitor.setCanceled(true);
					return;
				}
			} catch (CharConversionErrorWithDetail exception) {
				Shell shell = getActiveShell();
				boolean userOK = openUnconvertableCharactersWarningForSave(exception, shell); //resource.getName()
				if (userOK) {
					model.save(resource, EncodingRule.IGNORE_CONVERSION_ERROR);
				} else {
					// User has canceled Save. Keep view opened
					progressMonitor.setCanceled(true);
					//outStream.close();
					//outStream = null;
					return;
				}
			}
			if (!resource.exists()) {
				progressMonitor.beginTask(SSEUIPlugin.getResourceString("%FileDocumentProvider.task.saving"), 2000); //$NON-NLS-1$ 
				ContainerGenerator generator = new ContainerGenerator(resource.getParent().getFullPath());
				generator.generateContainer(new SubProgressMonitor(progressMonitor, 1000));
			}
			// if we get to here without an exception... success!
			success = true;
			model.setDirtyState(false);
			model.resetSynchronizationStamp(resource);

			// update markers
			if (getAnnotationModel(element) instanceof AbstractMarkerAnnotationModel) {
				((AbstractMarkerAnnotationModel) getAnnotationModel(element)).updateMarkers(document);
			}
			// reset the modification stamp record so we know we don't try to
			// reload on following resource change notifications
			FileInfo info = (FileInfo) getElementInfo(element);
			if (info != null) {
				info.fModificationStamp = computeModificationStamp(resource);
			}

			//For error handling test only!!!==========
			//
			//Uncomment the following line of code to simulate a
			// FileNotFoundException.
			//throw new FileNotFoundException();
			//
			//Uncomment the following line of code to simulate a
			// UnsupportedEncodingException.
			//throw new UnsupportedEncodingException();
			//
			//Uncomment the following line of code to simulate a IOException.
			//throw new IOException();
			//For error handling test only!!!==========
		} catch (java.io.FileNotFoundException exception) {
			/*
			 * The FileNotFoundException's message may not be very meaningful
			 * to user. Since the SourceEditingRuntimeException(exception,
			 * message) form will use just the detail message in the passed-in
			 * exception (instead of concatenating the detail message with the
			 * additional message), we are converting this exception into a
			 * more informative message. Same idea applies to the following
			 * catch blocks.
			 */
			progressMonitor.setCanceled(true);
			// inform about failure
			fireElementStateChangeFailed(element);
			throw new SourceEditingRuntimeException(SSEUIPlugin.getResourceString("%Unable_to_save_the_documen_ERROR_")); //$NON-NLS-1$ = "Unable to save the document. Output file not found."
		} catch (UnsupportedEncodingException exception) {
			progressMonitor.setCanceled(true);
			// inform about failure
			fireElementStateChangeFailed(element);
			throw new SourceEditingRuntimeException(SSEUIPlugin.getResourceString("%Unable_to_save_the_documen1_ERROR_")); //$NON-NLS-1$ = "Unable to save the document. Unsupported encoding."
		} catch (java.io.IOException exception) {
			progressMonitor.setCanceled(true);
			// inform about failure
			fireElementStateChangeFailed(element);
			throw new SourceEditingRuntimeException(SSEUIPlugin.getResourceString("%Unable_to_save_the_documen2_ERROR_")); //$NON-NLS-1$
			//$NON-NLS-1$ = "Unable to save the document. An I/O error occurred while saving the document."
		} catch (OperationCanceledException exception) {
			Logger.log(Logger.INFO, "Save Operation Canceled at user's request"); //$NON-NLS-1$
		} finally {
			if (!success) {
				model.setDirtyState(localDirtyState);
			}
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.texteditor.IDocumentProviderExtension#synchronize(java.lang.Object)
	 */
	public void doSynchronize(Object element, IProgressMonitor monitor) throws CoreException {
		super.doSynchronize(element, monitor);
		if (element instanceof IFileEditorInput) {
			IFileEditorInput input = (IFileEditorInput) element;
			getModel(input).resetSynchronizationStamp(input.getFile());
		}
	}

	protected void fireModelContentAboutToBeReplaced(IStructuredModel model) {
	}

	protected void fireModelContentReplaced(IStructuredModel model) {
	}

	protected void fireModelDeleted(IStructuredModel model) {
	}

	protected void fireModelDirtyStateChanged(IStructuredModel model, final boolean isDirty) {
	}

	protected void fireModelMoved(IStructuredModel originalModel, IStructuredModel movedModel) {
	}

	protected Shell getActiveShell() {
		Shell shell = null;
		// Looks like Display tells me what is the current active Shell
		// so that it seems not to ask EditorPart to give me a Shell.
		// Same technique in used by
		// Infopop(org.eclipse.help.internal.ui.ContextHelpDialog(Object [],
		// int, int))
		// looks like there's not always an active shell, at least
		// during debugging the save operation with invalid encoding
		if (fActiveShell != null) {
			shell = fActiveShell;
		} else {
			Display dsp = getDisplay();
			shell = dsp.getActiveShell();
		}
		return shell;
	}

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

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.editors.text.IStorageDocumentProvider#getEncoding(java.lang.Object)
	 */
	public String getEncoding(Object element) {
		EncodingMemento em = null;
		IStructuredModel model = getModel((IEditorInput) element);
		// model can be null if opened on non-expected file
		if (model != null) {
			em = model.getStructuredDocument().getEncodingMemento();
		}
		// DefaultEncodingSupport uses IANA names
		if (em != null)
			return em.getDetectedCharsetName();
		return super.getEncoding(element);
	}

	protected IEditorInput getInputFor(IDocument document) {
		IStructuredModel model = getModelManager().getExistingModelForRead(document);
		IEditorInput input = getInputFor(model);
		model.releaseFromRead();
		return input;
	}

	protected IEditorInput getInputFor(IStructuredModel structuredModel) {
		IEditorInput result = null;
		ModelInfo info = getModelInfoFor(structuredModel);
		if (info != null)
			result = info.fElement;
		return result;
	}

	public IStructuredModel getModel(IEditorInput element) {
		IStructuredModel result = null;
		ModelInfo info = getModelInfoFor(element);
		if (info != null) {
			result = info.fStructuredModel;
		}
		return result;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.wst.sse.ui.IModelProvider#getModel(java.lang.Object)
	 */
	public IStructuredModel getModel(Object element) {
		Assert.isTrue(element instanceof IFileEditorInput);
		return getModel((IFileEditorInput) element);
	}

	protected ModelInfo getModelInfoFor(IEditorInput element) {
		ModelInfo result = (ModelInfo) fModelInfoMap.get(element);
		return result;
	}

	protected ModelInfo getModelInfoFor(IStructuredModel structuredModel) {
		ModelInfo result = null;
		if (structuredModel != null) {
			ModelInfo[] modelInfos = (ModelInfo[]) fModelInfoMap.values().toArray(new ModelInfo[0]);
			for (int i = 0; i < modelInfos.length; i++) {
				ModelInfo info = modelInfos[i];
				if (structuredModel.equals(info.fStructuredModel)) {
					result = info;
					break;
				}
			}
		}
		return result;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.editors.text.FileDocumentProvider#getPersistedEncoding(java.lang.Object)
	 */
	protected String getPersistedEncoding(Object element) {
		EncodingMemento em = null;
		IStructuredModel model = getModel((IEditorInput) element);
		if (model != null) {
			em = model.getStructuredDocument().getEncodingMemento();
		}
		// DefaultEncodingSupport uses IANA names
		if (em != null) {
			return em.getDetectedCharsetName();
		} else {
			// error condition
			return ""; //$NON-NLS-1$
		}
	}

	/**
	 * Defines the standard procedure to handle CoreExceptions.
	 * 
	 * @param exception
	 *            the exception to be logged
	 * @param message
	 *            the message to be logged
	 */
	protected void handleCoreException(CoreException exception, String message) {
		Logger.logException(message, exception);
	}

	/**
	 * Updates the element info and Document contents to a change of the file
	 * content and sends out appropriate notifications.
	 * 
	 * @param fileEditorInput
	 *            the input of a text editor
	 */
	protected void handleElementContentChanged(IFileEditorInput fileEditorInput) {
		FileInfo info = (FileInfo) getElementInfo(fileEditorInput);
		if (info == null)
			return;

		String oldContents = getModel(fileEditorInput).getStructuredDocument().get();

		try {
			refreshFile(fileEditorInput.getFile());
		} catch (CoreException x) {
			handleCoreException(x, "FileDocumentProvider.handleElementContentChanged"); //$NON-NLS-1$
		}

		// set the new content and fire content related events
		fireElementContentAboutToBeReplaced(fileEditorInput);
		removeUnchangedElementListeners(fileEditorInput, info);

		// direct superclass also removes but never adds?
		info.fDocument.removeDocumentListener(info);

		boolean reloaded = false;
		InputStream inStream = null;
		try {
			inStream = fileEditorInput.getFile().getContents(true);
			getModel(fileEditorInput).reload(inStream);
			reloaded = true;
		} catch (IOException e) {
			String message = MessageFormat.format(SSEUIPlugin.getResourceString("%FileModelProvider.0"), new String[]{fileEditorInput.getName()}); //$NON-NLS-1$
			info.fStatus = new Status(IStatus.ERROR, SSEUIPlugin.ID, IStatus.ERROR, message, e);
		} catch (CoreException e) {
			info.fStatus = e.getStatus();
		} finally {
			if (inStream != null) {
				try {
					inStream.close();
				} catch (IOException e1) {
					Logger.logException(e1);
				}
			}
		}
		info.fDocument = getModel(fileEditorInput).getStructuredDocument();

		info.fCanBeSaved = false;
		info.fModificationStamp = computeModificationStamp(fileEditorInput.getFile());
		if (reloaded) {
			info.fStatus = null;
		}

		addUnchangedElementListeners(fileEditorInput, info);
		fireElementContentReplaced(fileEditorInput);
		if (!reloaded) {
			info.fDocument.set(oldContents);
		}
	}

	/**
	 * @see org.eclipse.ui.editors.text.FileDocumentProvider#isModifiable(java.lang.Object)
	 */
	public boolean isModifiable(Object element) {
		return super.isModifiable(element); //!isReadOnly(element);
	}

	/**
	 * @see org.eclipse.ui.texteditor.IDocumentProvider#mustSaveDocument(java.lang.Object)
	 *      <br>
	 * 
	 * The rule is that if it is sharedForEdit, then it never "must be saved",
	 * but if its not sharedForEdit, then it depends on its dirty state.
	 */
	public boolean mustSaveDocument(Object element) {
		boolean result = false;
		if (getModel((IEditorInput) element) != null) {
			if (!getModel((IEditorInput) element).isSharedForEdit()) {
				result = getModel((IEditorInput) element).isDirty();
			}
		}
		return result;
	}

	private boolean openUnconvertableCharactersWarningForSave(CharConversionErrorWithDetail outputException, Shell topshell) {
		// open message dialog
		final String title = UNSUPPORTED_ENCODING_WARNING_TITLE;
		String userMessage = SSEUIPlugin.getResourceString("%cannot_convert_some_characters2"); //$NON-NLS-1$
		MessageFormat form = new MessageFormat(userMessage);
		Object[] args = {outputException.getCharsetName()};
		final String msg = form.format(args);
		Shell shell = getActiveShell();
		MessageDialog warning = new MessageDialog(shell, title, null, msg, MessageDialog.QUESTION, new String[]{IDialogConstants.OK_LABEL, IDialogConstants.CANCEL_LABEL}, 0);
		if (warning.open() == 0)
			return true;
		return false;
	}

	protected boolean openUnconvertableCharactersWarningForSave(MalformedOutputExceptionWithDetail outputException, Shell topshell) {
		// open message dialog
		final String title = UNSUPPORTED_ENCODING_WARNING_TITLE;
		String userMessage = SSEUIPlugin.getResourceString("%cannot_convert_some_characters"); //$NON-NLS-1$
		MessageFormat form = new MessageFormat(userMessage);
		Object[] args = {outputException.getAttemptedIANAEncoding(), Integer.toString(outputException.getCharPosition())};
		final String msg = form.format(args);
		Shell shell = getActiveShell();
		MessageDialog warning = new MessageDialog(shell, title, null, msg, MessageDialog.QUESTION, new String[]{IDialogConstants.OK_LABEL, IDialogConstants.CANCEL_LABEL}, 0);
		if (warning.open() == 0)
			return true;
		return false;
	}

	protected void openUndecodableCharacterError(MalformedInputExceptionWithDetail e) {
		// checked and coordinated among all editors.
		String title = SSEUIPlugin.getResourceString("%Error_opening_file_UI_"); //$NON-NLS-1$ = "Error opening file"
		String msg = e.toString();
		// if the exception char position < 0, perhaps we exceeded the max
		// buffer when detecting pos of error
		// if that is the case, display a different error message
		IStatus status;
		if ((e.getCharPosition() < 0) && (e.isExceededMax()))
			status = new Status(IStatus.ERROR, SSEUIPlugin.ID, 0, SSEUIPlugin.getResourceString("%8concat_ERROR_", (new Object[]{Integer.toString(e.getMaxBuffer()), e.getAttemptedIANAEncoding()})), e); //$NON-NLS-1$
		else
			status = new Status(IStatus.ERROR, SSEUIPlugin.ID, 0, SSEUIPlugin.getResourceString("%7concat_ERROR_", (new Object[]{(Integer.toString(e.getCharPosition())), e.getAttemptedIANAEncoding()})), e); //$NON-NLS-1$
		//$NON-NLS-1$ = "Could not be decoded character (at position {0}) according to the encoding parameter {1}"
		ErrorDialog.openError(getActiveShell(), title, msg, status);
	}

	protected void openUnsupportedEncodingWarningForLoad(String encoding, String defaultToUse) {
		// open message dialog
		final String title = UNSUPPORTED_ENCODING_WARNING_TITLE;
		MessageFormat form = new MessageFormat(SSEUIPlugin.getResourceString("%This_encoding_({0})_is_not_supported._The_default_encoding_({1})_will_be_used_instead._1")); //$NON-NLS-1$
		Object[] args = {encoding, defaultToUse};
		final String msg = form.format(args);
		Shell shell = getActiveShell();
		MessageDialog warning = new MessageDialog(shell, title, null, msg, MessageDialog.WARNING, new String[]{IDialogConstants.OK_LABEL}, 0);
		warning.open();
	}

	protected boolean openUnsupportEncodingForSave(String foundEncoding, String defaultEncodingToUse, String dialogTitle, Shell topshell) {
		if (topshell == null)
			return true; // if no topshell, return true;
		// open message dialog
		//  MessageFormat form = new
		// MessageFormat(ResourceHandler.getString("This_encoding({0})_is_not__WARN_"));
		// //$NON-NLS-1$ = "This encoding({0}) is not supported. Continue ?"
		MessageFormat form = new MessageFormat(SSEUIPlugin.getResourceString("%This_encoding_({0})_is_not_supported._Continue_the_save_using_the_default_({1})__2")); //$NON-NLS-1$
		Object[] args = {foundEncoding, defaultEncodingToUse};
		final String msg = form.format(args);
		MessageDialog warning = new MessageDialog(topshell, dialogTitle, null, msg, MessageDialog.QUESTION, new String[]{IDialogConstants.OK_LABEL, IDialogConstants.CANCEL_LABEL}, 0);
		if (warning.open() == 0)
			return true;
		return false;
	}

	/**
	 * Register additional (viewer related) factories Note: this can be called
	 * twice, one for when model first created and loaded to editor. And
	 * possible later, if a model "reinit" takes place.
	 */
	protected void reinitializeFactories(IStructuredModel structuredModel) {
		// its an error to call with null argument
		if (structuredModel == null)
			return;
		SSEUIPlugin plugin = ((SSEUIPlugin) Platform.getPlugin(SSEUIPlugin.ID));
		AdapterFactoryRegistry adapterRegistry = plugin.getAdapterFactoryRegistry();
		Iterator adapterList = adapterRegistry.getAdapterFactories();
		// And all those appropriate for this particular type of content
		while (adapterList.hasNext()) {
			try {
				AdapterFactoryProvider provider = (AdapterFactoryProvider) adapterList.next();
				if (provider.isFor(structuredModel.getModelHandler())) {
					provider.reinitializeFactories(structuredModel);
				}
			} catch (Exception e) {
				Logger.logException(e);
			}
		}
	}

	protected IStructuredModel selfCreateModel(IFileEditorInput input) {
		// this method should be called only after is established the
		// desired model is not in the active items list.
		IStructuredModel structuredModel = getModelManager().getExistingModelForEdit(input.getFile());
		if (structuredModel == null) {
			try {
				try {
					structuredModel = getModelManager().getModelForEdit(input.getFile()); //
				} catch (UnsupportedCharsetException exception) {
					// TODO-future: user should be given a choice here to try
					// other encodings other than 'default'
					EncodingMemento encodingMemento = null;
					if (exception instanceof UnsupportedCharsetExceptionWithDetail) {
						UnsupportedCharsetExceptionWithDetail detailedException = (UnsupportedCharsetExceptionWithDetail) exception;
						encodingMemento = detailedException.getEncodingMemento();
					}

					String foundEncoding = encodingMemento.getInvalidEncoding();
					String defaultToUse = encodingMemento.getAppropriateDefault();
					openUnsupportedEncodingWarningForLoad(foundEncoding, defaultToUse);
					try {
						structuredModel = getModelManager().getModelForEdit(input.getFile(), EncodingRule.FORCE_DEFAULT); //$NON-NLS-1$ //$NON-NLS-2$
					} catch (MalformedInputExceptionWithDetail ex) { // this
						openUndecodableCharacterError(ex);
						structuredModel = null;
					}
				} catch (MalformedInputExceptionWithDetail e) {
					openUndecodableCharacterError(e);

					structuredModel = getModelManager().getModelForEdit(input.getFile(), EncodingRule.IGNORE_CONVERSION_ERROR);
				}
			} catch (CoreException e) {
				throw new SourceEditingRuntimeException(e);
			} catch (IOException e) {
				throw new SourceEditingRuntimeException(e);
			}
		}
		return structuredModel;
	}

	/**
	 * we should figure out how not to need this in future. I've found that
	 * during 'save', the active shell, obtainable from Display, is null, so
	 * this shell must be set by editor before requesting the save. We should
	 * check "legality" directly from editor.
	 */
	public void setActiveShell(Shell activeShell) {
		fActiveShell = activeShell;

	}

	/**
	 * This method is intended for those uses where the model has already been
	 * obtained and provided by the client (with its own id, not necessarily
	 * the one we would create by default). The IEditorInput must still be
	 * connect()ed before regular IDocumentProvider APIs will function.
	 */
	public void setModel(IStructuredModel model, IEditorInput input) {
		if (debugOperations) {
			if (input instanceof IFileEditorInput)
				System.out.println("FileModelProvider: setModel override used for " + ((IFileEditorInput) input).getFile().getFullPath());
			else
				System.out.println("FileModelProvider: setModel override used for " + input);
		}
		createModelInfo(input, model, false);
	}

}
