/*******************************************************************************
 * Copyright (c) 2004, 2006 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
 *******************************************************************************/
package org.eclipse.jst.jsp.core.internal.modelhandler;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.filebuffers.FileBuffers;
import org.eclipse.core.filebuffers.ITextFileBuffer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.content.IContentDescription;
import org.eclipse.core.runtime.content.IContentType;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IDocumentPartitioner;
import org.eclipse.jst.jsp.core.internal.Logger;
import org.eclipse.jst.jsp.core.internal.contentproperties.JSPFContentProperties;
import org.eclipse.jst.jsp.core.internal.document.PageDirectiveAdapter;
import org.eclipse.jst.jsp.core.internal.document.PageDirectiveAdapterFactory;
import org.eclipse.jst.jsp.core.internal.document.PageDirectiveWatcherFactory;
import org.eclipse.jst.jsp.core.internal.domdocument.DOMModelForJSP;
import org.eclipse.jst.jsp.core.internal.encoding.IJSPHeadContentDetector;
import org.eclipse.jst.jsp.core.internal.encoding.JSPDocumentHeadContentDetector;
import org.eclipse.jst.jsp.core.internal.encoding.JSPDocumentLoader;
import org.eclipse.jst.jsp.core.internal.modelquery.JSPModelQueryAdapterImpl;
import org.eclipse.jst.jsp.core.internal.modelquery.ModelQueryAdapterFactoryForJSP;
import org.eclipse.jst.jsp.core.internal.parser.JSPReParser;
import org.eclipse.jst.jsp.core.internal.parser.JSPSourceParser;
import org.eclipse.jst.jsp.core.internal.provisional.contenttype.ContentTypeIdForJSP;
import org.eclipse.jst.jsp.core.internal.provisional.contenttype.IContentDescriptionForJSP;
import org.eclipse.jst.jsp.core.internal.text.StructuredTextPartitionerForJSP;
import org.eclipse.wst.html.core.internal.provisional.contenttype.ContentTypeFamilyForHTML;
import org.eclipse.wst.html.core.internal.provisional.contenttype.ContentTypeIdForHTML;
import org.eclipse.wst.html.core.internal.text.StructuredTextPartitionerForHTML;
import org.eclipse.wst.sse.core.internal.PropagatingAdapter;
import org.eclipse.wst.sse.core.internal.document.IDocumentLoader;
import org.eclipse.wst.sse.core.internal.document.StructuredDocumentFactory;
import org.eclipse.wst.sse.core.internal.ltk.modelhandler.EmbeddedTypeHandler;
import org.eclipse.wst.sse.core.internal.ltk.parser.JSPCapableParser;
import org.eclipse.wst.sse.core.internal.ltk.parser.RegionParser;
import org.eclipse.wst.sse.core.internal.model.AbstractModelLoader;
import org.eclipse.wst.sse.core.internal.modelhandler.EmbeddedTypeRegistry;
import org.eclipse.wst.sse.core.internal.modelhandler.EmbeddedTypeRegistryImpl;
import org.eclipse.wst.sse.core.internal.provisional.IModelLoader;
import org.eclipse.wst.sse.core.internal.provisional.INodeAdapterFactory;
import org.eclipse.wst.sse.core.internal.provisional.INodeNotifier;
import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
import org.eclipse.wst.sse.core.internal.text.BasicStructuredDocument;
import org.eclipse.wst.sse.core.internal.util.Assert;
import org.eclipse.wst.sse.core.internal.util.Debug;
import org.eclipse.wst.sse.core.internal.util.DocumentInputStream;
import org.eclipse.wst.xml.core.internal.DebugAdapterFactory;
import org.eclipse.wst.xml.core.internal.document.DOMModelImpl;
import org.eclipse.wst.xml.core.internal.propagate.PropagatingAdapterFactoryImpl;
import org.eclipse.wst.xml.core.internal.provisional.contenttype.ContentTypeIdForXML;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
import org.eclipse.wst.xml.core.internal.ssemodelquery.ModelQueryAdapter;
import org.eclipse.wst.xml.core.internal.text.rules.StructuredTextPartitionerForXML;
import org.w3c.dom.Document;

