/*******************************************************************************
 * 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 java.util.Enumeration;
import java.util.Iterator;

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.JSPTag;
import org.eclipse.wst.xml.core.document.XMLElement;
import org.eclipse.wst.xml.core.document.XMLGenerator;
import org.eclipse.wst.xml.core.document.XMLNode;
import org.eclipse.wst.xml.core.parser.XMLRegionContext;
import org.w3c.dom.Attr;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.Text;


/**
 * XMLModelUpdater class
 */
public class XMLModelUpdater {
	private int diff = 0;
	private int gapLength = 0;
	private int gapOffset = 0;
	private IStructuredDocumentRegion gapStructuredDocumentRegion = null;
	private XMLGenerator generator = null;
	private XMLModelImpl model = null;
	private NodeImpl nextNode = null;
	private NodeImpl parentNode = null;

	protected XMLModelUpdater(XMLModelImpl model) {
		super();

		if (model != null) {
			this.model = model;
			this.generator = model.getGenerator();
		}
	}

	/**
	 * changeAttrValue method
	 * 
	 * @param attrNode
	 *            org.w3c.dom.Attr
	 */
	private void changeAttrName(Attr attrNode) {
		if (attrNode == null)
			return;

		AttrImpl attr = (AttrImpl) attrNode;
		ElementImpl element = (ElementImpl) attr.getOwnerElement();
		if (element == null)
			return;

		if (element.isCommentTag()) {
			changeStartTag(element);
			return;
		}

		int offset = element.getStartOffset();
		int start = offset;
		int end = offset;

		String name = attr.getName();
		if (name == null)
			name = new String();
		ITextRegion nameRegion = attr.getNameRegion();
		if (nameRegion == null)
			return; // error
		start += nameRegion.getStart();
		// use getTextEnd() because getEnd() may include the tailing spaces
		end += nameRegion.getTextEnd();

		replaceSource(name, start, end);
	}

	/**
	 * changeAttrValue method
	 * 
	 * @param attrNode
	 *            org.w3c.dom.Attr
	 */
	private void changeAttrValue(Attr attrNode) {
		if (attrNode == null)
			return;

		AttrImpl attr = (AttrImpl) attrNode;
		ElementImpl element = (ElementImpl) attr.getOwnerElement();
		if (element == null)
			return;

		if (element.isCommentTag()) {
			changeStartTag(element);
			return;
		}

		int offset = element.getStartOffset();
		int start = offset;
		int end = offset;

		String value = null;
		ITextRegion valueRegion = attr.getValueRegion();
		if (valueRegion != null) {
			char quote = 0; // no quote preference
			// DW: 4/16/2003 due to change in structuredDocument ... we need a
			// flatnode to
			// get at region values. For now I'll assume this is always the
			// first
			// flatnode .. may need to make smarter later (e.g. to search for
			// the flatnode that this.valueRegion belongs to.
			IStructuredDocumentRegion documentRegion = element.getFirstStructuredDocumentRegion();
			String oldValue = documentRegion.getText(valueRegion);
			if (oldValue != null && oldValue.length() > 0) {
				char firstChar = oldValue.charAt(0);
				if (firstChar == '"' || firstChar == '\'') {
					quote = firstChar;
				}
			}

			ITextRegion startRegion = valueRegion;

			value = this.generator.generateAttrValue(attr, quote);
			if (value == null) {
				value = new String();
				// remove equal too
				ITextRegion equalRegion = attr.getEqualRegion();
				if (equalRegion != null)
					startRegion = equalRegion;
			}
			attr.setValueRegion(valueRegion); // reset value

			start += startRegion.getStart();
			// use getTextEnd() because getEnd() may include the tailing
			// spaces
			end += valueRegion.getTextEnd();
		}
		else {
			ITextRegion equalRegion = attr.getEqualRegion();

			value = this.generator.generateAttrValue(attr);
			if (value == null) {
				if (equalRegion == null)
					return; // nothng to do
				value = new String();
				// remove equal
				start += equalRegion.getStart();
				end += equalRegion.getTextEnd();
			}
			else {
				if (equalRegion != null) {
					// use getTextEnd() because getEnd() may include the
					// tailing spaces
					start += equalRegion.getTextEnd();
				}
				else {
					ITextRegion nameRegion = attr.getNameRegion();
					if (nameRegion == null)
						return; // must never happen
					// use getTextEnd() because getEnd() may include the
					// tailing spaces
					start += nameRegion.getTextEnd();
					value = '=' + value;
				}
				end = start;
			}
		}

		replaceSource(value, start, end);
	}

	/**
	 */
	void changeEndTag(Element element) {
		String source = this.generator.generateEndTag(element);
		if (source == null)
			return;
		int length = source.length();
		if (length == 0)
			return;

		ElementImpl impl = (ElementImpl) element;
		int offset = impl.getEndStartOffset();
		int start = offset;
		int end = offset;
		if (impl.hasEndTag()) {
			end = impl.getEndOffset();
			this.gapStructuredDocumentRegion = impl.getEndStructuredDocumentRegion();
			impl.setEndStructuredDocumentRegion(new StructuredDocumentRegionProxy(offset, length));
		}

		replaceSource(source, start, end);
	}

	/**
	 * changeName method
	 * 
	 * @param node
	 *            org.w3c.dom.Node
	 */
	void changeName(Node node) {
		if (node == null)
			return;
		if (getStructuredDocument() == null)
			return;

		// support changing name of attribute for setPrefix()
		short nodeType = node.getNodeType();
		if (nodeType == Node.ATTRIBUTE_NODE) {
			changeAttrName((Attr) node);
			return;
		}

		// not supported
		return;
	}

	void changeRegion(IStructuredDocumentRegion flatNode, ITextRegion region) {
		// future_TODO: optimize

		NodeImpl root = (NodeImpl) this.model.getDocument();
		this.parentNode = root;
		this.nextNode = (NodeImpl) root.getFirstChild();

		removeGapStructuredDocumentRegion(flatNode);
		insertGapStructuredDocumentRegionBefore(flatNode.getStart());
		changeStructuredDocumentRegion(flatNode);
		insertGapStructuredDocumentRegionAfter(flatNode.getEnd());
	}

	/**
	 * This is a fallback method to regenerate the start tag.
	 */
	void changeStartTag(Element element) {
		if (element == null)
			return;
		ElementImpl impl = (ElementImpl) element;

		if (!impl.hasStartTag() && !impl.hasEndTag()) {
			// need to generate the start and the end tags
			Node parent = element.getParentNode();
			if (parent != null) {
				replaceChild(parent, element, element);
				return;
			}
			// else error
		}

		String source = this.generator.generateStartTag(element);
		if (source == null)
			return;
		int length = source.length();
		if (length == 0)
			return;

		int offset = impl.getStartOffset();
		int start = offset;
		int end = offset;
		if (impl.hasStartTag()) {
			end = impl.getStartEndOffset();
			this.gapStructuredDocumentRegion = impl.getStartStructuredDocumentRegion();
		}
		impl.setStartStructuredDocumentRegion(new StructuredDocumentRegionProxy(offset, length));

		replaceSource(source, start, end);
	}

