/*******************************************************************************
 * 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.internal.provisional.text.IStructuredDocument;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegionList;
import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion;
import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionList;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
import org.eclipse.wst.xml.core.internal.provisional.document.ISourceGenerator;
import org.eclipse.wst.xml.core.internal.regions.DOMRegionContext;
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 ISourceGenerator generator = null;
	private DOMModelImpl model = null;
	private NodeImpl nextNode = null;
	private NodeImpl parentNode = null;

	protected XMLModelUpdater(DOMModelImpl 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((IDOMNode) 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(IDOMElement 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() != DOMRegionContext.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(IDOMNode 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();

		IDOMNode lastChild = (IDOMNode) 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(IDOMElement 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 == DOMRegionContext.XML_TAG_CLOSE || regionType == DOMRegionContext.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 == DOMRegionContext.XML_TAG_CLOSE || regionType == DOMRegionContext.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((IDOMElement) 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 == DOMRegionContext.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 == DOMRegionContext.XML_TAG_ATTRIBUTE_EQUALS) {
				if (attr != null)
					attr.setEqualRegion(region);
			}
			else if (regionType == DOMRegionContext.XML_TAG_ATTRIBUTE_VALUE) {
				if (attr != null) {
					attr.setValueRegion(region);
					attr = null;
				}
			}
		}
	}
}