public class JSPModelLoader extends AbstractModelLoader {
	protected final int MAX_BUFFERED_SIZE_FOR_RESET_MARK = 200000;

	/**
	 * DMW - Note: I think the embeddedTypeRegistry in IModelManager can be
	 * removed
	 */
	private EmbeddedTypeRegistry embeddedContentTypeRegistry;
	private final static String DEFAULT_MIME_TYPE = "text/html"; //$NON-NLS-1$
	private final static String DEFAULT_LANGUAGE = "java"; //$NON-NLS-1$

	public JSPModelLoader() {
		super();
	}

	/**
	 * Gets the embeddedContentTypeRegistry.
	 * 
	 * @return Returns a EmbeddedContentTypeRegistry
	 */
	private EmbeddedTypeRegistry getEmbeddedContentTypeRegistry() {
		if (embeddedContentTypeRegistry == null) {
			embeddedContentTypeRegistry = EmbeddedTypeRegistryImpl.getInstance();
		}
		return embeddedContentTypeRegistry;
	}

	public IStructuredModel newModel() {
		DOMModelForJSP model = new DOMModelForJSP();
		return model;
	}

	/**
	 * For JSP files, text/html is the default content type. This may want
	 * this different for types like jsv (jsp for voice xml) For now, hard
	 * code to new instance. In future, should get instance from registry.
	 * 
	 * Specification cites HTML as the default contentType.
	 */
	private EmbeddedTypeHandler getJSPDefaultEmbeddedType(IStructuredModel model) {
		EmbeddedTypeRegistry reg = getEmbeddedContentTypeRegistry();

		String mimeType = null;
		// default embedded type for fragments
		if (model != null) {
			IFile file = getFile(model);
			if (file != null) {
				mimeType = JSPFContentProperties.getProperty(JSPFContentProperties.JSPCONTENTTYPE, file, true);
			}
		}
		mimeType = mimeType == null ? getDefaultMimeType() : mimeType;
		return reg.getTypeFor(mimeType);
	}

	/**
	 * Method getDefaultMimeType.
	 * 
	 * @return String
	 */
	private String getDefaultMimeType() {
		return DEFAULT_MIME_TYPE;
	}

	/**
	 * This method must return a new instance of IStructuredDocument, that has
	 * been initialized with appropriate parser. For many loaders, the
	 * (default) parser used is known for any input. For others, the correct
	 * parser (and its initialization) is normall dependent on the content of
	 * the file. This no-argument method should assume "empty input" and would
	 * therefore return the default parser for the default contentType.
	 * 
	 * If the parser is to handle tag libraries, it must have a TaglibSupport
	 * object with a valid URIResolver and this IStructuredDocument attached
	 * to it before the contents are set on the IStructuredDocument.
	 */
	public IStructuredDocument newStructuredDocument() {
		IStructuredDocument structuredDocument = StructuredDocumentFactory.getNewStructuredDocumentInstance(getParser());
		((BasicStructuredDocument) structuredDocument).setReParser(new JSPReParser());
		// structuredDocument.setDocumentPartitioner(new
		// JSPJavaDocumentPartioner());
		// even though this is an "empty model" ... we want it to have at
		// least the
		// default embeddeded content type handler
		EmbeddedTypeHandler embeddedType = getJSPDefaultEmbeddedType(null);
		embeddedType.initializeParser((JSPCapableParser) structuredDocument.getParser());
		return structuredDocument;
	}

	public RegionParser getParser() {
		// remember, the Loader
		// will need to finish initialization of parser
		// based on "embedded content"
		return new JSPSourceParser();
	}