	private void changeStructuredDocumentRegion(IStructuredDocumentRegion oldStructuredDocumentRegion) {
		if (oldStructuredDocumentRegion == null)
			return; // error
		if (this.parentNode == null)
			return; // error

		int oldOffset = oldStructuredDocumentRegion.getStart();
		int oldEnd = oldStructuredDocumentRegion.getEnd();
		boolean isEndTag = false;

		// find owner node
		NodeImpl ownerNode = null;
		while (this.parentNode != null) {
			if (this.nextNode != null) {
				IStructuredDocumentRegion nextStructuredDocumentRegion = this.nextNode.getStructuredDocumentRegion();
				if (nextStructuredDocumentRegion != null) {
					if (nextStructuredDocumentRegion == oldStructuredDocumentRegion) {
						ownerNode = this.nextNode;
						break;
					}
					int nextOffset = nextStructuredDocumentRegion.getStart();
					if (nextOffset == oldOffset) { // found
						ownerNode = this.nextNode;
						break;
					}
					if (this.nextNode.getNodeType() == Node.TEXT_NODE) {
						TextImpl text = (TextImpl) this.nextNode;
						if (text.hasStructuredDocumentRegion(oldStructuredDocumentRegion)) {
							ownerNode = this.nextNode;
							break;
						}
						int nextEnd = nextStructuredDocumentRegion.getEnd();
						if (nextOffset < oldEnd && nextEnd > oldOffset) {
							ownerNode = this.nextNode;
							break;
						}
					}
				}

				Node child = this.nextNode.getFirstChild();
				if (child != null) {
					this.parentNode = this.nextNode;
					this.nextNode = (NodeImpl) child;
					continue;
				}

				if (this.nextNode.getNodeType() == Node.ELEMENT_NODE) {
					this.parentNode = this.nextNode;
					this.nextNode = null;
					continue;
				}

				this.nextNode = (NodeImpl) this.nextNode.getNextSibling();
				if (this.nextNode != null)
					continue;
			}

			if (this.parentNode.getNodeType() == Node.ELEMENT_NODE) {
				ElementImpl element = (ElementImpl) this.parentNode;
				IStructuredDocumentRegion endStructuredDocumentRegion = element.getEndStructuredDocumentRegion();
				if (endStructuredDocumentRegion != null) {
					if (endStructuredDocumentRegion == oldStructuredDocumentRegion) {
						ownerNode = this.parentNode;
						isEndTag = true;
						break;
					}
					int endOffset = endStructuredDocumentRegion.getStart();
					if (endOffset == oldOffset) { // found
						ownerNode = this.parentNode;
						isEndTag = true;
						break;
					}
				}
			}

			this.nextNode = (NodeImpl) this.parentNode.getNextSibling();
			this.parentNode = (NodeImpl) this.parentNode.getParentNode();
		}
		if (ownerNode == null)
			throw new StructuredDocumentRegionManagementException();

		short nodeType = ownerNode.getNodeType();
		if (nodeType == Node.ELEMENT_NODE) {
			ElementImpl element = (ElementImpl) ownerNode;
			if (isEndTag) {
				element.setEndStructuredDocumentRegion(oldStructuredDocumentRegion);
			}
			else {
				element.setStartStructuredDocumentRegion(oldStructuredDocumentRegion);
				updateAttrRegions(element, oldStructuredDocumentRegion);
			}
		}
		else if (nodeType == Node.TEXT_NODE) {
			TextImpl text = (TextImpl) ownerNode;

			IStructuredDocumentRegion flatNode = text.getStructuredDocumentRegion();
			if (flatNode == oldStructuredDocumentRegion) {
				int newOffset = oldOffset;
				int newEnd = oldEnd;
				if (oldOffset == this.gapOffset) {
					newOffset += this.diff;
				}
				else {
					newEnd = this.gapOffset;
				}
				int newLength = newEnd - newOffset;
				IStructuredDocumentRegion newStructuredDocumentRegion = new StructuredDocumentRegionProxy(newOffset, newLength, oldStructuredDocumentRegion);
				text.setStructuredDocumentRegion(newStructuredDocumentRegion);

				if (oldEnd > newEnd) {
					this.nextNode = (NodeImpl) text.getNextSibling();
					changeStructuredDocumentRegion(oldStructuredDocumentRegion);
				}
				return;
			}

			if (flatNode instanceof StructuredDocumentRegionProxy) {
				StructuredDocumentRegionProxy proxy = (StructuredDocumentRegionProxy) flatNode;
				int offset = proxy.getOffset();
				int end = offset + proxy.getLength();
				if (proxy.getStructuredDocumentRegion() == null) {
					if (offset == oldOffset && end == oldEnd) {
						text.setStructuredDocumentRegion(oldStructuredDocumentRegion);
					}
					else {
						if (end > oldEnd) {
							StructuredDocumentRegionContainer container = new StructuredDocumentRegionContainer();
							container.appendStructuredDocumentRegion(oldStructuredDocumentRegion);
							proxy.setOffset(oldEnd);
							proxy.setLength(end - oldEnd);
							container.appendStructuredDocumentRegion(proxy);
							text.setStructuredDocumentRegion(container);
						}
						else {
							proxy.setStructuredDocumentRegion(oldStructuredDocumentRegion);

							if (end < oldEnd) { // to be shared
								this.nextNode = (NodeImpl) text.getNextSibling();
								changeStructuredDocumentRegion(oldStructuredDocumentRegion);
							}
						}
					}
					return;
				}

				if (offset >= this.gapOffset) {
					proxy.setOffset(offset + this.diff);
					end += this.diff;
				}
				if (end < oldEnd) { // to be shared
					this.nextNode = (NodeImpl) text.getNextSibling();
					changeStructuredDocumentRegion(oldStructuredDocumentRegion);
					return;
				}
			}
			else if (flatNode instanceof StructuredDocumentRegionContainer) {
				StructuredDocumentRegionContainer container = (StructuredDocumentRegionContainer) flatNode;
				int count = container.getStructuredDocumentRegionCount();
				for (int i = 0; i < count; i++) {
					IStructuredDocumentRegion content = container.getStructuredDocumentRegion(i);
					if (content == null)
						continue; // error
					if (content == oldStructuredDocumentRegion) {
						int newOffset = oldOffset;
						int newEnd = oldEnd;
						if (oldOffset == this.gapOffset) {
							newOffset += this.diff;
						}
						else {
							newEnd = this.gapOffset;
						}
						int newLength = newEnd - newOffset;
						IStructuredDocumentRegion newStructuredDocumentRegion = new StructuredDocumentRegionProxy(newOffset, newLength, oldStructuredDocumentRegion);
						container.replaceStructuredDocumentRegion(newStructuredDocumentRegion, i);

						if (oldEnd > newEnd) { // to be shared
							this.nextNode = (NodeImpl) text.getNextSibling();
							changeStructuredDocumentRegion(oldStructuredDocumentRegion);
						}
						return;
					}

					if (content instanceof StructuredDocumentRegionProxy) {
						StructuredDocumentRegionProxy proxy = (StructuredDocumentRegionProxy) content;
						int offset = proxy.getOffset();
						int end = offset + proxy.getLength();
						if (end <= oldOffset)
							continue;
						if (proxy.getStructuredDocumentRegion() == null) {
							if (offset == oldOffset && end == oldEnd) {
								container.replaceStructuredDocumentRegion(oldStructuredDocumentRegion, i);
							}
							else {
								if (end > oldEnd) {
									container.insertStructuredDocumentRegion(oldStructuredDocumentRegion, i);
									proxy.setOffset(oldEnd);
									proxy.setLength(end - oldEnd);
								}
								else {
									proxy.setStructuredDocumentRegion(oldStructuredDocumentRegion);

									if (end < oldEnd) { // to be shared
										this.nextNode = (NodeImpl) text.getNextSibling();
										changeStructuredDocumentRegion(oldStructuredDocumentRegion);
									}
								}
							}
							return;
						}

						if (offset >= this.gapOffset) {
							proxy.setOffset(offset + this.diff);
							end += this.diff;
						}
						if (end < oldEnd) { // to be shared
							this.nextNode = (NodeImpl) text.getNextSibling();
							changeStructuredDocumentRegion(oldStructuredDocumentRegion);
							return;
						}
					}
				}
			}
			else {
				throw new StructuredDocumentRegionManagementException();
			}
		}
		else {
			ownerNode.setStructuredDocumentRegion(oldStructuredDocumentRegion);
		}
	}

