/*******************************************************************************
 * 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.xml.core.internal.document;

import org.eclipse.wst.sse.core.internal.model.AbstractStructuredModel;
import org.eclipse.wst.sse.core.internal.provisional.IndexedRegion;
import org.eclipse.wst.sse.core.internal.provisional.events.IStructuredDocumentListener;
import org.eclipse.wst.sse.core.internal.provisional.events.NewDocumentEvent;
import org.eclipse.wst.sse.core.internal.provisional.events.NoChangeEvent;
import org.eclipse.wst.sse.core.internal.provisional.events.RegionChangedEvent;
import org.eclipse.wst.sse.core.internal.provisional.events.RegionsReplacedEvent;
import org.eclipse.wst.sse.core.internal.provisional.events.StructuredDocumentRegionsReplacedEvent;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegionList;
import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion;
import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionList;
import org.eclipse.wst.xml.core.internal.Logger;
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.provisional.document.IDOMNode;
import org.eclipse.wst.xml.core.internal.provisional.document.ISourceGenerator;
import org.w3c.dom.Attr;
import org.w3c.dom.DOMException;
import org.w3c.dom.DOMImplementation;
import org.w3c.dom.Document;
import org.w3c.dom.DocumentType;
import org.w3c.dom.Element;
import org.w3c.dom.Node;


/**
 * XMLModelImpl class
 */
public class DOMModelImpl extends AbstractStructuredModel implements IStructuredDocumentListener, IDOMModel, DOMImplementation {
	private static String TRACE_PARSER_MANAGEMENT_EXCEPTION = "parserManagement"; //$NON-NLS-1$
	private Object active = null;
	private DocumentImpl document = null;
	private ISourceGenerator generator = null;
	private XMLModelNotifier notifier = null;
	private XMLModelParser parser = null;
	private boolean refresh = false;
	private XMLModelUpdater updater = null;

	/**
	 * XMLModelImpl constructor
	 */
	public DOMModelImpl() {
		super();
		this.document = (DocumentImpl) internalCreateDocument();
	}

	/**
	 * This API allows clients to declare that they are about to make a
	 * "large" change to the model. This change might be in terms of content
	 * or it might be in terms of the model id or base location.
	 * 
	 * Note that in the case of embedded calls, notification to listners is
	 * sent only once.
	 * 
	 * Note that the client who is making these changes has the responsibility
	 * to restore the models state once finished with the changes. See
	 * getMemento and restoreState.
	 * 
	 * The method isModelStateChanging can be used by a client to determine if
	 * the model is already in a change sequence.
	 */
	public void aboutToChangeModel() {
		super.aboutToChangeModel();
		// technically, no need to call beginChanging so often,
		// since aboutToChangeModel can be nested.
		// but will leave as is for this release.
		// see modelChanged, and be sure stays coordinated there.
		getModelNotifier().beginChanging();
	}

	public void aboutToReinitializeModel() {
		XMLModelNotifier notifier = getModelNotifier();
		notifier.cancelPending();
		super.aboutToReinitializeModel();
	}

	/**
	 * attrReplaced method
	 * 
	 * @param element
	 *            org.w3c.dom.Element
	 * @param newAttr
	 *            org.w3c.dom.Attr
	 * @param oldAttr
	 *            org.w3c.dom.Attr
	 */
	protected void attrReplaced(Element element, Attr newAttr, Attr oldAttr) {
		if (element == null)
			return;
		if (getActiveParser() == null) {
			XMLModelUpdater updater = getModelUpdater();
			setActive(updater);
			updater.initialize();
			updater.replaceAttr(element, newAttr, oldAttr);
			setActive(null);
		}
		getModelNotifier().attrReplaced(element, newAttr, oldAttr);
	}