	protected void preLoadAdapt(IStructuredModel structuredModel) {
		super.preLoadAdapt(structuredModel);
		IDOMModel domModel = (IDOMModel) structuredModel;
		//
		// document must have already been set for this to
		// work.
		Document document = domModel.getDocument();
		Assert.isNotNull(document);
		// if there is a model in the adapter, this will adapt it to
		// first node. After that the PropagatingAdater spreads over the
		// children being
		// created. Each time that happends, a side effect is to
		// also "spread" sprecific registered adapters,
		// they two can propigate is needed.
		// This 'get' causes first to be be attached.
		PropagatingAdapter propagatingAdapter = (PropagatingAdapter) ((INodeNotifier) document).getAdapterFor(PropagatingAdapter.class);
		// may make this easier to use in futue
		propagatingAdapter.addAdaptOnCreateFactory(new PageDirectiveWatcherFactory());
		if (Debug.debugNotificationAndEvents) {
			propagatingAdapter.addAdaptOnCreateFactory(new DebugAdapterFactory());
		}
		// For JSPs, the ModelQueryAdapter must be "attached" to the document
		// before content is set in the model, so taglib initization can
		// take place.
		((INodeNotifier) document).getAdapterFor(ModelQueryAdapter.class);
		//

	}

	/**
	 * This method must return those factories which must be attached to the
	 * structuredModel before content is applied.
	 */
	public List getAdapterFactories() {
		List result = new ArrayList();
		INodeAdapterFactory factory = null;
		//
		factory = new ModelQueryAdapterFactoryForJSP();
		result.add(factory);
		factory = new PropagatingAdapterFactoryImpl();
		result.add(factory);
		factory = new PageDirectiveAdapterFactory();
		result.add(factory);

		return result;
	}


	public IJSPHeadContentDetector getHeadParser() {
		return new JSPDocumentHeadContentDetector();
	}

	private IContentDescription getContentDescription(IDocument doc) {
		if (doc == null)
			return null;
		DocumentInputStream in = new DocumentInputStream(doc);
		return getContentDescription(in);
	}

	/**
	 * 
	 * @param filePath
	 * @return the content description, or null if there's no buffer for the
	 *         filepath
	 */
	private IContentDescription getContentDescription(String filePath) {
		if (filePath == null)
			return null;

		IDocument doc = null;
		ITextFileBuffer buf = FileBuffers.getTextFileBufferManager().getTextFileBuffer(new Path(filePath));
		if (buf != null) {
			doc = buf.getDocument();
		}

		IContentDescription contentDescription = null;
		if (doc != null) {
			contentDescription = getContentDescription(doc);
		}
		return contentDescription;
	}

	/**
	 * Returns content description for an input stream Assumes it's JSP
	 * content. Closes the input stream when finished.
	 * 
	 * @param in
	 * @return the IContentDescription for in, or null if in is null
	 */
	private IContentDescription getContentDescription(InputStream in) {

		if (in == null)
			return null;

		IContentDescription desc = null;
		try {

			IContentType contentTypeJSP = Platform.getContentTypeManager().getContentType(ContentTypeIdForJSP.ContentTypeID_JSP);
			desc = contentTypeJSP.getDescriptionFor(in, IContentDescription.ALL);
		}
		catch (IOException e) {
			Logger.logException(e);
		}
		finally {
			if (in != null) {
				try {
					in.close();
				}
				catch (IOException e) {
					Logger.logException(e);
				}
			}
		}
		return desc;
	}

	private IFile getFile(IStructuredModel model) {
		if (model != null) {
			String location = model.getBaseLocation();
			if (location != null) {
				IPath path = new Path(location);
				if (!path.toFile().exists() && path.segmentCount() > 1) {
					return ResourcesPlugin.getWorkspace().getRoot().getFile(path);
				}
			}
		}
		return null;
	}