	/**
	 */
	private void changeTextData(Text text) {
		if (text == null)
			return;

		String source = this.generator.generateSource(text);
		if (source == null)
			source = new String();
		int length = source.length();

		TextImpl impl = (TextImpl) text;
		int start = impl.getStartOffset();
		int end = impl.getEndOffset();
		int offset = start;

		// make sure previous tag is closed
		Node prev = text.getPreviousSibling();
		if (prev != null) {
			String preTag = getCloseTag((XMLNode) prev);
			if (preTag != null && preTag.length() > 0) {
				offset += preTag.length();
				source = preTag + source;
			}
		}
		else {
			Node parent = text.getParentNode();
			if (parent != null && parent.getNodeType() == Node.ELEMENT_NODE) {
				ElementImpl element = (ElementImpl) parent;
				String preTag = getStartCloseTag(element);
				if (preTag != null && preTag.length() > 0) {
					offset += preTag.length();
					StringBuffer buffer = new StringBuffer();
					buffer.append(preTag);
					buffer.append(source);
					if (text.getNextSibling() == null && !element.hasEndTag() && (element.isJSPContainer() || element.isCDATAContainer())) {
						// need to generate the end tag
						String postTag = this.generator.generateEndTag(element);
						if (postTag != null) {
							int postLength = postTag.length();
							if (postLength > 0) {
								buffer.append(postTag);
								int postOffset = offset + length;
								IStructuredDocumentRegion flatNode = new StructuredDocumentRegionProxy(postOffset, postLength);
								element.setEndStructuredDocumentRegion(flatNode);
							}
						}
					}
					source = buffer.toString();
				}
			}
		}

		this.gapStructuredDocumentRegion = impl.getStructuredDocumentRegion();
		IStructuredDocumentRegion newStructuredDocumentRegion = null;
		if (length > 0)
			newStructuredDocumentRegion = new StructuredDocumentRegionProxy(offset, length);
		impl.setStructuredDocumentRegion(newStructuredDocumentRegion);

		replaceSource(source, start, end);
	}

	/**
	 * changeValue method
	 * 
	 * @param node
	 *            org.w3c.dom.Node
	 */
	void changeValue(Node node) {
		if (node == null)
			return;
		if (getStructuredDocument() == null)
			return;

		short nodeType = node.getNodeType();
		if (nodeType == Node.TEXT_NODE) {
			changeTextData((Text) node);
			return;
		}
		if (nodeType == Node.ATTRIBUTE_NODE) {
			changeAttrValue((Attr) node);
			return;
		}
		if (nodeType == Node.ELEMENT_NODE) {
			changeStartTag((Element) node);
			return;
		}

		String source = this.generator.generateSource(node);
		if (source == null)
			source = new String();
		int length = source.length();

		NodeImpl impl = (NodeImpl) node;
		int start = impl.getStartOffset();
		int end = impl.getEndOffset();

		this.gapStructuredDocumentRegion = impl.getStructuredDocumentRegion();
		IStructuredDocumentRegion flatNode = null;
		if (length > 0)
			flatNode = new StructuredDocumentRegionProxy(start, length);
		impl.setStructuredDocumentRegion(flatNode);

		replaceSource(source, start, end);
	}

	/**
	 */
	private String getAttrValueClose(XMLElement element) {
		if (element == null)
			return null;

		IStructuredDocumentRegion flatNode = element.getStartStructuredDocumentRegion();
		if (flatNode == null)
			return null;
		ITextRegion region = StructuredDocumentRegionUtil.getLastRegion(flatNode);
		if (region == null || region.getType() != XMLRegionContext.XML_TAG_ATTRIBUTE_VALUE)
			return null;
		String value = flatNode.getText(region);
		if (value == null)
			return null;
		int length = value.length();
		if (length == 0)
			return null;

		// check open JSP tag
		boolean closeJSPTag = false;
		int offset = value.indexOf(JSPTag.TAG_OPEN);
		while (offset >= 0) {
			offset = value.indexOf(JSPTag.TAG_CLOSE, offset + 2);
			if (offset < 0) {
				closeJSPTag = true;
				break;
			}
			offset = value.indexOf(JSPTag.TAG_OPEN, offset + 2);
		}

		// check quote
		boolean closeQuote = false;
		char firstChar = value.charAt(0);
		if (firstChar == '"' || firstChar == '\'') {
			if (closeJSPTag || length == 1 || value.charAt(length - 1) != firstChar) {
				closeQuote = true;
			}
		}

		if (!closeJSPTag && !closeQuote)
			return null;

		StringBuffer buffer = new StringBuffer();
		if (closeJSPTag)
			buffer.append(JSPTag.TAG_CLOSE);
		if (closeQuote)
			buffer.append(firstChar);
		return buffer.toString();
	}