	/**
	 * This API allows a client controlled way of notifying all ModelEvent
	 * listners that the model has been changed. This method is a matched pair
	 * to aboutToChangeModel, and must be called after aboutToChangeModel ...
	 * or some listeners could be left waiting indefinitely for the changed
	 * event. So, its suggested that changedModel always be in a finally
	 * clause. Likewise, a client should never call changedModel without
	 * calling aboutToChangeModel first.
	 * 
	 * In the case of embedded calls, the notification is just sent once.
	 * 
	 */
	public void changedModel() {
		// NOTE: the order of 'changedModel' and 'endChanging' is significant.
		// By calling changedModel first, this basically decrements the
		// "isChanging" counter
		// in super class and when zero all listeners to model state events
		// will be notified
		// that the model has been changed. 'endChanging' will notify all
		// deferred adapters.
		// So, the significance of order is that adapters (and methods they
		// call)
		// can count on the state of model "isChanging" to be accurate.
		// But, remember, that this means the "modelChanged" event can be
		// received before all
		// adapters have finished their processing.
		// NOTE NOTE: The above note is obsolete in fact (though still states
		// issue correctly).
		// Due to popular demand, the order of these calls were reversed and
		// behavior
		// changed on 07/22/2004.
		// 
		// see also
		// https://w3.opensource.ibm.com/bugzilla/show_bug.cgi?id=4302
		// for motivation for this 'on verge of' call.
		// this could be improved in future if notifier also used counting
		// flag to avoid nested calls. If/when changed be sure to check if
		// aboutToChangeModel needs any changes too.
		if (isModelChangeStateOnVergeOfEnding()) {
			// end lock before noticiation loop, since directly or indirectly
			// we may be "called from foriegn code" during notification.
			endLock();

			// the notifier is what controls adaper notification, which
			// should be sent out before the 'modelChanged' event.
			getModelNotifier().endChanging();
		}
		// changedModel handles 'nesting', so only one event sent out
		// when mulitple calls to 'aboutToChange/Changed'.
		super.changedModel();
		handleRefresh();
	}

	/**
	 * childReplaced method
	 * 
	 * @param parentNode
	 *            org.w3c.dom.Node
	 * @param newChild
	 *            org.w3c.dom.Node
	 * @param oldChild
	 *            org.w3c.dom.Node
	 */
	protected void childReplaced(Node parentNode, Node newChild, Node oldChild) {
		if (parentNode == null)
			return;
		if (getActiveParser() == null) {
			XMLModelUpdater updater = getModelUpdater();
			setActive(updater);
			updater.initialize();
			updater.replaceChild(parentNode, newChild, oldChild);
			setActive(null);
		}
		getModelNotifier().childReplaced(parentNode, newChild, oldChild);
	}

	/**
	 * Creates an XML <code>Document</code> object of the specified type
	 * with its document element. HTML-only DOM implementations do not need to
	 * implement this method.
	 * 
	 * @param namespaceURIThe
	 *            namespace URI of the document element to create.
	 * @param qualifiedNameThe
	 *            qualified name of the document element to be created.
	 * @param doctypeThe
	 *            type of document to be created or <code>null</code>. When
	 *            <code>doctype</code> is not <code>null</code>, its
	 *            <code>Node.ownerDocument</code> attribute is set to the
	 *            document being created.
	 * @return A new <code>Document</code> object.
	 * @exception DOMException
	 *                INVALID_CHARACTER_ERR: Raised if the specified qualified
	 *                name contains an illegal character. <br>
	 *                NAMESPACE_ERR: Raised if the <code>qualifiedName</code>
	 *                is malformed, if the <code>qualifiedName</code> has a
	 *                prefix and the <code>namespaceURI</code> is
	 *                <code>null</code>, or if the
	 *                <code>qualifiedName</code> has a prefix that is "xml"
	 *                and the <code>namespaceURI</code> is different from "
	 *                http://www.w3.org/XML/1998/namespace" .<br>
	 *                WRONG_DOCUMENT_ERR: Raised if <code>doctype</code> has
	 *                already been used with a different document or was
	 *                created from a different implementation.
	 * @since DOM Level 2
	 */
	public Document createDocument(String namespaceURI, String qualifiedName, DocumentType doctype) throws DOMException {
		return null;
	}

	/**
	 * Creates an empty <code>DocumentType</code> node. Entity declarations
	 * and notations are not made available. Entity reference expansions and
	 * default attribute additions do not occur. It is expected that a future
	 * version of the DOM will provide a way for populating a
	 * <code>DocumentType</code>.<br>
	 * HTML-only DOM implementations do not need to implement this method.
	 * 
	 * @param qualifiedNameThe
	 *            qualified name of the document type to be created.
	 * @param publicIdThe
	 *            external subset public identifier.
	 * @param systemIdThe
	 *            external subset system identifier.
	 * @return A new <code>DocumentType</code> node with
	 *         <code>Node.ownerDocument</code> set to <code>null</code>.
	 * @exception DOMException
	 *                INVALID_CHARACTER_ERR: Raised if the specified qualified
	 *                name contains an illegal character. <br>
	 *                NAMESPACE_ERR: Raised if the <code>qualifiedName</code>
	 *                is malformed.
	 * @since DOM Level 2
	 */
	public DocumentType createDocumentType(String qualifiedName, String publicId, String systemId) throws DOMException {
		DocumentTypeImpl documentType = new DocumentTypeImpl();
		documentType.setName(qualifiedName);
		documentType.setPublicId(publicId);
		documentType.setSystemId(systemId);
		return documentType;
	}