	/**
	 * Method getLanguage.
	 * 
	 * @param model
	 * @return String
	 */
	private String getLanguage(IStructuredModel model) {
		String result = null;
		// first check the model (document itself) to see if contains
		result = getLanguageFromStructuredDocument(model.getStructuredDocument());
		// Note: if model contains an unsupported
		// language, we'll even return it,
		// since who knows what future holds.

		// get default language specified in properties page
		IFile file = getFile(model);
		result = JSPFContentProperties.getProperty(JSPFContentProperties.JSPLANGUAGE, file, true);

		// always return something
		if (result == null) {
			result = DEFAULT_LANGUAGE;
		}
		return result;
	}

	/**
	 * Method getLanguageFromStructuredDocument.
	 * 
	 * @param structuredDocument
	 * @return String
	 */
	private String getLanguageFromStructuredDocument(IStructuredDocument structuredDocument) {
		if (structuredDocument == null)
			return null;
		String result = null;
		// bascially same algorithm as get encoding or
		// get content type from structuredDocument.
		IJSPHeadContentDetector localHeadParser = getHeadParser();
		// we can be assured that its already been
		// parsed. If not call parseHeaderForPageDirective()
		// before calling getLanguage;
		localHeadParser.set(structuredDocument);
		try {
			result = localHeadParser.getLanguage();
		}
		catch (IOException e) {
			// impossible
			// TODO need to reconsider design to avoid
			throw new Error(e);
		}
		return result;
	}

	/**
	 * This is "reinitialize" since there should always be at least the
	 * default one assigned, before we start checking the stream
	 */
	private void reInitializeEmbeddedType(IStructuredModel model, EmbeddedTypeHandler oldEmbeddedContentType, EmbeddedTypeHandler newEmbeddedContentType) {
		// check program logic
		Assert.isNotNull(oldEmbeddedContentType, "Program error: invalid call during model initialization"); //$NON-NLS-1$
		// once we know the embedded content type, we need to set it in the
		// PageDirectiveAdapter ... the order of initialization is
		// critical here, the doc must have been created, but its contents not
		// set yet,
		// and all factories must have been set up also.
		IDOMModel domModel = (IDOMModel) model;
		IStructuredDocument structuredDocument = model.getStructuredDocument();
		IDOMDocument document = domModel.getDocument();
		PageDirectiveAdapter pageDirectiveAdapter = (PageDirectiveAdapter) document.getExistingAdapter(PageDirectiveAdapter.class);
		// ==> // PropagatingAdapter propagatingAdapter = (PropagatingAdapter)
		// ((INodeNotifier)
		// document).getExistingAdapter(PropagatingAdapter.class);
		// ==> // ModelQueryAdapter modelQueryAdapter = (ModelQueryAdapter)
		// ((INodeNotifier)
		// document).getExistingAdapter(ModelQueryAdapter.class);
		oldEmbeddedContentType.uninitializeFactoryRegistry(model.getFactoryRegistry());
		oldEmbeddedContentType.uninitializeParser((JSPCapableParser) structuredDocument.getParser());
		// since 'document' is not recreated in this
		// reinit path, we need to remove all adapters,
		// except for the propagated adapters (including page
		// directive adapter, and model query adapter).
		// to accomplish this, we'll just remove all, then
		// add back with a call to pre-load adapt.
		// let clients decide to unload adapters from document
		// Collection oldAdapters = document.getAdapters();
		// Iterator oldAdaptersIterator = oldAdapters.iterator();
		// while (oldAdaptersIterator.hasNext()) {
		// INodeAdapter oldAdapter = (INodeAdapter)
		// oldAdaptersIterator.next();
		// if (oldAdapter != pageDirectiveAdapter && oldAdapter !=
		// propagatingAdapter && oldAdapter != modelQueryAdapter) {
		// // DO NOT remove directly!
		// // can change contents while in notifity loop!
		// //oldAdaptersIterator.remove();
		// document.removeAdapter(oldAdapter);
		// }
		// }
		// DMW: I believe something like the following is needed,
		// since releases cached adapters
		// if (document instanceof DocumentImpl) {
		// ((DocumentImpl) document).releaseDocumentType();
		// ((DocumentImpl) document).releaseStyleSheets();
		// }
		// remember, embedded type factories are automatically cleared when
		// embededType changed
		pageDirectiveAdapter.setEmbeddedType(newEmbeddedContentType);
		// // but still need to clear the page directive watchers, and let
		// them be rediscovered (with new, accurate node as target)
		// pageDirectiveAdapter.clearPageWatchers();
		if (newEmbeddedContentType != null) {

			// need to null out or else ModelParserAdapter
			// won't get reinitialized
			((DOMModelImpl) model).setModelParser(null);

			newEmbeddedContentType.initializeFactoryRegistry(model.getFactoryRegistry());
			newEmbeddedContentType.initializeParser((JSPCapableParser) structuredDocument.getParser());

			// partitioner setup is the responsibility of this loader
			IDocumentPartitioner documentPartitioner = structuredDocument.getDocumentPartitioner();
			// ISSUE: this logic is flawed, not sure of original intent, but
			// added null/type checks for safety.
			if (documentPartitioner != null && documentPartitioner instanceof StructuredTextPartitionerForJSP) {
				if (newEmbeddedContentType.getFamilyId().equals(ContentTypeIdForXML.ContentTypeID_XML)) {
					((StructuredTextPartitionerForJSP) documentPartitioner).setEmbeddedPartitioner(new StructuredTextPartitionerForXML());
				}
				else if (newEmbeddedContentType.getFamilyId().equals(ContentTypeIdForHTML.ContentTypeID_HTML)) {
					((StructuredTextPartitionerForJSP) documentPartitioner).setEmbeddedPartitioner(new StructuredTextPartitionerForHTML());
				}
			}
		}
		// adding language here, in this convienent central
		// location, but some obvious renaming or refactoring
		// wouldn't hurt, in future.
		// I needed to add this language setting for JSP Fragment support
		// Note: this is the one that counts, since at this point,
		// the model has an ID, so we can look up IFile, etc.
		String language = getLanguage(model);
		if (language != null && language.length() > 0) {
			pageDirectiveAdapter.setLanguage(language);
		}
	}