	/**
	 * Gather close tags recursively.
	 */
	private String getCloseTag(XMLNode node) {
		if (node == null || node.isClosed())
			return null;

		if (node.getNodeType() != Node.ELEMENT_NODE) {
			return this.generator.generateCloseTag(node);
		}

		ElementImpl element = (ElementImpl) node;
		if (element.hasEndTag()) {
			// end tag is not closed
			return this.generator.generateCloseTag(element);
		}

		// no end tag
		int offset = element.getEndOffset();
		StringBuffer buffer = new StringBuffer();

		XMLNode lastChild = (XMLNode) element.getLastChild();
		if (lastChild == null) {
			if (!element.isStartTagClosed()) {
				if (element.preferEmptyTag())
					element.setEmptyTag(true);
				String closeTag = getStartCloseTag(element);
				if (closeTag != null) {
					int length = closeTag.length();
					if (length > 0) {
						buffer.append(closeTag);
						offset += length;
					}
				}
			}
		}
		else {
			String closeTag = getCloseTag(lastChild);
			if (closeTag != null) {
				int length = closeTag.length();
				if (length > 0) {
					buffer.append(closeTag);
					offset += length;
				}
			}
		}

		String endTag = this.generator.generateEndTag(element);
		if (endTag != null) {
			int length = endTag.length();
			if (length > 0) {
				buffer.append(endTag);
				IStructuredDocumentRegion flatNode = new StructuredDocumentRegionProxy(offset, length);
				element.setEndStructuredDocumentRegion(flatNode);
			}
		}

		return buffer.toString();
	}

	/**
	 */
	private String getStartCloseTag(XMLElement element) {
		if (element == null || element.isStartTagClosed())
			return null;

		StringBuffer buffer = new StringBuffer();
		String attrValueClose = getAttrValueClose(element);
		if (attrValueClose != null)
			buffer.append(attrValueClose);
		String closeTag = this.generator.generateCloseTag(element);
		if (closeTag != null)
			buffer.append(closeTag);
		return buffer.toString();
	}

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

	/**
	 */
	void initialize() {
		this.gapStructuredDocumentRegion = null;
		this.gapOffset = 0;
		this.gapLength = 0;
		this.diff = 0;
		this.parentNode = null;
		this.nextNode = null;
	}

	private void insertGapStructuredDocumentRegionAfter(int endOffset) {
		if (this.gapStructuredDocumentRegion == null)
			return;

		if (this.gapStructuredDocumentRegion instanceof StructuredDocumentRegionProxy) {
			StructuredDocumentRegionProxy proxy = (StructuredDocumentRegionProxy) this.gapStructuredDocumentRegion;
			IStructuredDocumentRegion flatNode = proxy.getStructuredDocumentRegion();
			if (flatNode != null)
				insertStructuredDocumentRegion(flatNode);
		}
		else if (this.gapStructuredDocumentRegion instanceof StructuredDocumentRegionContainer) {
			StructuredDocumentRegionContainer container = (StructuredDocumentRegionContainer) this.gapStructuredDocumentRegion;
			int count = container.getStructuredDocumentRegionCount();
			for (int i = 0; i < count; i++) {
				IStructuredDocumentRegion content = container.getStructuredDocumentRegion(i);
				if (content == null)
					continue;
				if (content.getStart() < endOffset)
					continue;
				if (content instanceof StructuredDocumentRegionProxy) {
					StructuredDocumentRegionProxy proxy = (StructuredDocumentRegionProxy) content;
					IStructuredDocumentRegion flatNode = proxy.getStructuredDocumentRegion();
					if (flatNode != null)
						insertStructuredDocumentRegion(flatNode);
				}
				else {
					insertStructuredDocumentRegion(content);
				}
			}
		}
		else {
			insertStructuredDocumentRegion(this.gapStructuredDocumentRegion);
		}
	}

	private void insertGapStructuredDocumentRegionBefore(int startOffset) {
		if (this.gapStructuredDocumentRegion == null)
			return;

		if (this.gapStructuredDocumentRegion instanceof StructuredDocumentRegionProxy) {
			StructuredDocumentRegionProxy proxy = (StructuredDocumentRegionProxy) this.gapStructuredDocumentRegion;
			IStructuredDocumentRegion flatNode = proxy.getStructuredDocumentRegion();
			if (flatNode != null)
				insertStructuredDocumentRegion(flatNode);
		}
		else if (this.gapStructuredDocumentRegion instanceof StructuredDocumentRegionContainer) {
			StructuredDocumentRegionContainer container = (StructuredDocumentRegionContainer) this.gapStructuredDocumentRegion;
			int count = container.getStructuredDocumentRegionCount();
			for (int i = 0; i < count; i++) {
				IStructuredDocumentRegion content = container.getStructuredDocumentRegion(i);
				if (content == null)
					continue;
				if (content.getStart() >= startOffset)
					return;
				if (content instanceof StructuredDocumentRegionProxy) {
					StructuredDocumentRegionProxy proxy = (StructuredDocumentRegionProxy) content;
					IStructuredDocumentRegion flatNode = proxy.getStructuredDocumentRegion();
					if (flatNode != null)
						insertStructuredDocumentRegion(flatNode);
				}
				else {
					insertStructuredDocumentRegion(content);
				}
			}
		}
		else {
			insertStructuredDocumentRegion(this.gapStructuredDocumentRegion);
		}
	}

