/*******************************************************************************
 * 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.format;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Preferences;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.wst.sse.core.exceptions.SourceEditingRuntimeException;
import org.eclipse.wst.sse.core.format.IStructuredFormatContraints;
import org.eclipse.wst.sse.core.format.IStructuredFormatPreferences;
import org.eclipse.wst.sse.core.format.IStructuredFormatter;
import org.eclipse.wst.sse.core.format.StructuredFormatContraints;
import org.eclipse.wst.sse.core.internal.SSECorePlugin;
import org.eclipse.wst.sse.core.internal.parser.ContextRegion;
import org.eclipse.wst.sse.core.preferences.CommonModelPreferenceNames;
import org.eclipse.wst.sse.core.text.IStructuredDocument;
import org.eclipse.wst.sse.core.text.IStructuredDocumentRegion;
import org.eclipse.wst.sse.core.text.ITextRegion;
import org.eclipse.wst.sse.core.text.ITextRegionList;
import org.eclipse.wst.sse.core.util.StringUtils;
import org.eclipse.wst.xml.core.document.XMLModel;
import org.eclipse.wst.xml.core.document.XMLNode;
import org.eclipse.wst.xml.core.internal.XMLCorePlugin;
import org.eclipse.wst.xml.core.internal.document.CDATASectionImpl;
import org.eclipse.wst.xml.core.internal.parser.regions.TagNameRegion;
import org.eclipse.wst.xml.core.jsp.model.parser.temp.XMLJSPRegionContexts;
import org.eclipse.wst.xml.core.parser.XMLRegionContext;
import org.w3c.dom.Node;

public class NodeFormatter implements IStructuredFormatter {
	static protected final String CR = "\r"; //$NON-NLS-1$
	static protected final String CRLF = "\r\n"; //$NON-NLS-1$
	static protected final String DELIMITERS = " \t\n\r\f"; //$NON-NLS-1$
	static protected final String EMPTY_STRING = ""; //$NON-NLS-1$
	static protected final String FF = "\f"; //$NON-NLS-1$
	static protected final String LF = "\n"; //$NON-NLS-1$
	static protected final String SPACE = " "; //$NON-NLS-1$
	static protected final char SPACE_CHAR = ' '; //$NON-NLS-1$
	static protected final String TAB = "\t"; //$NON-NLS-1$
	static protected final char TAB_CHAR = '\t'; //$NON-NLS-1$
	protected IStructuredFormatContraints fFormatContraints = null;
	protected IStructuredFormatPreferences fFormatPreferences = null;
	protected IProgressMonitor fProgressMonitor = null;

	protected String compressSpaces(String string, IStructuredFormatContraints formatContraints) {
		/*
		 * Note that the StructuredTextEditor supports mixed new line
		 * characters (CR, LF, CRLF) in one file. We have to handle that when
		 * we try to preserve blank lines.
		 */
		String[] stringArray = null;
		boolean clearAllBlankLines = formatContraints.getClearAllBlankLines();

		if (clearAllBlankLines)
			stringArray = StringUtils.asArray(string);
		else
			stringArray = StringUtils.asArray(string, DELIMITERS, true);

		StringBuffer compressedString = new StringBuffer();
		if (stringArray.length > 0) {
			boolean cr = false, lf = false, cr2 = false, nonSpace = true;

			if (stringArray[0].compareTo(CR) == 0)
				cr = true;
			else if (stringArray[0].compareTo(LF) == 0)
				lf = true;
			else if ((stringArray[0].compareTo(SPACE) != 0) && (stringArray[0].compareTo(TAB) != 0) && (stringArray[0].compareTo(FF) != 0)) {
				compressedString.append(stringArray[0]);
				nonSpace = true;
			}

			for (int i = 1; i < stringArray.length; i++) {
				if (stringArray[i].compareTo(CR) == 0) {
					if (cr && lf) {
						if (nonSpace) {
							compressedString.append(CR + LF);
							nonSpace = false;
						}
						compressedString.append(stringArray[i]);
						cr2 = true;
					} else if (cr) {
						if (nonSpace) {
							compressedString.append(CR);
							nonSpace = false;
						}
						compressedString.append(stringArray[i]);
						cr2 = true;
					} else
						cr = true;
				} else if (stringArray[i].compareTo(LF) == 0) {
					if (cr && lf && cr2) {
						compressedString.append(stringArray[i]);
					} else if (lf) {
						if (nonSpace) {
							compressedString.append(LF);
							nonSpace = false;
						}
						compressedString.append(stringArray[i]);
					} else
						lf = true;
				} else if ((stringArray[i].compareTo(SPACE) != 0) && (stringArray[i].compareTo(TAB) != 0) && (stringArray[i].compareTo(FF) != 0)) {
					if (compressedString.length() > 0)
						compressedString.append(SPACE);
					compressedString.append(stringArray[i]);

					cr = false;
					lf = false;
					cr2 = false;
					nonSpace = true;
				}
			}
		}

		return compressedString.toString();
	}

	protected boolean firstStructuredDocumentRegionContainsLineDelimiters(XMLNode node) {
		boolean result = false;

		if (node != null) {
			IStructuredDocumentRegion firstStructuredDocumentRegion = node.getFirstStructuredDocumentRegion();
			if (firstStructuredDocumentRegion != null && firstStructuredDocumentRegion.getText() != null) {
				String firstStructuredDocumentRegionText = firstStructuredDocumentRegion.getText();
				result = StringUtils.containsLineDelimiter(firstStructuredDocumentRegionText);
			}
		}

		return result;
	}

	public void format(Node node) {
		IStructuredFormatContraints formatContraints = getFormatContraints();

		format(node, formatContraints);
	}

	public void format(Node node, IStructuredFormatContraints formatContraints) {
		if (formatContraints.getFormatWithSiblingIndent())
			formatContraints.setCurrentIndent(getSiblingIndent(node));

		if (node instanceof XMLNode)
			formatNode((XMLNode) node, formatContraints);
	}

	protected void formatIndentationAfterNode(XMLNode node, IStructuredFormatContraints formatContraints) {
		if (node != null) {
			XMLNode nextSibling = (XMLNode) node.getNextSibling();
			IStructuredDocument doc = node.getModel().getStructuredDocument();
			int line = doc.getLineOfOffset(node.getEndOffset());
			String lineDelimiter = doc.getLineDelimiter();
			try {
				lineDelimiter = doc.getLineDelimiter(line);
				if (lineDelimiter == null)
					lineDelimiter = ""; //$NON-NLS-1$
			} catch (BadLocationException exception) {
				throw new SourceEditingRuntimeException(exception);
			}

			if (node.getParentNode() != null) {
				if (node.getParentNode().getNodeType() == Node.DOCUMENT_NODE)
					if (nextSibling != null)
						if (nextSibling.getNodeType() == Node.TEXT_NODE)
							getFormatter(nextSibling).format(nextSibling, formatContraints);
						else if (nextSibling.getNodeType() == Node.COMMENT_NODE) {
							// do nothing
						} else {
							String lineIndent = formatContraints.getCurrentIndent();
							insertAfterNode(node, lineDelimiter + lineIndent);
						}
					else {
					}

				else if (nextSibling != null)
					if (nextSibling.getNodeType() == Node.TEXT_NODE)
						getFormatter(nextSibling).format(nextSibling, formatContraints);
					else if (nextSibling.getNodeType() == Node.COMMENT_NODE) {
						// do nothing
					} else {
						String lineIndent = formatContraints.getCurrentIndent();
						insertAfterNode(node, lineDelimiter + lineIndent);
					}
				else {
					XMLNode indentNode = getParentIndentNode(node);
					String lineIndent = getNodeIndent(indentNode);
					XMLNode lastChild = getDeepestChildNode(node);
					boolean clearAllBlankLines = formatContraints.getClearAllBlankLines();

					if (lastChild != null) {
						if ((lastChild.getNodeType() == Node.TEXT_NODE) && (lastChild.getNodeValue().endsWith(lineDelimiter + lineIndent))) {
							// this text node already ends with the requested
							// indentation
						}

						else if ((lastChild.getNodeType() == Node.TEXT_NODE) && (lastChild.getNodeValue() != null && lastChild.getNodeValue().endsWith(lineDelimiter)))
							if (clearAllBlankLines) {
								replaceNodeValue(lastChild, lineDelimiter + lineIndent);
							} else {
								// append indentation
								insertAfterNode(lastChild, lineIndent);
							}
						else if (lastChild.getNodeType() == Node.TEXT_NODE)
							if (lastChild.getNodeValue().length() == 0) {
								// replace
								replaceNodeValue(lastChild, lineDelimiter + lineIndent);
							} else {
								// append indentation
								insertAfterNode(lastChild, lineDelimiter + lineIndent);
							}
						else {
							// append indentation
							insertAfterNode(lastChild, lineDelimiter + lineIndent);
						}
					}
				}
			}
		}
	}

	protected void formatIndentationBeforeNode(XMLNode node, IStructuredFormatContraints formatContraints) {
		if (node != null) {
			XMLNode previousSibling = (XMLNode) node.getPreviousSibling();
			IStructuredDocument doc = node.getModel().getStructuredDocument();
			int line = doc.getLineOfOffset(node.getStartOffset());
			String lineDelimiter = doc.getLineDelimiter();
			try {
				if (line > 0) {
					lineDelimiter = doc.getLineDelimiter(line - 1);
					if (lineDelimiter == null)
						lineDelimiter = ""; //$NON-NLS-1$
				}
			} catch (BadLocationException exception) {
				throw new SourceEditingRuntimeException(exception);
			}
			String lineIndent = formatContraints.getCurrentIndent();

			if (node.getParentNode() != null) {
				if (node.getParentNode().getNodeType() == Node.DOCUMENT_NODE) {
					if (previousSibling != null)
						if (previousSibling.getNodeType() == Node.TEXT_NODE)
							getFormatter(previousSibling).format(previousSibling, formatContraints);
						else {
							insertBeforeNode(node, lineDelimiter + lineIndent);
						}
				} else {
					if (previousSibling == null || previousSibling.getNodeType() != Node.TEXT_NODE) {
						// 261968 - formatting tag without closing bracket:
						// <t1><t1
						// 265673 - Null ptr in formatIndentationBeforeNode
						int prevEndNodeOffset = -1;
						int prevEndRegionOffset = -1;
						if (previousSibling != null) {
							prevEndNodeOffset = previousSibling.getEndOffset();
							IStructuredDocumentRegion endRegion = previousSibling.getEndStructuredDocumentRegion();
							if (endRegion != null) {
								prevEndRegionOffset = endRegion.getTextEndOffset();
							}
						}
						if ((previousSibling == null) || (prevEndNodeOffset != -1 && prevEndNodeOffset == prevEndRegionOffset)) {
							insertBeforeNode(node, lineDelimiter + lineIndent);
						}

					} else {
						if (previousSibling.getNodeValue().length() == 0) {
							// replace
							replaceNodeValue(previousSibling, lineDelimiter + lineIndent);
						} else {
							// append indentation
							if (!previousSibling.getNodeValue().endsWith(lineDelimiter + lineIndent)) {
								if (previousSibling.getNodeValue().endsWith(lineDelimiter)) {
									insertAfterNode(previousSibling, lineIndent);
								} else
									getFormatter(previousSibling).format(previousSibling, formatContraints);
							}
						}
					}
				}
			}
		}
	}

	protected void formatNode(XMLNode node, IStructuredFormatContraints formatContraints) {
		if (node != null && (fProgressMonitor == null || !fProgressMonitor.isCanceled())) {
			// format indentation before node
			formatIndentationBeforeNode(node, formatContraints);

			// format indentation after node
			formatIndentationAfterNode(node, formatContraints);
		}
	}

	/**
	 * This method will compute the correct indentation after this node
	 * depending on the indentations of its sibling nodes and parent node. Not
	 * needed anymore?
	 */
	protected void formatTrailingText(XMLNode node, IStructuredFormatContraints formatContraints) {
		String lineDelimiter = node.getModel().getStructuredDocument().getLineDelimiter();
		String lineIndent = formatContraints.getCurrentIndent();
		String parentLineIndent = getNodeIndent(node.getParentNode());
		boolean clearAllBlankLines = formatContraints.getClearAllBlankLines();

		if ((node != null) && (node.getNodeType() != Node.DOCUMENT_NODE)) {
			XMLNode nextSibling = (XMLNode) node.getNextSibling();
			if ((nextSibling != null) && (nextSibling.getNodeType() == Node.TEXT_NODE)) {
				String nextSiblingText = nextSibling.getNodeValue();
				if (nextSibling.getNextSibling() == null)
					if ((nextSibling.getParentNode().getNodeType() == Node.DOCUMENT_NODE) && (nextSiblingText.trim().length() == 0))
						// delete spaces at the end of the document
						replaceNodeValue(nextSibling, EMPTY_STRING);
					else
						// replace the text node with parent indentation
						replaceNodeValue(nextSibling, lineDelimiter + parentLineIndent);
				else
					// replace the text node with indentation
					replaceNodeValue(nextSibling, lineDelimiter + lineIndent);
			} else {
				if (nextSibling == null) {
					lineIndent = parentLineIndent;

					if (node.getParentNode().getNodeType() != Node.DOCUMENT_NODE)
						if ((node.getNodeType() == Node.TEXT_NODE) && (node.getNodeValue().endsWith(lineDelimiter + lineIndent))) {
							// this text node already ends with the requested
							// indentation
						}

						else if ((node.getNodeType() == Node.TEXT_NODE) && (node.getNodeValue().endsWith(lineDelimiter)))
							if (clearAllBlankLines)
								replaceNodeValue(node, lineDelimiter + lineIndent);
							else
								// append indentation
								insertAfterNode(node, lineIndent);
						else if (node.getNodeType() == Node.TEXT_NODE)
							if (node.getNodeValue().length() == 0)
								// replace
								replaceNodeValue(node, lineDelimiter + lineIndent);
							else
							// append indentation
							if (!node.getNodeValue().endsWith(lineDelimiter + lineIndent))
								if (node.getNodeValue().endsWith(lineDelimiter))
									insertAfterNode(node, lineIndent);
								else
									insertAfterNode(node, lineDelimiter + lineIndent);
							else
								replaceNodeValue(node, lineDelimiter + lineIndent);
				} else {
					if ((node.getNodeType() == Node.TEXT_NODE) && (node.getNodeValue().endsWith(lineDelimiter + lineIndent))) {
						// this text node already ends with the requested
						// indentation
					}

					else if ((node.getNodeType() == Node.TEXT_NODE) && (node.getNodeValue().endsWith(lineDelimiter)))
						if (clearAllBlankLines)
							replaceNodeValue(node, lineDelimiter + lineIndent);
						else
							// append indentation
							insertAfterNode(node, lineIndent);
					else if (node.getNodeType() == Node.TEXT_NODE)
						if (node.getNodeValue().length() == 0)
							// replace
							replaceNodeValue(node, lineDelimiter + lineIndent);
						else
							// append indentation
							insertAfterNode(node, lineDelimiter + lineIndent);
					else
						// append indentation
						insertAfterNode(node, lineDelimiter + lineIndent);
				}
			}
		}
	}

	protected String getCompressedNodeText(XMLNode node, IStructuredFormatContraints formatContraints) {
		return compressSpaces(getNodeText(node), formatContraints);
	}

	protected XMLNode getDeepestChildNode(XMLNode node) {
		XMLNode result = null;
		XMLNode lastChild = (XMLNode) node.getLastChild();

		if (lastChild == null)
			result = node;
		else {
			result = getDeepestChildNode(lastChild);

			if ((result.getNodeType() == Node.TEXT_NODE || result.getNodeType() == Node.COMMENT_NODE) && !isEndTagMissing(node))
				result = node;
		}

		return result;
	}

	public IStructuredFormatContraints getFormatContraints() {
		if (fFormatContraints == null) {
			fFormatContraints = new StructuredFormatContraints();

			fFormatContraints.setClearAllBlankLines(getFormatPreferences().getClearAllBlankLines());
		}

		return fFormatContraints;
	}

	public IStructuredFormatPreferences getFormatPreferences() {
		if (fFormatPreferences == null) {
			fFormatPreferences = new StructuredFormatPreferencesXML();

			Preferences preferences = getModelPreferences();
			if (preferences != null) {
				fFormatPreferences.setLineWidth(preferences.getInt(CommonModelPreferenceNames.LINE_WIDTH));
				((IStructuredFormatPreferencesXML) fFormatPreferences).setSplitMultiAttrs(preferences.getBoolean(CommonModelPreferenceNames.SPLIT_MULTI_ATTRS));
				fFormatPreferences.setClearAllBlankLines(preferences.getBoolean(CommonModelPreferenceNames.CLEAR_ALL_BLANK_LINES));

				if (preferences.getBoolean(CommonModelPreferenceNames.INDENT_USING_TABS))
					fFormatPreferences.setIndent("\t"); //$NON-NLS-1$
				else {
					int tabWidth = SSECorePlugin.getDefault().getPluginPreferences().getInt(CommonModelPreferenceNames.TAB_WIDTH);
					String indent = ""; //$NON-NLS-1$
					for (int i = 0; i < tabWidth; i++) {
						indent += " "; //$NON-NLS-1$
					}
					fFormatPreferences.setIndent(indent);
				}
			}
		}

		return fFormatPreferences;
	}

	protected IStructuredFormatter getFormatter(XMLNode node) {
		// 262135 - NPE during format of empty document
		if (node == null)
			return null;

		short nodeType = ((Node) node).getNodeType();
		IStructuredFormatter formatter = null;
		switch (nodeType) {
			case Node.ELEMENT_NODE : {
				formatter = new ElementNodeFormatter();
				break;
			}
			case Node.TEXT_NODE : {
				if (node instanceof CDATASectionImpl)
					formatter = new NodeFormatter();
				else
					formatter = new TextNodeFormatter();
				break;
			}
			case Node.COMMENT_NODE : {
				formatter = new CommentNodeFormatter();
				break;
			}
			case Node.PROCESSING_INSTRUCTION_NODE : {
				formatter = new NodeFormatter();
				break;
			}
			case Node.DOCUMENT_NODE : {
				formatter = new DocumentNodeFormatter();
				break;
			}
			default : {
				formatter = new NodeFormatter();
			}
		}

		// init fomatter
		formatter.setFormatPreferences(getFormatPreferences());
		formatter.setProgressMonitor(fProgressMonitor);

		return formatter;
	}

	protected int getIndentationLength(String indent) {
		// TODO Kit : The calculation of IndentationLength is not correct
		// here.
		// nodeIndentation may contain tabs. Multiply by 4 temporarily to get
		// approx. width.
		// Need to re-work.

		int indentationLength = 0;

		for (int i = 0; i < indent.length(); i++) {
			if (indent.substring(i, i + 1).compareTo(TAB) == 0)
				indentationLength += 4;
			else
				indentationLength++;
		}

		return indentationLength;
	}

	protected Preferences getModelPreferences() {
		return XMLCorePlugin.getDefault().getPluginPreferences();
	}

	/**
	 * This method will find the indentation for this node. It will search
	 * backwards starting from the beginning of the node until a character
	 * other than a space or a tab is found. If this node is null or it's a
	 * document node or it's a first level node (node's parent is a document
	 * node) the default empty string will be returned as the indentation.
	 */
	protected String getNodeIndent(Node node) {
		String result = EMPTY_STRING;

		if ((node != null) && (node.getNodeType() != Node.DOCUMENT_NODE) && (node.getParentNode() != null) && (node.getParentNode().getNodeType() != Node.DOCUMENT_NODE)) {
			XMLNode siblingTextNode = (XMLNode) node.getPreviousSibling();
			if ((siblingTextNode != null) && (siblingTextNode.getNodeType() == Node.TEXT_NODE)) {
				// find the indentation
				String siblingText = siblingTextNode.getNodeValue();
				int siblingTextLength = siblingText.length();
				if ((siblingText != null) && (siblingTextLength > 0) && ((siblingText.charAt(siblingTextLength - 1) == SPACE_CHAR) || (siblingText.charAt(siblingTextLength - 1) == TAB_CHAR))) {
					int searchIndex = siblingTextLength - 1;
					while ((searchIndex >= 0) && ((siblingText.charAt(searchIndex) == SPACE_CHAR) || (siblingText.charAt(searchIndex) == TAB_CHAR)))
						searchIndex--;

					if (searchIndex < siblingTextLength)
						result = siblingText.substring(searchIndex + 1, siblingTextLength);
				}
			}
		}

		return result;
	}

	protected String getNodeName(XMLNode node) {
		return node.getNodeName();
	}

	protected String getNodeText(XMLNode node) {
		String text = null;

		if ((node instanceof org.eclipse.wst.xml.core.internal.document.CharacterDataImpl) && !(node instanceof org.eclipse.wst.xml.core.internal.document.CommentImpl) && !(node instanceof org.eclipse.wst.xml.core.internal.document.CDATASectionImpl) && !isJSPTag(node))
			text = ((org.eclipse.wst.xml.core.internal.document.CharacterDataImpl) node).getSource();
		else
			text = node.getFirstStructuredDocumentRegion().getText();

		return text;
	}

	protected XMLNode getParentIndentNode(XMLNode node) {
		XMLNode result = null;
		XMLNode parentNode = (XMLNode) node.getParentNode();

		if (parentNode.getNodeType() == Node.DOCUMENT_NODE)
			result = parentNode;
		else {
			ITextRegion region = parentNode.getLastStructuredDocumentRegion().getFirstRegion();
			if (region.getType() == XMLRegionContext.XML_END_TAG_OPEN)
				result = parentNode;
			else
				result = getParentIndentNode(parentNode);
		}

		return result;
	}

	/**
	 * This method will find the indentation for a node sibling to this node.
	 * It will try to find a sibling node before this node first. If there is
	 * no sibling node before this node, it will try to find a sibling node
	 * after this node. If still not found, we will check if this node is
	 * already indented from its parent. If yes, this node's indentation will
	 * be used. Otherwise, the parent node's indentation plus one indentation
	 * will be used. If this node is null or it's a document node or it's a
	 * first level node (node's parent is a document node) the default empty
	 * string will be returned as the indentation.
	 */
	protected String getSiblingIndent(Node node) {
		String result = EMPTY_STRING;

		if ((node != null) && (node.getNodeType() != Node.DOCUMENT_NODE) && (node.getParentNode() != null) && (node.getParentNode().getNodeType() != Node.DOCUMENT_NODE)) {
			// find the text node before the previous non-text sibling
			// if that's not found, we will try the text node before the next
			// non-text sibling
			XMLNode sibling = (XMLNode) node.getPreviousSibling();
			while ((sibling != null) && (sibling.getNodeType() == Node.TEXT_NODE || sibling.getNodeType() == Node.COMMENT_NODE)) {
				if (sibling.getNodeType() == Node.COMMENT_NODE && sibling.getPreviousSibling() != null && sibling.getPreviousSibling().getNodeType() == Node.TEXT_NODE && StringUtils.containsLineDelimiter(sibling.getPreviousSibling().getNodeValue()))
					break;
				sibling = (XMLNode) sibling.getPreviousSibling();
			}
			if (sibling == null) {
				sibling = (XMLNode) node.getNextSibling();
				while ((sibling != null) && (sibling.getNodeType() == Node.TEXT_NODE))
					sibling = (XMLNode) sibling.getNextSibling();
			}
			String singleIndent = getFormatPreferences().getIndent();
			String parentLineIndent = getNodeIndent(node.getParentNode());

			if (sibling != null) {
				String siblingIndent = getNodeIndent(sibling);
				if (siblingIndent.length() > 0)
					result = siblingIndent;
				else {
					String nodeIndent = getNodeIndent(node);
					if (nodeIndent.length() > parentLineIndent.length())
						// this node is indented from its parent, its
						// indentation will be used
						result = nodeIndent;
					else
						result = parentLineIndent + singleIndent;
				}
			} else {
				String nodeIndent = getNodeIndent(node);
				if (nodeIndent.length() > parentLineIndent.length())
					// this node is indented from its parent, its indentation
					// will be used
					result = nodeIndent;
				else
					result = parentLineIndent + singleIndent;
			}
		}

		return result;
	}

	protected void insertAfterNode(XMLNode node, String string) {
		XMLModel structuredModel = node.getModel();
		IStructuredDocument structuredDocument = structuredModel.getStructuredDocument();

		int offset = node.getEndOffset();
		int length = 0;

		// 261968 - formatting tag without closing bracket: <t1><t1
		if (node.getEndStructuredDocumentRegion() != null) {
			offset = node.getEndStructuredDocumentRegion().getTextEndOffset();
			length = node.getEndOffset() - offset;
		}
		replace(structuredDocument, offset, length, string);
	}

	protected void insertBeforeNode(XMLNode node, String string) {
		XMLModel structuredModel = node.getModel();
		IStructuredDocument structuredDocument = structuredModel.getStructuredDocument();

		replace(structuredDocument, node.getStartOffset(), 0, string);
	}

	/**
	 * Allowing the INodeAdapter to compare itself against the type allows it
	 * to return true in more than one case.
	 */
	public boolean isAdapterForType(Object type) {
		return type.equals(IStructuredFormatter.class);
	}

	protected boolean isEndTagMissing(XMLNode node) {
		boolean result = false;

		if ((node != null) && (node.getNodeType() != Node.DOCUMENT_NODE) && !isJSPTag(node)) {
			IStructuredDocumentRegion startTagStructuredDocumentRegion = node.getFirstStructuredDocumentRegion();
			IStructuredDocumentRegion endTagStructuredDocumentRegion = node.getLastStructuredDocumentRegion();

			ITextRegion startTagNameRegion = null;
			if (startTagStructuredDocumentRegion.getRegions().size() > 1)
				startTagNameRegion = startTagStructuredDocumentRegion.getRegions().get(1);
			ITextRegion endTagNameRegion = null;
			if (endTagStructuredDocumentRegion.getRegions().size() > 1)
				endTagNameRegion = endTagStructuredDocumentRegion.getRegions().get(1);

			ITextRegionList startTagRegions = startTagStructuredDocumentRegion.getRegions();
			if (startTagNameRegion == endTagNameRegion && startTagNameRegion != null && (startTagRegions.get(0)).getType() != XMLRegionContext.XML_END_TAG_OPEN && (startTagRegions.get(startTagRegions.size() - 1).getType()) != XMLRegionContext.XML_EMPTY_TAG_CLOSE)
				// end tag missing
				result = true;
		}

		return result;
	}

	protected boolean isJSPTag(XMLNode node) {
		boolean result = false;

		IStructuredDocumentRegion flatNode = node.getFirstStructuredDocumentRegion();
		// in some cases, the nodes exists, but hasn't been associated with
		// a flatnode yet (the screen updates can be initiated on a different
		// thread,
		// so the request for a flatnode can come in before the node is fully
		// formed.
		// if the flatnode is null, we'll just allow the defaults to apply.
		// (html adapter in this case).
		if (flatNode != null) {
			String flatNodeType = flatNode.getType();
			if ((flatNodeType == XMLJSPRegionContexts.JSP_CONTENT) || (flatNodeType == XMLJSPRegionContexts.JSP_EXPRESSION_OPEN) || (flatNodeType == XMLJSPRegionContexts.JSP_SCRIPTLET_OPEN) || (flatNodeType == XMLJSPRegionContexts.JSP_DECLARATION_OPEN) || (flatNodeType == XMLJSPRegionContexts.JSP_DIRECTIVE_CLOSE) || (flatNodeType == XMLJSPRegionContexts.JSP_DIRECTIVE_NAME) || (flatNodeType == XMLJSPRegionContexts.JSP_DIRECTIVE_OPEN) || (flatNodeType == XMLJSPRegionContexts.JSP_CLOSE)) {
				result = true;
			}
		}

		return result;
	}

	protected boolean nodeHasSiblings(XMLNode node) {
		return (node.getPreviousSibling() != null) || (node.getNextSibling() != null);
	}

	/**
	 * Node changed. No format should be performed automatically.
	 */
	public void notifyChanged(org.eclipse.wst.sse.core.INodeNotifier notifier, int eventType, Object changedFeature, Object oldValue, Object newValue, int pos) {
	}

	protected void removeRegionSpaces(XMLNode node, IStructuredDocumentRegion flatNode, ITextRegion region) {
		if ((region != null) && (region instanceof ContextRegion || region instanceof TagNameRegion) && (flatNode.getEndOffset(region) > flatNode.getTextEndOffset(region))) {
			XMLModel structuredModel = node.getModel();
			IStructuredDocument structuredDocument = structuredModel.getStructuredDocument();

			replace(structuredDocument, flatNode.getTextEndOffset(region), flatNode.getEndOffset(region) - flatNode.getTextEndOffset(region), EMPTY_STRING);
		}
	}

	/**
	 * This method will replace the string at offset and length with a new
	 * string. If the string to be replaced is the same as the new string, the
	 * string will not be replaced.
	 */
	protected void replace(IStructuredDocument structuredDocument, int offset, int length, String string) {
		try {
			String structuredDocumentString = structuredDocument.get(offset, length);
			if (structuredDocumentString.compareTo(string) != 0)
				structuredDocument.replaceText(structuredDocument, offset, length, string);
		} catch (BadLocationException exception) {
			throw new SourceEditingRuntimeException(exception);
		}
	}

	/**
	 * This method will replace the node value with a new string. If the node
	 * value to be replaced is the same as the new string, the node value will
	 * not be replaced.
	 */
	protected void replaceNodeValue(XMLNode node, String string) {
		XMLModel structuredModel = node.getModel();
		IStructuredDocument structuredDocument = structuredModel.getStructuredDocument();
		int offset = node.getStartOffset();
		int length = node.getEndOffset() - node.getStartOffset();

		try {
			String structuredDocumentString = structuredDocument.get(offset, length);
			if (structuredDocumentString.compareTo(string) != 0)
				replace(structuredDocument, offset, length, string);
		} catch (BadLocationException exception) {
			throw new SourceEditingRuntimeException(exception);
		}
	}

	public void setFormatPreferences(IStructuredFormatPreferences formatPreferences) {
		fFormatPreferences = formatPreferences;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.wst.sse.core.format.IStructuredFormatter#setProgressMonitor(org.eclipse.core.runtime.IProgressMonitor)
	 */
	public void setProgressMonitor(IProgressMonitor monitor) {
		fProgressMonitor = monitor;
	}
}