	/**
	 * This is "reinitialize" since there should always be at least the
	 * default one assigned, before we start checking the stream
	 */
	private void initCloneOfEmbeddedType(IStructuredModel model, EmbeddedTypeHandler oldEmbeddedContentType, EmbeddedTypeHandler newEmbeddedContentType) {
		// check program logic
		Assert.isNotNull(oldEmbeddedContentType, "Program error: invalid call during model initialization"); //$NON-NLS-1$
		// once we know the embedded content type, we need to set it in the
		// PageDirectiveAdapter ... the order of initialization is
		// critical here, the doc must have been created, but its contents not
		// set yet,
		// and all factories must have been set up also.
		IDOMModel domModel = (IDOMModel) model;
		IStructuredDocument structuredDocument = model.getStructuredDocument();
		IDOMDocument document = domModel.getDocument();
		PageDirectiveAdapter pageDirectiveAdapter = (PageDirectiveAdapter) document.getAdapterFor(PageDirectiveAdapter.class);
		// ==> // PropagatingAdapter propagatingAdapter = (PropagatingAdapter)
		// ((INodeNotifier) document).getAdapterFor(PropagatingAdapter.class);
		// ==> // ModelQueryAdapter modelQueryAdapter = (ModelQueryAdapter)
		// ((INodeNotifier) document).getAdapterFor(ModelQueryAdapter.class);
		// because, even in the clone case, the model has been paritally
		// intialized with
		// the old embedded type (during createModel), we need to unitialize
		// parts of it, based on the old (or default) ones
		oldEmbeddedContentType.uninitializeFactoryRegistry(model.getFactoryRegistry());
		oldEmbeddedContentType.uninitializeParser((JSPCapableParser) structuredDocument.getParser());
		// remember, embedded type factories are automatically cleared when
		// embededType changed
		pageDirectiveAdapter.setEmbeddedType(newEmbeddedContentType);
		if (newEmbeddedContentType != null) {
			newEmbeddedContentType.initializeFactoryRegistry(model.getFactoryRegistry());
			newEmbeddedContentType.initializeParser((JSPCapableParser) structuredDocument.getParser());
		}
		// adding language here, in this convienent central
		// location, but some obvious renaming or refactoring
		// wouldn't hurt, in future.
		// I needed to add this language setting for JSP Fragment support
		// Note: this is the one that counts, since at this point,
		// the model has an ID, so we can look up IFile, etc.
		String language = getLanguage(model);
		if (language != null && language.length() > 0) {
			pageDirectiveAdapter.setLanguage(language);
		}
	}