	/**
	 */
	private void insertStructuredDocumentRegion(IStructuredDocumentRegion newStructuredDocumentRegion) {
		if (newStructuredDocumentRegion == null)
			return; // error
		if (this.parentNode == null)
			return; // error

		int newOffset = newStructuredDocumentRegion.getStart();
		int newEnd = newStructuredDocumentRegion.getEnd();
		boolean isEndTag = false;

		// find owner node
		NodeImpl ownerNode = null;
		while (this.parentNode != null) {
			if (this.nextNode != null) {
				IStructuredDocumentRegion nextStructuredDocumentRegion = this.nextNode.getStructuredDocumentRegion();
				if (nextStructuredDocumentRegion != null) {
					int nextOffset = nextStructuredDocumentRegion.getStart();
					if (nextOffset == newOffset) { // found
						ownerNode = this.nextNode;
						break;
					}
					if (this.nextNode.getNodeType() == Node.TEXT_NODE) {
						int nextEnd = nextStructuredDocumentRegion.getEnd();
						if (nextOffset < newEnd && nextEnd > newOffset) {
							ownerNode = this.nextNode;
							break;
						}
					}
				}

				Node child = this.nextNode.getFirstChild();
				if (child != null) {
					this.parentNode = this.nextNode;
					this.nextNode = (NodeImpl) child;
					continue;
				}

				if (this.nextNode.getNodeType() == Node.ELEMENT_NODE) {
					this.parentNode = this.nextNode;
					this.nextNode = null;
					continue;
				}

				this.nextNode = (NodeImpl) this.nextNode.getNextSibling();
				if (this.nextNode != null)
					continue;
			}

			if (this.parentNode.getNodeType() == Node.ELEMENT_NODE) {
				ElementImpl element = (ElementImpl) this.parentNode;
				IStructuredDocumentRegion endStructuredDocumentRegion = element.getEndStructuredDocumentRegion();
				if (endStructuredDocumentRegion != null) {
					int endOffset = endStructuredDocumentRegion.getStart();
					if (endOffset == newOffset) { // found
						ownerNode = this.parentNode;
						isEndTag = true;
						break;
					}
				}
			}

			this.nextNode = (NodeImpl) this.parentNode.getNextSibling();
			this.parentNode = (NodeImpl) this.parentNode.getParentNode();
		}
		if (ownerNode == null)
			throw new StructuredDocumentRegionManagementException();

		short nodeType = ownerNode.getNodeType();
		if (nodeType == Node.ELEMENT_NODE) {
			ElementImpl element = (ElementImpl) ownerNode;
			if (isEndTag) {
				element.setEndStructuredDocumentRegion(newStructuredDocumentRegion);
			}
			else {
				element.setStartStructuredDocumentRegion(newStructuredDocumentRegion);
				updateAttrRegions(element, newStructuredDocumentRegion);
			}
		}
		else if (nodeType == Node.TEXT_NODE) {
			TextImpl text = (TextImpl) ownerNode;
			IStructuredDocumentRegion oldStructuredDocumentRegion = text.getStructuredDocumentRegion();
			if (oldStructuredDocumentRegion == null) {
				throw new StructuredDocumentRegionManagementException();
			}
			int oldOffset = oldStructuredDocumentRegion.getStart();
			int oldEnd = oldStructuredDocumentRegion.getEnd();
			if (oldOffset == newOffset && oldEnd == newEnd) {
				text.setStructuredDocumentRegion(newStructuredDocumentRegion);
				return;
			}

			if (oldStructuredDocumentRegion instanceof StructuredDocumentRegionProxy) {
				StructuredDocumentRegionProxy proxy = (StructuredDocumentRegionProxy) oldStructuredDocumentRegion;
				if (oldEnd > newEnd) {
					StructuredDocumentRegionContainer container = new StructuredDocumentRegionContainer();
					if (oldOffset == newOffset) {
						container.appendStructuredDocumentRegion(newStructuredDocumentRegion);
					}
					else {
						StructuredDocumentRegionProxy newProxy = new StructuredDocumentRegionProxy();
						newProxy.setOffset(oldOffset);
						newProxy.setLength(newEnd - oldOffset);
						newProxy.setStructuredDocumentRegion(newStructuredDocumentRegion);
						container.appendStructuredDocumentRegion(newProxy);
					}
					proxy.setOffset(newEnd);
					proxy.setLength(oldEnd - newEnd);
					container.appendStructuredDocumentRegion(proxy);
					text.setStructuredDocumentRegion(container);
				}
				else {
					proxy.setStructuredDocumentRegion(newStructuredDocumentRegion);

					if (oldEnd < newEnd) { // to be shared
						this.nextNode = (NodeImpl) text.getNextSibling();
						insertStructuredDocumentRegion(newStructuredDocumentRegion);
					}
				}
				return;
			}

			if (oldStructuredDocumentRegion instanceof StructuredDocumentRegionContainer) {
				StructuredDocumentRegionContainer container = (StructuredDocumentRegionContainer) oldStructuredDocumentRegion;
				int count = container.getStructuredDocumentRegionCount();
				for (int i = 0; i < count; i++) {
					IStructuredDocumentRegion content = container.getStructuredDocumentRegion(i);
					if (content == null)
						continue; // error
					int offset = content.getStart();
					int end = content.getEnd();
					if (end <= newOffset)
						continue;
					if (offset == newOffset && end == newEnd) {
						container.replaceStructuredDocumentRegion(newStructuredDocumentRegion, i);
						return;
					}

					if (content instanceof StructuredDocumentRegionProxy) {
						StructuredDocumentRegionProxy proxy = (StructuredDocumentRegionProxy) content;
						if (end > newEnd) {
							if (offset == newOffset) {
								container.insertStructuredDocumentRegion(newStructuredDocumentRegion, i);
							}
							else {
								StructuredDocumentRegionProxy newProxy = new StructuredDocumentRegionProxy();
								newProxy.setOffset(offset);
								newProxy.setLength(newEnd - offset);
								newProxy.setStructuredDocumentRegion(newStructuredDocumentRegion);
								container.insertStructuredDocumentRegion(newProxy, i);
							}
							proxy.setOffset(newEnd);
							proxy.setLength(end - newEnd);
							return;
						}
						else {
							proxy.setStructuredDocumentRegion(newStructuredDocumentRegion);
							if (end == newEnd)
								return;
						}
					}
				}

				if (oldEnd < newEnd) { // to be shared
					this.nextNode = (NodeImpl) text.getNextSibling();
					insertStructuredDocumentRegion(newStructuredDocumentRegion);
				}
				return;
			}
			else {
				throw new StructuredDocumentRegionManagementException();
			}
		}
		else {
			ownerNode.setStructuredDocumentRegion(newStructuredDocumentRegion);
		}
	}

	private void removeGapStructuredDocumentRegion(IStructuredDocumentRegion oldStructuredDocumentRegion) {
		if (this.gapStructuredDocumentRegion == null)
			return;

		if (this.gapStructuredDocumentRegion == oldStructuredDocumentRegion) {
			this.gapStructuredDocumentRegion = null;
			return;
		}

		if (this.gapStructuredDocumentRegion instanceof StructuredDocumentRegionProxy) {
			StructuredDocumentRegionProxy proxy = (StructuredDocumentRegionProxy) this.gapStructuredDocumentRegion;
			IStructuredDocumentRegion flatNode = proxy.getStructuredDocumentRegion();
			if (flatNode == oldStructuredDocumentRegion)
				this.gapStructuredDocumentRegion = null;
		}
		else if (this.gapStructuredDocumentRegion instanceof StructuredDocumentRegionContainer) {
			StructuredDocumentRegionContainer container = (StructuredDocumentRegionContainer) this.gapStructuredDocumentRegion;
			int count = container.getStructuredDocumentRegionCount();
			for (int i = 0; i < count; i++) {
				IStructuredDocumentRegion content = container.getStructuredDocumentRegion(i);
				if (content == null)
					continue;
				if (content == oldStructuredDocumentRegion) {
					if (count > 1)
						container.removeStructuredDocumentRegion(i);
					else
						this.gapStructuredDocumentRegion = null;
					return;
				}
				if (content instanceof StructuredDocumentRegionProxy) {
					StructuredDocumentRegionProxy proxy = (StructuredDocumentRegionProxy) content;
					if (proxy.getStructuredDocumentRegion() == oldStructuredDocumentRegion) {
						if (count > 1)
							container.removeStructuredDocumentRegion(i);
						else
							this.gapStructuredDocumentRegion = null;
						return;
					}
				}
			}
		}
	}