	/**
	 */
	protected void documentTypeChanged() {
		if (this.refresh)
			return;
		// unlike 'resfresh', 'reinitialize' finishes loop
		// and flushes remaining notification que before
		// actually reinitializing.
		// ISSUE: should reinit be used instead of handlerefresh?
		// this.setReinitializeNeeded(true);
		if (this.active != null || getModelNotifier().isChanging())
			return; // defer
		handleRefresh();
	}

	protected void editableChanged(Node node) {
		if (node != null) {
			getModelNotifier().editableChanged(node);
		}
	}

	/**
	 */
	protected void endTagChanged(Element element) {
		if (element == null)
			return;
		if (getActiveParser() == null) {
			XMLModelUpdater updater = getModelUpdater();
			setActive(updater);
			updater.initialize();
			updater.changeEndTag(element);
			setActive(null);
		}
		getModelNotifier().endTagChanged(element);
	}

	/**
	 */
	private XMLModelParser getActiveParser() {
		if (this.parser == null)
			return null;
		if (this.parser != this.active)
			return null;
		return this.parser;
	}

	/**
	 */
	private XMLModelUpdater getActiveUpdater() {
		if (this.updater == null)
			return null;
		if (this.updater != this.active)
			return null;
		return this.updater;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
	 */
	public Object getAdapter(Class adapter) {
		if (Document.class.equals(adapter))
			return getDocument();
		return super.getAdapter(adapter);
	}

	/**
	 * getDocument method
	 * 
	 * @return XMLDocument
	 */
	public IDOMDocument getDocument() {
		return this.document;
	}

	public ISourceGenerator getGenerator() {
		if (this.generator == null) {
			this.generator = XMLGeneratorImpl.getInstance();
		}
		return this.generator;
	}

	/**
	 * getNode method
	 * 
	 * @param offset
	 *            int
	 */
	public IndexedRegion getIndexedRegion(int offset) {
		if (this.document == null)
			return null;
		// search in document children
		IDOMNode parent = null;
		int length = this.document.getEndOffset();
		if (offset * 2 < length) {
			// search from the first
			IDOMNode child = (IDOMNode) this.document.getFirstChild();
			while (child != null) {
				if (child.getEndOffset() <= offset) {
					child = (IDOMNode) child.getNextSibling();
					continue;
				}
				if (child.getStartOffset() > offset) {
					break;
				}
				IStructuredDocumentRegion startStructuredDocumentRegion = child.getStartStructuredDocumentRegion();
				if (startStructuredDocumentRegion != null) {
					if (startStructuredDocumentRegion.getEnd() > offset)
						return child;
				}
				IStructuredDocumentRegion endStructuredDocumentRegion = child.getEndStructuredDocumentRegion();
				if (endStructuredDocumentRegion != null) {
					if (endStructuredDocumentRegion.getStart() <= offset)
						return child;
				}
				// dig more
				parent = child;
				child = (IDOMNode) parent.getFirstChild();
			}
		}
		else {
			// search from the last
			IDOMNode child = (IDOMNode) this.document.getLastChild();
			while (child != null) {
				if (child.getStartOffset() > offset) {
					child = (IDOMNode) child.getPreviousSibling();
					continue;
				}
				if (child.getEndOffset() <= offset) {
					break;
				}
				IStructuredDocumentRegion startStructuredDocumentRegion = child.getStartStructuredDocumentRegion();
				if (startStructuredDocumentRegion != null) {
					if (startStructuredDocumentRegion.getEnd() > offset)
						return child;
				}
				IStructuredDocumentRegion endStructuredDocumentRegion = child.getEndStructuredDocumentRegion();
				if (endStructuredDocumentRegion != null) {
					if (endStructuredDocumentRegion.getStart() <= offset)
						return child;
				}
				// dig more
				parent = child;
				child = (IDOMNode) parent.getLastChild();
			}
		}
		return parent;
	}

	/**
	 */
	public XMLModelNotifier getModelNotifier() {
		if (this.notifier == null) {
			this.notifier = new XMLModelNotifierImpl();
		}
		return this.notifier;
	}

	/**
	 */
	private XMLModelParser getModelParser() {
		if (this.parser == null) {
			this.parser = createModelParser();
		}
		return this.parser;
	}

	protected XMLModelParser createModelParser() {
		return new XMLModelParser(this);
	}

	/**
	 */
	private XMLModelUpdater getModelUpdater() {
		if (this.updater == null) {
			this.updater = createModelUpdater();
		}
		return this.updater;
	}

	protected XMLModelUpdater createModelUpdater() {
		return new XMLModelUpdater(this);
	}

	/**
	 */
	private void handleRefresh() {
		if (!this.refresh)
			return;
		XMLModelNotifier notifier = getModelNotifier();
		boolean isChanging = notifier.isChanging();
		if (!isChanging)
			notifier.beginChanging(true);
		XMLModelParser parser = getModelParser();
		setActive(parser);
		this.document.removeChildNodes();
		try {
			parser.replaceStructuredDocumentRegions(getStructuredDocument().getRegionList(), null);
		}
		catch (Exception ex) {
			Logger.logException(ex);
		}
		finally {
			setActive(null);
			if (!isChanging)
				notifier.endChanging();
			this.refresh = false;
		}
	}

	/**
	 * Test if the DOM implementation implements a specific feature.
	 * 
	 * @param featureThe
	 *            name of the feature to test (case-insensitive). The values
	 *            used by DOM features are defined throughout the DOM Level 2
	 *            specifications and listed in the section. The name must be
	 *            an XML name. To avoid possible conflicts, as a convention,
	 *            names referring to features defined outside the DOM
	 *            specification should be made unique by reversing the name of
	 *            the Internet domain name of the person (or the organization
	 *            that the person belongs to) who defines the feature,
	 *            component by component, and using this as a prefix. For
	 *            instance, the W3C SVG Working Group defines the feature
	 *            "org.w3c.dom.svg".
	 * @param versionThis
	 *            is the version number of the feature to test. In Level 2,
	 *            the string can be either "2.0" or "1.0". If the version is
	 *            not specified, supporting any version of the feature causes
	 *            the method to return <code>true</code>.
	 * @return <code>true</code> if the feature is implemented in the
	 *         specified version, <code>false</code> otherwise.
	 */
	public boolean hasFeature(String feature, String version) {
		if (feature == null)
			return false;
		if (version != null) {
			if (!version.equals("1.0") && !version.equals("2.0")) { //$NON-NLS-2$//$NON-NLS-1$
				return false;
			}
		}
		if (feature.equalsIgnoreCase("Core")) //$NON-NLS-1$
			return true; //$NON-NLS-1$
		if (feature.equalsIgnoreCase("XML")) //$NON-NLS-1$
			return true; //$NON-NLS-1$
		return false;
	}

	/**
	 * createDocument method
	 * 
	 * @return org.w3c.dom.Document
	 */
	protected Document internalCreateDocument() {
		DocumentImpl document = new DocumentImpl();
		document.setModel(this);
		return document;
	}

	boolean isReparsing() {
		return (active != null);
	}

	/**
	 * nameChanged method
	 * 
	 * @param node
	 *            org.w3c.dom.Node
	 */
	protected void nameChanged(Node node) {
		if (node == null)
			return;
		if (getActiveParser() == null) {
			XMLModelUpdater updater = getModelUpdater();
			setActive(updater);
			updater.initialize();
			updater.changeName(node);
			setActive(null);
		}
		// notification is already sent
	}

	/**
	 * newModel method
	 * 
	 * @param structuredDocumentEvent
	 *            com.ibm.sed.structuredDocument.impl.events.NewModelEvent
	 */
	public void newModel(NewDocumentEvent structuredDocumentEvent) {
		if (structuredDocumentEvent == null)
			return;
		IStructuredDocument structuredDocument = structuredDocumentEvent.getStructuredDocument();
		if (structuredDocument == null)
			return;
		// this should not happen, but for the case
		if (structuredDocument != getStructuredDocument())
			setStructuredDocument(structuredDocument);
		IStructuredDocumentRegionList flatNodes = structuredDocument.getRegionList();
		if ((flatNodes == null) || (flatNodes.getLength() == 0)) {
			return;
		}
		if (this.document == null)
			return; // being constructed
		XMLModelUpdater updater = getActiveUpdater();
		if (updater != null) { // being updated
			try {
				updater.replaceStructuredDocumentRegions(flatNodes, null);
			}
			catch (Exception ex) {
				Logger.logException(ex);
				this.refresh = true;
				handleRefresh();
			}
			finally {
				setActive(null);
			}
			// // for new model, we might need to
			// // re-init, e.g. if someone calls setText
			// // on an existing model
			// checkForReinit();
			return;
		}
		XMLModelNotifier notifier = getModelNotifier();
		boolean isChanging = notifier.isChanging();
		// call even if changing to notify doing new model
		getModelNotifier().beginChanging(true);
		XMLModelParser parser = getModelParser();
		setActive(parser);
		this.document.removeChildNodes();
		try {
			parser.replaceStructuredDocumentRegions(flatNodes, null);
		}
		catch (Exception ex) {
			Logger.logException(ex);
			// meaningless to refresh, because the result might be the same
		}
		finally {
			setActive(null);
			if (!isChanging) {
				getModelNotifier().endChanging();
			}
			// ignore refresh
			this.refresh = false;
		}
		// checkForReinit();
	}

	/**
	 */
	public void noChange(NoChangeEvent event) {
		XMLModelUpdater updater = getActiveUpdater();
		if (updater != null) { // being updated
			// cleanup updater staffs
			try {
				updater.replaceStructuredDocumentRegions(null, null);
			}
			catch (Exception ex) {
				Logger.logException(ex);
				this.refresh = true;
				handleRefresh();
			}
			finally {
				setActive(null);
			}
			// I guess no chanage means the model could not need re-init
			// checkForReinit();
			return;
		}
	}

	/**
	 * nodesReplaced method
	 * 
	 * @param event
	 *            com.ibm.sed.structuredDocument.impl.events.NodesReplacedElement
	 */
	public void nodesReplaced(StructuredDocumentRegionsReplacedEvent event) {
		if (event == null)
			return;
		IStructuredDocumentRegionList oldStructuredDocumentRegions = event.getOldStructuredDocumentRegions();
		IStructuredDocumentRegionList newStructuredDocumentRegions = event.getNewStructuredDocumentRegions();
		XMLModelUpdater updater = getActiveUpdater();
		if (updater != null) { // being updated
			try {
				updater.replaceStructuredDocumentRegions(newStructuredDocumentRegions, oldStructuredDocumentRegions);
			}
			catch (Exception ex) {
				if (ex.getClass().equals(StructuredDocumentRegionManagementException.class)) {
					Logger.traceException(TRACE_PARSER_MANAGEMENT_EXCEPTION, ex);
				}
				else {
					Logger.logException(ex);
				}
				this.refresh = true;
				handleRefresh();
			}
			finally {
				setActive(null);
			}
			// checkForReinit();
			return;
		}
		XMLModelNotifier notifier = getModelNotifier();
		boolean isChanging = notifier.isChanging();
		if (!isChanging)
			notifier.beginChanging();
		XMLModelParser parser = getModelParser();
		setActive(parser);
		try {
			parser.replaceStructuredDocumentRegions(newStructuredDocumentRegions, oldStructuredDocumentRegions);
		}
		catch (Exception ex) {
			Logger.logException(ex);
			this.refresh = true;
			handleRefresh();
		}
		finally {
			setActive(null);
			if (!isChanging) {
				notifier.endChanging();
				handleRefresh();
			}
		}

	}

	/**
	 * regionChanged method
	 * 
	 * @param structuredDocumentEvent
	 *            com.ibm.sed.structuredDocument.impl.events.RegionChangedEvent
	 */
	public void regionChanged(RegionChangedEvent event) {
		if (event == null)
			return;
		IStructuredDocumentRegion flatNode = event.getStructuredDocumentRegion();
		if (flatNode == null)
			return;
		ITextRegion region = event.getRegion();
		if (region == null)
			return;
		XMLModelUpdater updater = getActiveUpdater();
		if (updater != null) { // being updated
			try {
				updater.changeRegion(flatNode, region);
			}
			catch (Exception ex) {
				Logger.logException(ex);
				this.refresh = true;
				handleRefresh();
			}
			finally {
				setActive(null);
			}
			// checkForReinit();
			return;
		}
		XMLModelNotifier notifier = getModelNotifier();
		boolean isChanging = notifier.isChanging();
		if (!isChanging)
			notifier.beginChanging();
		XMLModelParser parser = getModelParser();
		setActive(parser);
		try {
			parser.changeRegion(flatNode, region);
		}
		catch (Exception ex) {
			Logger.logException(ex);
			this.refresh = true;
			handleRefresh();
		}
		finally {
			setActive(null);
			if (!isChanging) {
				notifier.endChanging();
				handleRefresh();
			}
		}
		// checkForReinit();
	}

	/**
	 * regionsReplaced method
	 * 
	 * @param event
	 *            com.ibm.sed.structuredDocument.impl.events.RegionReplacedEvent
	 */
	public void regionsReplaced(RegionsReplacedEvent event) {
		if (event == null)
			return;
		IStructuredDocumentRegion flatNode = event.getStructuredDocumentRegion();
		if (flatNode == null)
			return;
		ITextRegionList oldRegions = event.getOldRegions();
		ITextRegionList newRegions = event.getNewRegions();
		if (oldRegions == null && newRegions == null)
			return;
		XMLModelUpdater updater = getActiveUpdater();
		if (updater != null) { // being updated
			try {
				updater.replaceRegions(flatNode, newRegions, oldRegions);
			}
			catch (Exception ex) {
				Logger.logException(ex);
				this.refresh = true;
				handleRefresh();
			}
			finally {
				setActive(null);
			}
			// checkForReinit();
			return;
		}
		XMLModelNotifier notifier = getModelNotifier();
		boolean isChanging = notifier.isChanging();
		if (!isChanging)
			notifier.beginChanging();
		XMLModelParser parser = getModelParser();
		setActive(parser);
		try {
			parser.replaceRegions(flatNode, newRegions, oldRegions);
		}
		catch (Exception ex) {
			Logger.logException(ex);
			this.refresh = true;
			handleRefresh();
		}
		finally {
			setActive(null);
			if (!isChanging) {
				notifier.endChanging();
				handleRefresh();
			}
		}
		// checkForReinit();
	}

	/**
	 */
	public void releaseFromEdit() {
		if (!isShared()) {
			// this.document.releaseStyleSheets();
			this.document.releaseDocumentType();
		}
		super.releaseFromEdit();
	}

	/**
	 */
	public void releaseFromRead() {
		if (!isShared()) {
			// this.document.releaseStyleSheets();
			this.document.releaseDocumentType();
		}
		super.releaseFromRead();
	}

	/**
	 */
	private void setActive(Object active) {
		this.active = active;
		// side effect
		// when ever becomes active, besure tagNameCache is cleared
		// (and not used)
		if (active == null) {
			document.activateTagNameCache(true);
		}
		else {
			document.activateTagNameCache(false);
		}

	}

	/**
	 */
	public void setGenerator(ISourceGenerator generator) {
		this.generator = generator;
	}

	/**
	 */
	public void setModelNotifier(XMLModelNotifier notifier) {
		this.notifier = notifier;
	}

	/**
	 */
	public void setModelParser(XMLModelParser parser) {
		this.parser = parser;
	}

	/**
	 */
	public void setModelUpdater(XMLModelUpdater updater) {
		this.updater = updater;
	}

	/**
	 * setStructuredDocument method
	 * 
	 * @param structuredDocument
	 *            com.ibm.sed.structuredDocument.IStructuredDocument
	 */
	public void setStructuredDocument(IStructuredDocument structuredDocument) {
		IStructuredDocument oldStructuredDocument = super.getStructuredDocument();
		if (structuredDocument == oldStructuredDocument)
			return; // nothing to do
		if (oldStructuredDocument != null)
			oldStructuredDocument.removeDocumentChangingListener(this);
		super.setStructuredDocument(structuredDocument);
		if (structuredDocument.getLength() > 0) {
			newModel(new NewDocumentEvent(structuredDocument, this));
		}
		if (structuredDocument != null)
			structuredDocument.addDocumentChangingListener(this);
	}

	/**
	 */
	protected void startTagChanged(Element element) {
		if (element == null)
			return;
		if (getActiveParser() == null) {
			XMLModelUpdater updater = getModelUpdater();
			setActive(updater);
			updater.initialize();
			updater.changeStartTag(element);
			setActive(null);
		}
		getModelNotifier().startTagChanged(element);
	}

	/**
	 * valueChanged method
	 * 
	 * @param node
	 *            org.w3c.dom.Node
	 */
	protected void valueChanged(Node node) {
		if (node == null)
			return;
		if (getActiveParser() == null) {
			XMLModelUpdater updater = getModelUpdater();
			setActive(updater);
			updater.initialize();
			updater.changeValue(node);
			setActive(null);
		}
		getModelNotifier().valueChanged(node);
	}

	/**
	 * NOT IMPLEMENTED. Is defined here in preparation of DOM 3.
	 */
	public Object getFeature(String feature, String version) {
		throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Not implemented in this version."); //$NON-NLS-1$
	}
}