	private EmbeddedTypeHandler getEmbeddedType(IStructuredModel model) {
		Document doc = ((IDOMModel) model).getDocument();
		PageDirectiveAdapter pageDirectiveAdapter = (PageDirectiveAdapter) ((INodeNotifier) doc).getAdapterFor(PageDirectiveAdapter.class);
		EmbeddedTypeHandler embeddedHandler = pageDirectiveAdapter.getEmbeddedType();
		return embeddedHandler;
	}

	protected void initEmbeddedTypePre(IStructuredModel model) {

		// note: this will currently only work for models backed by files
		EmbeddedTypeHandler embeddedContentType = null;
		IDOMModel domModel = (IDOMModel) model;

		String possibleFileBaseLocation = model.getBaseLocation();

		if (embeddedContentType == null) {
			IContentDescription desc = getContentDescription(possibleFileBaseLocation);
			if (desc != null) {
				Object prop = null;

				prop = desc.getProperty(IContentDescriptionForJSP.CONTENT_FAMILY_ATTRIBUTE);
				if (prop != null) {
					if (ContentTypeFamilyForHTML.HTML_FAMILY.equals(prop)) {
						embeddedContentType = EmbeddedTypeRegistryImpl.getInstance().getTypeFor("text/html");
					}
				}

				if (embeddedContentType == null) {

					prop = desc.getProperty(IContentDescriptionForJSP.CONTENT_TYPE_ATTRIBUTE);
					if (prop != null) {
						embeddedContentType = EmbeddedTypeRegistryImpl.getInstance().getTypeFor((String) prop);
					}
				}
			}
		}

		IDOMDocument document = domModel.getDocument();
		PageDirectiveAdapter pageDirectiveAdapter = (PageDirectiveAdapter) document.getAdapterFor(PageDirectiveAdapter.class);

		if (embeddedContentType != null) {
			pageDirectiveAdapter.setEmbeddedType(embeddedContentType);
			embeddedContentType.initializeFactoryRegistry(model.getFactoryRegistry());
		}
		else {
			// use default embeddedType if it couldn't determine one
			embeddedContentType = getJSPDefaultEmbeddedType(model);
			pageDirectiveAdapter.setEmbeddedType(embeddedContentType);
			embeddedContentType.initializeFactoryRegistry(model.getFactoryRegistry());
		}
	}

	protected void initEmbeddedTypePost(IStructuredModel model) {
		// should already be initialized (from initEmbeddedTypePre)
		// via IContentDescription
		setLanguageInPageDirective(model);
	}

	/**
	 * Method initEmbeddedType.
	 */
	protected void initEmbeddedType(IStructuredModel oldModel, IStructuredModel newModel) {
		EmbeddedTypeHandler existingEmbeddedType = getEmbeddedType(oldModel);
		EmbeddedTypeHandler newEmbeddedContentType = existingEmbeddedType.newInstance();
		if (existingEmbeddedType == null) {
			initEmbeddedTypePre(newModel);
			initEmbeddedTypePost(newModel);
		}
		else {
			// initEmbeddedType(newModel);
			initCloneOfEmbeddedType(newModel, existingEmbeddedType, newEmbeddedContentType);
			setLanguageInPageDirective(newModel);
		}
	}