	private void removeStructuredDocumentRegion(IStructuredDocumentRegion oldStructuredDocumentRegion) {
		if (oldStructuredDocumentRegion == null)
			return; // error
		if (this.parentNode == null)
			return; // error

		int gapEnd = this.gapOffset + this.gapLength;
		int oldOffset = oldStructuredDocumentRegion.getStart();
		int oldEnd = oldStructuredDocumentRegion.getEnd();
		if (oldOffset >= this.gapOffset && oldEnd <= gapEnd)
			return; // do nothing
		int oldLength = oldEnd - oldOffset;
		if (oldOffset >= gapEnd)
			oldOffset += this.diff;

		// find owner node
		NodeImpl ownerNode = null;
		ElementImpl ownerEndTag = null;
		TextImpl ownerText = null;
		while (this.parentNode != null) {
			if (this.nextNode != null) {
				if (this.nextNode.getStructuredDocumentRegion() == oldStructuredDocumentRegion) {
					ownerNode = this.nextNode;
					break;
				}
				if (this.nextNode.getNodeType() == Node.TEXT_NODE) {
					TextImpl text = (TextImpl) this.nextNode;
					if (text.hasStructuredDocumentRegion(oldStructuredDocumentRegion)) {
						ownerNode = this.nextNode;
						ownerText = text;
						break;
					}
				}

				Node child = this.nextNode.getFirstChild();
				if (child != null) {
					this.parentNode = this.nextNode;
					this.nextNode = (NodeImpl) child;
					continue;
				}

				if (this.nextNode.getNodeType() == Node.ELEMENT_NODE) {
					this.parentNode = this.nextNode;
					this.nextNode = null;
					continue;
				}

				this.nextNode = (NodeImpl) this.nextNode.getNextSibling();
				if (this.nextNode != null)
					continue;
			}

			if (this.parentNode.getNodeType() == Node.ELEMENT_NODE) {
				ElementImpl element = (ElementImpl) this.parentNode;
				if (element.getEndStructuredDocumentRegion() == oldStructuredDocumentRegion) {
					ownerNode = this.parentNode;
					ownerEndTag = element;
					break;
				}
			}

			this.nextNode = (NodeImpl) this.parentNode.getNextSibling();
			this.parentNode = (NodeImpl) this.parentNode.getParentNode();
		}
		if (ownerNode == null)
			throw new StructuredDocumentRegionManagementException();

		if (ownerText != null) {
			IStructuredDocumentRegion flatNode = ownerText.getStructuredDocumentRegion();
			if (flatNode == oldStructuredDocumentRegion) {
				IStructuredDocumentRegion newStructuredDocumentRegion = new StructuredDocumentRegionProxy(oldOffset, oldLength);
				ownerText.setStructuredDocumentRegion(newStructuredDocumentRegion);
				return;
			}

			if (flatNode instanceof StructuredDocumentRegionProxy) {
				StructuredDocumentRegionProxy proxy = (StructuredDocumentRegionProxy) flatNode;
				if (proxy.getStructuredDocumentRegion() != oldStructuredDocumentRegion) {
					throw new StructuredDocumentRegionManagementException();
				}
				int offset = proxy.getOffset();
				int end = offset + proxy.getLength();
				if (offset >= this.gapOffset) {
					proxy.setOffset(offset + this.diff);
				}
				proxy.setStructuredDocumentRegion(null);
				if (end < oldEnd && (end < this.gapOffset || oldEnd > gapEnd)) { // has
					// shared
					removeStructuredDocumentRegion(oldStructuredDocumentRegion);
					return;
				}
			}
			else if (flatNode instanceof StructuredDocumentRegionContainer) {
				StructuredDocumentRegionContainer container = (StructuredDocumentRegionContainer) flatNode;
				int count = container.getStructuredDocumentRegionCount();
				for (int i = 0; i < count; i++) {
					IStructuredDocumentRegion content = container.getStructuredDocumentRegion(i);
					if (content == null)
						continue; // error
					if (content == oldStructuredDocumentRegion) {
						IStructuredDocumentRegion newStructuredDocumentRegion = new StructuredDocumentRegionProxy(oldOffset, oldLength);
						container.replaceStructuredDocumentRegion(newStructuredDocumentRegion, i);
						return;
					}

					if (content instanceof StructuredDocumentRegionProxy) {
						StructuredDocumentRegionProxy proxy = (StructuredDocumentRegionProxy) content;
						if (proxy.getStructuredDocumentRegion() == oldStructuredDocumentRegion) {
							int offset = proxy.getOffset();
							int end = offset + proxy.getLength();
							if (offset >= this.gapOffset) {
								proxy.setOffset(offset + this.diff);
							}
							proxy.setStructuredDocumentRegion(null);
							if (end < oldEnd && (end < this.gapOffset || oldEnd > gapEnd)) { // has
								// shared
								removeStructuredDocumentRegion(oldStructuredDocumentRegion);
								return;
							}
						}
					}
				}
			}
			else {
				throw new StructuredDocumentRegionManagementException();
			}
		}
		else {
			IStructuredDocumentRegion newStructuredDocumentRegion = new StructuredDocumentRegionProxy(oldOffset, oldLength);
			if (ownerEndTag != null) {
				ownerEndTag.setEndStructuredDocumentRegion(newStructuredDocumentRegion);
			}
			else {
				ownerNode.setStructuredDocumentRegion(newStructuredDocumentRegion);
			}
		}
	}

