/*******************************************************************************
 * 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.Logger;
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.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;
	protected 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.
		// FUTURE: perhaps all "handleRefresh" should be changed
		// to "reinit needede"?
		this.setReinitializeNeeded(true);
	}

	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 = new XMLModelParser(this);
		}
		return this.parser;
	}

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

	/**
	 */
	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);
	}
}