	protected void setLanguageInPageDirective(IStructuredModel newModel) {
		if (newModel instanceof IDOMModel) {
			IDOMDocument document = ((IDOMModel) newModel).getDocument();
			PageDirectiveAdapter pageDirectiveAdapter = (PageDirectiveAdapter) document.getAdapterFor(PageDirectiveAdapter.class);
			String language = getLanguage(newModel);
			pageDirectiveAdapter.setLanguage(language);
		}
	}

	public IStructuredModel reinitialize(IStructuredModel model) {
		EmbeddedTypeHandler oldHandler = null;
		EmbeddedTypeHandler newHandler = null;
		Object reinitStateData = model.getReinitializeStateData();
		if (reinitStateData instanceof EmbeddedTypeStateData) {
			EmbeddedTypeStateData oldStateData = (EmbeddedTypeStateData) reinitStateData;
			oldHandler = oldStateData.getOldHandler();
			newHandler = oldStateData.getNewHandler();
			// note. We should already have the new handler in the model's
			// (documents) adapters,
			// so need need to use the old one to undo the old state data
			reInitializeEmbeddedType(model, oldHandler, newHandler);
		}
		else {
			// for language ... we someday MIGHT have to do something
			// here, but for now, we don't have any model-side language
			// sensitive adapters.
		}
		return super.reinitialize(model);
	}

	public IModelLoader newInstance() {
		return new JSPModelLoader();
	}

	public IDocumentLoader getDocumentLoader() {
		if (documentLoaderInstance == null) {
			documentLoaderInstance = new JSPDocumentLoader();
		}
		return documentLoaderInstance;
	}

	/**
	 * Ensures that an InputStream has mark/reset support.
	 */
	public static InputStream getMarkSupportedStream(InputStream original) {
		if (original == null)
			return null;
		if (original.markSupported())
			return original;
		return new BufferedInputStream(original);
	}

	protected byte[] getBytes(InputStream inputStream, int max) throws IOException {
		byte[] smallBuffer = new byte[max];
		byte[] returnBuffer = null;
		int nRead = inputStream.read(smallBuffer, 0, max);
		if (nRead < max) {
			// empty file will return -1;
			if (nRead < 0)
				nRead = 0;
			byte[] smallerBuffer = new byte[nRead];
			System.arraycopy(smallBuffer, 0, smallerBuffer, 0, nRead);
			returnBuffer = smallerBuffer;
		}
		else {
			returnBuffer = smallBuffer;
		}
		return returnBuffer;
	}

	public IStructuredModel createModel(IStructuredModel oldModel) {
		IStructuredModel model = super.createModel(oldModel);
		// For JSPs, the ModelQueryAdapter must be "attached" to the document
		// before content is set in the model, so taglib initization can
		// take place.
		// In this "clone model" case, we create a ModelQuery adapter
		// create a new instance from the old data. Note: I think this
		// "forced fit" only works here since the implimentaiton of
		// ModelQueryAdatper does not
		// have to be released.

		ModelQueryAdapter modelQueryAdapter = getModelQueryAdapter(model);
		if (modelQueryAdapter == null) {
			modelQueryAdapter = getModelQueryAdapter(oldModel);
			IDOMDocument document = ((IDOMModel) model).getDocument();
			document.addAdapter(new JSPModelQueryAdapterImpl(modelQueryAdapter.getCMDocumentCache(), modelQueryAdapter.getModelQuery(), modelQueryAdapter.getIdResolver()));

		}



		return model;
	}

	private ModelQueryAdapter getModelQueryAdapter(IStructuredModel model) {
		IDOMDocument document = ((IDOMModel) model).getDocument();

		ModelQueryAdapter modelQueryAdapter = (ModelQueryAdapter) ((INodeNotifier) document).getAdapterFor(ModelQueryAdapter.class);
		return modelQueryAdapter;
	}

}