	/**
	 * replaceAttr method
	 * 
	 * @param ownerElement
	 *            org.w3c.dom.Element
	 * @param newAttr
	 *            org.w3c.dom.Attr
	 * @param oldAttr
	 *            org.w3c.dom.Attr
	 */
	void replaceAttr(Element ownerElement, Attr newAttr, Attr oldAttr) {
		if (ownerElement == null)
			return;
		if (getStructuredDocument() == null)
			return;

		ElementImpl element = (ElementImpl) ownerElement;
		if (!element.hasStartTag()) {
			changeStartTag(element);
			return;
		}
		if (element.isCommentTag()) {
			changeStartTag(element);
			return;
		}

		int offset = element.getStartOffset();
		int start = offset;
		int end = offset;

		boolean insertSpace = false;
		String attrValueClose = null;
		if (oldAttr != null) {
			AttrImpl impl = (AttrImpl) oldAttr;
			ITextRegion nameRegion = impl.getNameRegion();
			if (nameRegion == null)
				return; // must never happen
			ITextRegion lastRegion = impl.getValueRegion();
			if (lastRegion != null) {
				end += lastRegion.getEnd();
			}
			else {
				lastRegion = impl.getEqualRegion();
				if (lastRegion != null) {
					end += lastRegion.getEnd();
				}
				else {
					end += nameRegion.getEnd();
					lastRegion = nameRegion;
				}
			}
			// check there are extra space before the last attribute
			IStructuredDocumentRegion flatNode = element.getStartStructuredDocumentRegion();
			if (flatNode == null)
				return; // must never happen
			ITextRegionList regions = flatNode.getRegions();
			if (regions == null)
				return; // must never happen
			ITextRegion prevRegion = null;
			ITextRegion nextRegion = null;
			for (int i = 0; i < regions.size(); i++) {
				ITextRegion region = regions.get(i);
				if (region == nameRegion) {
					if (i > 0) {
						prevRegion = regions.get(i - 1);
					}
				}
				if (region == lastRegion) {
					if (i + 1 < regions.size()) {
						nextRegion = regions.get(i + 1);
					}
					break;
				}
			}
			boolean isLastAttr = false;
			if (nextRegion != null) {
				String regionType = nextRegion.getType();
				if (regionType == XMLRegionContext.XML_TAG_CLOSE || regionType == XMLRegionContext.XML_EMPTY_TAG_CLOSE || isNestedTagClose(regionType)) {
					isLastAttr = true;
				}
			}
			if (isLastAttr && prevRegion != null) {
				start += prevRegion.getTextEnd();
			}
			else {
				start += nameRegion.getStart();
			}

			// impl.resetRegions(ownerElement);
			impl.resetRegions(element);
		}
		else { // append attribute
			IStructuredDocumentRegion flatNode = element.getStartStructuredDocumentRegion();
			if (flatNode == null)
				return; // must never happen

			attrValueClose = getAttrValueClose(element);
			if (attrValueClose != null && attrValueClose.length() > 0) {
				insertSpace = true;
				start = flatNode.getEndOffset();
				end = start;
			}
			else {
				ITextRegionList regions = flatNode.getRegions();
				if (regions == null)
					return; // must never happen
				int attrStart = 0;
				for (int i = regions.size() - 1; i >= 0; i--) {
					ITextRegion region = regions.get(i);
					String regionType = region.getType();
					if (regionType == XMLRegionContext.XML_TAG_CLOSE || regionType == XMLRegionContext.XML_EMPTY_TAG_CLOSE || isNestedTagClose(regionType))
						continue;
					int regionEnd = region.getEnd();
					if (regionEnd == region.getTextEnd())
						insertSpace = true;
					attrStart = regionEnd;
					break;
				}
				if (attrStart == 0)
					return; // not found, must never happen
				start += attrStart;
				end = start;
			}
		}

		String source = null;
		if (newAttr != null) {
			int size = 2;
			if (attrValueClose != null)
				size += attrValueClose.length();
			String name = this.generator.generateAttrName(newAttr);
			if (name != null)
				size += name.length();
			String value = this.generator.generateAttrValue(newAttr);
			if (value != null)
				size += value.length();
			StringBuffer buffer = new StringBuffer(size);
			if (attrValueClose != null)
				buffer.append(attrValueClose);
			if (insertSpace)
				buffer.append(' ');
			buffer.append(name);
			if (value != null) {
				buffer.append('=');
				buffer.append(value);
			}
			source = buffer.toString();
		}

		replaceSource(source, start, end);
	}

	protected boolean isNestedTagClose(String regionType) {
		boolean result = false;
		return result;
	}

	/**
	 * replaceChild method
	 * 
	 * @param parentNode
	 *            org.w3c.dom.Node
	 * @param newChild
	 *            org.w3c.dom.Node
	 * @param oldChild
	 *            org.w3c.dom.Node
	 */
	void replaceChild(Node parentNode, Node newChild, Node oldChild) {
		if (parentNode == null)
			return;
		if (newChild == null && oldChild == null)
			return;
		if (getStructuredDocument() == null)
			return;

		int start = 0;
		int end = 0;
		String preTag = null;
		String postTag = null;
		ElementImpl postElement = null;
		if (oldChild != null) {
			NodeImpl node = (NodeImpl) oldChild;
			start = node.getStartOffset();
			end = node.getEndOffset();
			if (oldChild.getNodeType() == Node.TEXT_NODE) {
				this.gapStructuredDocumentRegion = node.getStructuredDocumentRegion();
			}
			node.resetStructuredDocumentRegions(); // reset values from
			// IStructuredDocumentRegion
		}
		else {
			NodeImpl prev = (NodeImpl) newChild.getPreviousSibling();
			if (prev != null) {
				start = prev.getEndOffset();
				end = start;
				preTag = getCloseTag(prev);
			}
			else {
				// first child
				NodeImpl next = (NodeImpl) newChild.getNextSibling();
				if (next != null) {
					start = next.getStartOffset();
					end = start;
					if (parentNode.getNodeType() == Node.ELEMENT_NODE) {
						preTag = getStartCloseTag((XMLElement) parentNode);
					}
				}
				else {
					// newly having a child
					if (parentNode.getNodeType() == Node.ELEMENT_NODE) {
						ElementImpl element = (ElementImpl) parentNode;
						if (element.isEmptyTag()) { // empty tag format
							// need to generate the start and the end tags
							end = element.getEndOffset();
							start = end - 2; // for "/>"
							element.setEmptyTag(false);
							preTag = this.generator.generateCloseTag(element);
							postTag = this.generator.generateEndTag(element);
							postElement = element;
						}
						else if (!element.hasStartTag()) {
							start = element.getStartOffset();
							end = start;
							// invalid end tag or implicit tag
							// need to generate the start tag
							preTag = this.generator.generateStartTag(element);
							if (preTag != null) {
								int length = preTag.length();
								if (length > 0) {
									IStructuredDocumentRegion flatNode = new StructuredDocumentRegionProxy(start, length);
									element.setStartStructuredDocumentRegion(flatNode);
								}
							}
							if (!element.hasEndTag()) {
								// implicit tag
								// need to generate the end tags
								postTag = this.generator.generateEndTag(element);
								postElement = element;
							}
						}
						else {
							start = element.getStartEndOffset();
							end = start;
							preTag = getStartCloseTag(element);
							if (preTag != null && preTag.length() > 0) {
								if (!element.hasEndTag() && (element.isJSPContainer() || element.isCDATAContainer())) {
									// need to generate the end tag
									postTag = this.generator.generateEndTag(element);
									postElement = element;
								}
							}
						}
					}
					// else might DOCUMENT_NODE, start and end are 0
				}
			}
		}

		String source = null;
		if (newChild != null) {
			StringBuffer buffer = new StringBuffer();
			int offset = start;
			if (preTag != null) {
				int length = preTag.length();
				if (length > 0) {
					offset += length;
					buffer.append(preTag);
				}
			}

			NodeImpl node = (NodeImpl) newChild;
			while (node != null) {
				if (node.getNodeType() == Node.ELEMENT_NODE) {
					ElementImpl element = (ElementImpl) node;
					if (element.preferEmptyTag())
						element.setEmptyTag(true);
					IStructuredDocumentRegion flatNode = null;
					String startTag = this.generator.generateStartTag(element);
					if (startTag != null) {
						int length = startTag.length();
						if (length > 0) {
							buffer.append(startTag);
							flatNode = new StructuredDocumentRegionProxy(offset, length);
							offset += length;
						}
					}
					element.setStartStructuredDocumentRegion(flatNode);
				}
				else {
					String content = this.generator.generateSource(node);
					if (content == null)
						content = new String();
					int length = content.length();
					IStructuredDocumentRegion flatNode = null;
					if (length > 0) {
						buffer.append(content);
						flatNode = new StructuredDocumentRegionProxy(offset, length);
						offset += length;
					}
					node.setStructuredDocumentRegion(flatNode);
				}

				NodeImpl child = (NodeImpl) node.getFirstChild();
				if (child != null) {
					node = child;
					continue;
				}

				if (node.getNodeType() == Node.ELEMENT_NODE) {
					ElementImpl element = (ElementImpl) node;
					IStructuredDocumentRegion flatNode = null;
					String endTag = this.generator.generateEndTag(element);
					if (endTag != null) {
						int length = endTag.length();
						if (length > 0) {
							buffer.append(endTag);
							flatNode = new StructuredDocumentRegionProxy(offset, length);
							offset += length;
						}
					}
					element.setEndStructuredDocumentRegion(flatNode);
				}

				while (node != null) {
					if (node == newChild) {
						node = null;
						break;
					}
					NodeImpl next = (NodeImpl) node.getNextSibling();
					if (next != null) {
						node = next;
						break;
					}

					node = (NodeImpl) node.getParentNode();
					if (node.getNodeType() != Node.ELEMENT_NODE)
						continue;
					ElementImpl element = (ElementImpl) node;
					IStructuredDocumentRegion flatNode = null;
					String endTag = this.generator.generateEndTag(element);
					if (endTag != null) {
						int length = endTag.length();
						if (length > 0) {
							buffer.append(endTag);
							flatNode = new StructuredDocumentRegionProxy(offset, length);
							offset += length;
						}
					}
					element.setEndStructuredDocumentRegion(flatNode);
				}
			}

			if (postTag != null) {
				int length = postTag.length();
				if (length > 0) {
					buffer.append(postTag);
					if (postElement != null) {
						IStructuredDocumentRegion flatNode = new StructuredDocumentRegionProxy(offset, length);
						postElement.setEndStructuredDocumentRegion(flatNode);
					}
				}
			}
			source = buffer.toString();
		}

		if (start == end && (source == null || source.length() == 0)) {
			// no thing changed
			return;
		}

		replaceSource(source, start, end);
	}

