/*******************************************************************************
 * Copyright (c) 2001, 2005 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;
				}
			}
		}
	}
}
