/*******************************************************************************
 * 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.AbstractStructuredModel;
import org.eclipse.wst.sse.core.IndexedRegion;
import org.eclipse.wst.sse.core.events.IStructuredDocumentListener;
import org.eclipse.wst.sse.core.events.NewDocumentEvent;
import org.eclipse.wst.sse.core.events.NoChangeEvent;
import org.eclipse.wst.sse.core.events.RegionChangedEvent;
import org.eclipse.wst.sse.core.events.RegionsReplacedEvent;
import org.eclipse.wst.sse.core.events.StructuredDocumentRegionsReplacedEvent;
import org.eclipse.wst.sse.core.text.IStructuredDocument;
import org.eclipse.wst.sse.core.text.IStructuredDocumentRegion;
import org.eclipse.wst.sse.core.text.IStructuredDocumentRegionList;
import org.eclipse.wst.sse.core.text.ITextRegion;
import org.eclipse.wst.sse.core.text.ITextRegionList;
import org.eclipse.wst.xml.core.document.XMLDocument;
import org.eclipse.wst.xml.core.document.XMLGenerator;
import org.eclipse.wst.xml.core.document.XMLModel;
import org.eclipse.wst.xml.core.document.XMLModelNotifier;
import org.eclipse.wst.xml.core.document.XMLNode;
import org.eclipse.wst.xml.core.internal.Logger;
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 XMLModelImpl extends AbstractStructuredModel implements IStructuredDocumentListener, XMLModel, DOMImplementation {
	private static String TRACE_PARSER_MANAGEMENT_EXCEPTION = "parserManagement"; //$NON-NLS-1$
	private Object active = null;
	private DocumentImpl document = null;
	private XMLGenerator generator = null;
	private XMLModelNotifier notifier = null;
	private XMLModelParser parser = null;
	private boolean refresh = false;
	private XMLModelUpdater updater = null;

	/**
	 * XMLModelImpl constructor
	 */
	public XMLModelImpl() {
		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 XMLDocument getDocument() {
		return this.document;
	}

	public XMLGenerator 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
		XMLNode parent = null;
		int length = this.document.getEndOffset();
		if (offset * 2 < length) {
			// search from the first
			XMLNode child = (XMLNode) this.document.getFirstChild();
			while (child != null) {
				if (child.getEndOffset() <= offset) {
					child = (XMLNode) 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 = (XMLNode) parent.getFirstChild();
			}
		} else {
			// search from the last
			XMLNode child = (XMLNode) this.document.getLastChild();
			while (child != null) {
				if (child.getStartOffset() > offset) {
					child = (XMLNode) 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 = (XMLNode) 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)
			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(XMLGenerator 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);
	}
}