	void replaceRegions(IStructuredDocumentRegion flatNode, ITextRegionList newRegions, ITextRegionList oldRegions) {
		// future_TODO: optimize

		NodeImpl root = (NodeImpl) this.model.getDocument();
		this.parentNode = root;
		this.nextNode = (NodeImpl) root.getFirstChild();

		removeGapStructuredDocumentRegion(flatNode);
		insertGapStructuredDocumentRegionBefore(flatNode.getStart());
		changeStructuredDocumentRegion(flatNode);
		insertGapStructuredDocumentRegionAfter(flatNode.getEnd());
	}

	/**
	 * Wraps IStructuredDocumentRegion.replaceText() and sets contextual
	 * information.
	 */
	private void replaceSource(String source, int start, int end) {
		int inserted = 0;
		if (source == null)
			source = new String();
		else
			inserted = source.length();
		int removed = end - start;
		if (inserted == 0 && removed == 0)
			return;

		this.gapOffset = start;
		this.gapLength = removed;
		this.diff = inserted - removed;
		// Note: due to bug
		// https://w3.opensource.ibm.com/bugzilla/show_bug.cgi?id=3619
		// for now assume "ignore readonly" region is ok -- assume DOM itself
		// checks if
		// ok to insert or not. In reality, we may have to make or "contains"
		// method more
		// better. Or, we may have to "perculate up" the parameter for clients
		// to tell us programatically
		// that its ok to insert/format in a read-only region.
		getStructuredDocument().replaceText(this.model, this.gapOffset, this.gapLength, source, true);
	}

	void replaceStructuredDocumentRegions(IStructuredDocumentRegionList newStructuredDocumentRegions, IStructuredDocumentRegionList oldStructuredDocumentRegions) {
		NodeImpl root = (NodeImpl) this.model.getDocument();

		if (oldStructuredDocumentRegions != null) {
			this.parentNode = root;
			this.nextNode = (NodeImpl) root.getFirstChild();

			Enumeration e = oldStructuredDocumentRegions.elements();
			while (e.hasMoreElements()) {
				IStructuredDocumentRegion flatNode = (IStructuredDocumentRegion) e.nextElement();
				if (flatNode == null)
					continue;
				removeStructuredDocumentRegion(flatNode);
				removeGapStructuredDocumentRegion(flatNode);
			}
		}

		if (newStructuredDocumentRegions != null) {
			this.parentNode = root;
			this.nextNode = (NodeImpl) root.getFirstChild();

			IStructuredDocumentRegion lastStructuredDocumentRegion = null;
			Enumeration e = newStructuredDocumentRegions.elements();
			while (e.hasMoreElements()) {
				IStructuredDocumentRegion flatNode = (IStructuredDocumentRegion) e.nextElement();
				if (flatNode == null)
					continue;
				if (lastStructuredDocumentRegion == null)
					insertGapStructuredDocumentRegionBefore(flatNode.getStart());
				insertStructuredDocumentRegion(flatNode);
				lastStructuredDocumentRegion = flatNode;
			}
			if (lastStructuredDocumentRegion != null) {
				insertGapStructuredDocumentRegionAfter(lastStructuredDocumentRegion.getEnd());
			}
			else {
				insertGapStructuredDocumentRegionBefore(this.gapOffset);
				// make sure to restore all backuped StructuredDocumentRegions
				insertGapStructuredDocumentRegionAfter(this.gapOffset);
			}
		}
		else {
			this.parentNode = root;
			this.nextNode = (NodeImpl) root.getFirstChild();

			insertGapStructuredDocumentRegionBefore(this.gapOffset);
			// make sure to restore all backuped StructuredDocumentRegions
			insertGapStructuredDocumentRegionAfter(this.gapOffset);
		}
	}

	/**
	 */
	private void updateAttrRegions(Element element, IStructuredDocumentRegion flatNode) {

		// update attributes
		ITextRegionList regions = flatNode.getRegions();
		if (regions == null)
			return;
		NamedNodeMap attributes = element.getAttributes();
		if (attributes == null)
			return;
		int index = -1;
		AttrImpl attr = null;
		Iterator e = regions.iterator();
		while (e.hasNext()) {
			ITextRegion region = (ITextRegion) e.next();
			String regionType = region.getType();
			if (regionType == XMLRegionContext.XML_TAG_ATTRIBUTE_NAME) {
				attr = (AttrImpl) attributes.item(++index);
				if (attr != null) {
					attr.setNameRegion(region);
					// reset other regions
					attr.setEqualRegion(null);
					attr.setValueRegion(null);
				}
			}
			else if (regionType == XMLRegionContext.XML_TAG_ATTRIBUTE_EQUALS) {
				if (attr != null)
					attr.setEqualRegion(region);
			}
			else if (regionType == XMLRegionContext.XML_TAG_ATTRIBUTE_VALUE) {
				if (attr != null) {
					attr.setValueRegion(region);
					attr = null;
				}
			}
		}
	}
}
