/*******************************************************************************
 * Copyright (c) 2001, 2004 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Jens Lukowski/Innoopract - initial renaming/restructuring
 *     
 *******************************************************************************/
package org.eclipse.wst.xml.core.internal.document;



import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion;
import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMText;
import org.eclipse.wst.xml.core.internal.provisional.document.ISourceGenerator;
import org.eclipse.wst.xml.core.internal.regions.DOMRegionContext;
import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.Text;


/**
 * TextImpl class
 */
public class TextImpl extends CharacterDataImpl implements IDOMText {

	/**
	 */
	private class StringPair {
		private String fFirst = null;
		private String fSecond = null;

		StringPair(String first, String second) {
			this.fFirst = first;
			this.fSecond = second;
		}

		String getFirst() {
			return this.fFirst;
		}

		String getSecond() {
			return this.fSecond;
		}
	}

	private String fSource = null;

	/**
	 * TextImpl constructor
	 */
	protected TextImpl() {
		super();
	}

	/**
	 * TextImpl constructor
	 * 
	 * @param that
	 *            TextImpl
	 */
	protected TextImpl(TextImpl that) {
		super(that);

		if (that != null) {
			this.fSource = that.getSource();
		}
	}

	/**
	 * appendData method
	 * 
	 * @param arg
	 *            java.lang.String
	 */
	public void appendData(String arg) throws DOMException {
		if (arg == null || arg.length() == 0)
			return;

		if (!isDataEditable()) {
			throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, new String());
		}

		String newSource = getSource(arg);
		if (newSource == null)
			return;
		String source = getSource();
		if (source != null)
			setTextSource(source + newSource);
		else
			setTextSource(newSource);
	}

	/**
	 */
	IStructuredDocumentRegion appendStructuredDocumentRegion(IStructuredDocumentRegion newStructuredDocumentRegion) {
		if (newStructuredDocumentRegion == null)
			return null;

		IStructuredDocumentRegion flatNode = getStructuredDocumentRegion();
		if (flatNode == null) {
			setStructuredDocumentRegion(newStructuredDocumentRegion);
			return newStructuredDocumentRegion;
		}

		if (flatNode instanceof StructuredDocumentRegionContainer) {
			StructuredDocumentRegionContainer container = (StructuredDocumentRegionContainer) flatNode;
			container.appendStructuredDocumentRegion(newStructuredDocumentRegion);
		}
		else {
			StructuredDocumentRegionContainer container = new StructuredDocumentRegionContainer();
			container.appendStructuredDocumentRegion(flatNode);
			container.appendStructuredDocumentRegion(newStructuredDocumentRegion);
			setStructuredDocumentRegion(container);
		}

		return newStructuredDocumentRegion;
	}

	/**
	 * appendText method
	 * 
	 * @param text
	 *            org.w3c.dom.Text
	 */
	public void appendText(Text newText) {
		if (newText == null)
			return;

		if (!isDataEditable()) {
			throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, new String());
		}

		TextImpl text = (TextImpl) newText;
		String newSource = text.getSource();
		if (newSource == null && newSource.length() == 0)
			return;
		String source = getSource();
		if (source != null)
			setTextSource(source + newSource);
		else
			setTextSource(newSource);
	}

	/**
	 * cloneNode method
	 * 
	 * @return org.w3c.dom.Node
	 * @param deep
	 *            boolean
	 */
	public Node cloneNode(boolean deep) {
		TextImpl cloned = new TextImpl(this);
		return cloned;
	}

	/**
	 * deleteData method
	 * 
	 * @param offset
	 *            int
	 * @param count
	 *            int
	 */
	public void deleteData(int offset, int count) throws DOMException {
		if (count == 0)
			return;
		if (!isDataEditable()) {
			throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, new String());
		}
		if (count < 0 || offset < 0) {
			throw new DOMException(DOMException.INDEX_SIZE_ERR, new String());
		}

		String source = getSource();
		if (source == null || source.length() == 0) {
			throw new DOMException(DOMException.INDEX_SIZE_ERR, new String());
		}
		StringPair pair = substringSourceExcluded(source, offset, count);
		if (pair == null)
			return;
		source = null;
		String first = pair.getFirst();
		if (first != null)
			source = first;
		String second = pair.getSecond();
		if (second != null) {
			if (source != null)
				source += second;
			else
				source = second;
		}
		if (source == null)
			source = new String(); // delete all
		setTextSource(source);
	}

	/**
	 * getData method
	 * 
	 * @return java.lang.String
	 */
	public String getData() throws DOMException {
		if (this.fSource != null)
			return getData(this.fSource);
		String data = super.getData();
		if (data != null)
			return data;
		return getData(getStructuredDocumentRegion());
	}

	/**
	 */
	private String getData(IStructuredDocumentRegion flatNode) {
		if (flatNode == null)
			return new String();

		if (flatNode instanceof StructuredDocumentRegionContainer) {
			StructuredDocumentRegionContainer container = (StructuredDocumentRegionContainer) flatNode;
			int length = container.getLength();
			if (length < 16)
				length = 16; // default
			StringBuffer buffer = new StringBuffer(length);
			int count = container.getStructuredDocumentRegionCount();
			for (int i = 0; i < count; i++) {
				IStructuredDocumentRegion content = container.getStructuredDocumentRegion(i);
				String data = getData(content);
				if (data == null)
					continue;
				buffer.append(data);
			}
			return buffer.toString();
		}

		if (flatNode instanceof StructuredDocumentRegionProxy) {
			return flatNode.getText();
		}

		ITextRegion region = StructuredDocumentRegionUtil.getFirstRegion(flatNode);
		if (region != null) {
			String regionType = region.getType();
			if (regionType == DOMRegionContext.XML_ENTITY_REFERENCE || regionType == DOMRegionContext.XML_CHAR_REFERENCE) {
				String name = StructuredDocumentRegionUtil.getEntityRefName(flatNode, region);
				if (name != null) {
					DocumentImpl document = (DocumentImpl) getOwnerDocument();
					if (document != null) {
						String value = document.getCharValue(name);
						if (value != null)
							return value;
					}
				}
			}
		}

		return flatNode.getText();
	}

	/**
	 * Returns data for the source
	 */
	private String getData(String source) {
		if (source == null)
			return null;
		StringBuffer buffer = null;
		int offset = 0;
		int length = source.length();
		int ref = source.indexOf('&');
		while (ref >= 0) {
			int end = source.indexOf(';', ref + 1);
			if (end > ref + 1) {
				String name = source.substring(ref + 1, end);
				String value = getCharValue(name);
				if (value != null) {
					if (buffer == null)
						buffer = new StringBuffer(length);
					if (ref > offset)
						buffer.append(source.substring(offset, ref));
					buffer.append(value);
					offset = end + 1;
					ref = end;
				}
			}
			ref = source.indexOf('&', ref + 1);
		}
		if (buffer == null)
			return source;
		if (length > offset)
			buffer.append(source.substring(offset));
		return buffer.toString();
	}

	/**
	 * getFirstStructuredDocumentRegion method
	 * 
	 */
	public IStructuredDocumentRegion getFirstStructuredDocumentRegion() {
		return StructuredDocumentRegionUtil.getFirstStructuredDocumentRegion(getStructuredDocumentRegion());
	}

	/**
	 * getLastStructuredDocumentRegion method
	 * 
	 */
	public IStructuredDocumentRegion getLastStructuredDocumentRegion() {
		return StructuredDocumentRegionUtil.getLastStructuredDocumentRegion(getStructuredDocumentRegion());
	}

	/**
	 * getNodeName method
	 * 
	 * @return java.lang.String
	 */
	public String getNodeName() {
		return "#text";//$NON-NLS-1$
	}

	/**
	 * getNodeType method
	 * 
	 * @return short
	 */
	public short getNodeType() {
		return TEXT_NODE;
	}

	/**
	 */
	public String getSource() {
		if (this.fSource != null)
			return this.fSource;
		String data = super.getData();
		if (data != null && data.length() > 0) {
			String source = getSource(data);
			if (source != null)
				return source;
		}
		return super.getSource();
	}

	/**
	 * Returns source for the data
	 */
	private String getSource(String data) {
		if (data == null)
			return null;
		IDOMModel model = getModel();
		if (model == null)
			return null; // error
		ISourceGenerator generator = model.getGenerator();
		if (generator == null)
			return null; // error
		return generator.generateTextData(this, data);
	}

	/**
	 */
	String getTextSource() {
		return this.fSource;
	}

	/**
	 */
	public String getValueSource() {
		return getSource();
	}

	/**
	 */
	boolean hasStructuredDocumentRegion(IStructuredDocumentRegion askedStructuredDocumentRegion) {
		if (askedStructuredDocumentRegion == null)
			return false;

		IStructuredDocumentRegion flatNode = getStructuredDocumentRegion();
		if (flatNode == null)
			return false;

		if (flatNode == askedStructuredDocumentRegion)
			return true;

		if (flatNode instanceof StructuredDocumentRegionProxy) {
			StructuredDocumentRegionProxy proxy = (StructuredDocumentRegionProxy) flatNode;
			if (proxy.getStructuredDocumentRegion() == askedStructuredDocumentRegion)
				return true;
			return false;
		}

		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;
				if (content == askedStructuredDocumentRegion)
					return true;
				if (content instanceof StructuredDocumentRegionProxy) {
					StructuredDocumentRegionProxy proxy = (StructuredDocumentRegionProxy) content;
					if (proxy.getStructuredDocumentRegion() == askedStructuredDocumentRegion)
						return true;
				}
			}
			return false;
		}

		return false;
	}

	/**
	 * insertData method
	 * 
	 * @param offset
	 *            int
	 * @param arg
	 *            java.lang.String
	 */
	public void insertData(int offset, String arg) throws DOMException {
		if (arg == null || arg.length() == 0)
			return;
		if (!isDataEditable()) {
			throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, new String());
		}
		if (offset < 0) {
			throw new DOMException(DOMException.INDEX_SIZE_ERR, new String());
		}

		String source = getSource();
		if (source == null || source.length() == 0) {
			if (offset > 0) {
				throw new DOMException(DOMException.INDEX_SIZE_ERR, new String());
			}
			source = getSource(arg);
			if (source != null)
				setTextSource(source);
			return;
		}

		StringPair pair = substringSourceExcluded(source, offset, 0);
		if (pair == null)
			return; // error
		StringBuffer buffer = new StringBuffer(source.length() + arg.length());
		String first = pair.getFirst();
		if (first != null)
			buffer.append(first);
		source = getSource(arg);
		if (source != null)
			buffer.append(source);
		String second = pair.getSecond();
		if (second != null)
			buffer.append(second);
		setTextSource(buffer.toString());
	}

	/**
	 */
	IStructuredDocumentRegion insertStructuredDocumentRegion(IStructuredDocumentRegion newStructuredDocumentRegion, IStructuredDocumentRegion nextStructuredDocumentRegion) {
		if (newStructuredDocumentRegion == null)
			return null;
		if (nextStructuredDocumentRegion == null)
			return appendStructuredDocumentRegion(newStructuredDocumentRegion);

		IStructuredDocumentRegion flatNode = getStructuredDocumentRegion();
		if (flatNode == null)
			return null; // error

		if (flatNode == nextStructuredDocumentRegion) {
			StructuredDocumentRegionContainer container = new StructuredDocumentRegionContainer();
			container.appendStructuredDocumentRegion(newStructuredDocumentRegion);
			container.appendStructuredDocumentRegion(flatNode);
			setStructuredDocumentRegion(container);
			return newStructuredDocumentRegion;
		}

		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 == nextStructuredDocumentRegion) {
					container.insertStructuredDocumentRegion(newStructuredDocumentRegion, i);
					return newStructuredDocumentRegion;
				}
			}
			return null; // error
		}

		return null; // error
	}

	/**
	 * insertText method
	 * 
	 * @param text
	 *            org.w3c.dom.Text
	 * @param offset
	 *            int
	 */
	public void insertText(Text newText, int offset) throws DOMException {
		if (newText == null)
			return;
		if (!isDataEditable()) {
			throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, new String());
		}
		TextImpl text = (TextImpl) newText;
		String newSource = text.getSource();
		if (newSource == null && newSource.length() == 0)
			return;
		if (offset < 0) {
			throw new DOMException(DOMException.INDEX_SIZE_ERR, new String());
		}

		String source = getSource();
		if (source == null || source.length() == 0) {
			if (offset > 0) {
				throw new DOMException(DOMException.INDEX_SIZE_ERR, new String());
			}
			setTextSource(newSource);
			return;
		}

		StringPair pair = substringSourceExcluded(source, offset, 0);
		if (pair == null)
			return; // error
		StringBuffer buffer = new StringBuffer(source.length() + newSource.length());
		String first = pair.getFirst();
		if (first != null)
			buffer.append(first);
		buffer.append(newSource);
		String second = pair.getSecond();
		if (second != null)
			buffer.append(second);
		setTextSource(buffer.toString());
	}

	/**
	 * isCDATAContent method
	 * 
	 * @return boolean
	 */
	public boolean isCDATAContent() {
		Node parent = getParentNode();
		if (parent == null || parent.getNodeType() != Node.ELEMENT_NODE)
			return false;
		ElementImpl element = (ElementImpl) parent;
		return element.isCDATAContainer();
	}

	/**
	 */
	public boolean isInvalid() {
		return isInvalid(getStructuredDocumentRegion());
	}

	/**
	 */
	private boolean isInvalid(IStructuredDocumentRegion flatNode) {
		if (flatNode == null)
			return false;

		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 (isInvalid(content))
					return true;
			}
			return false;
		}

		if (flatNode instanceof StructuredDocumentRegionProxy) {
			StructuredDocumentRegionProxy proxy = (StructuredDocumentRegionProxy) flatNode;
			return isInvalid(proxy.getStructuredDocumentRegion());
		}

		String regionType = StructuredDocumentRegionUtil.getFirstRegionType(flatNode);
		if (regionType != DOMRegionContext.XML_CONTENT && isNotNestedContent(regionType) && regionType != DOMRegionContext.XML_ENTITY_REFERENCE && regionType != DOMRegionContext.XML_CHAR_REFERENCE && regionType != DOMRegionContext.BLOCK_TEXT && regionType != DOMRegionContext.WHITE_SPACE) {
			return true;
		}

		return false;
	}

	protected boolean isNotNestedContent(String regionType) {
		boolean result = true;
		return result;
	}

	/**
	 */
	boolean isSharingStructuredDocumentRegion(IStructuredDocumentRegion sharedStructuredDocumentRegion) {
		if (sharedStructuredDocumentRegion == null)
			return false;

		IStructuredDocumentRegion flatNode = getStructuredDocumentRegion();
		if (flatNode == null)
			return false;

		if (flatNode == sharedStructuredDocumentRegion)
			return false;

		if (flatNode instanceof StructuredDocumentRegionProxy) {
			StructuredDocumentRegionProxy proxy = (StructuredDocumentRegionProxy) flatNode;
			if (proxy.getStructuredDocumentRegion() == sharedStructuredDocumentRegion)
				return true;
			return false;
		}

		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;
				if (content == sharedStructuredDocumentRegion)
					return false;
				if (content instanceof StructuredDocumentRegionProxy) {
					StructuredDocumentRegionProxy proxy = (StructuredDocumentRegionProxy) content;
					if (proxy.getStructuredDocumentRegion() == sharedStructuredDocumentRegion)
						return true;
				}
			}
			return false;
		}

		return false;
	}

	/**
	 * Returns whether this text node contains <a
	 * href='http://www.w3.org/TR/2004/REC-xml-infoset-20040204#infoitem.character'>
	 * element content whitespace</a>, often abusively called "ignorable
	 * whitespace". The text node is determined to contain whitespace in
	 * element content during the load of the document or if validation occurs
	 * while using <code>Document.normalizeDocument()</code>.
	 * 
	 * @see DOM Level 3
	 */
	public boolean isElementContentWhitespace() {
		return isWhitespace();
	}

	/**
	 */
	public boolean isWhitespace() {
		String data = getData();
		if (data == null)
			return true;
		int length = data.length();
		for (int i = 0; i < length; i++) {
			if (!Character.isWhitespace(data.charAt(i)))
				return false;
		}
		return true;
	}

	/**
	 */
	IStructuredDocumentRegion removeStructuredDocumentRegion(IStructuredDocumentRegion oldStructuredDocumentRegion) {
		if (oldStructuredDocumentRegion == null)
			return null;

		IStructuredDocumentRegion flatNode = getStructuredDocumentRegion();
		if (flatNode == null)
			return null; // error

		if (flatNode == oldStructuredDocumentRegion) {
			setStructuredDocumentRegion(null);
			return oldStructuredDocumentRegion;
		}

		if (flatNode instanceof StructuredDocumentRegionProxy) {
			StructuredDocumentRegionProxy proxy = (StructuredDocumentRegionProxy) flatNode;
			if (proxy.getStructuredDocumentRegion() == oldStructuredDocumentRegion) {
				// removed with proxy
				setStructuredDocumentRegion(null);
				return oldStructuredDocumentRegion;
			}
			return null; // error
		}

		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 == oldStructuredDocumentRegion) {
					container.removeStructuredDocumentRegion(i);
					if (container.getStructuredDocumentRegionCount() == 1) {
						// get back to single IStructuredDocumentRegion
						setStructuredDocumentRegion(container.getStructuredDocumentRegion(0));
					}
					return oldStructuredDocumentRegion;
				}

				if (content instanceof StructuredDocumentRegionProxy) {
					StructuredDocumentRegionProxy proxy = (StructuredDocumentRegionProxy) content;
					if (proxy.getStructuredDocumentRegion() == oldStructuredDocumentRegion) {
						// removed with proxy
						container.removeStructuredDocumentRegion(i);
						if (container.getStructuredDocumentRegionCount() == 1) {
							// get back to single IStructuredDocumentRegion
							setStructuredDocumentRegion(container.getStructuredDocumentRegion(0));
						}
						return oldStructuredDocumentRegion;
					}
				}
			}
			return null; // error
		}

		return null; // error
	}

	/**
	 * replaceData method
	 * 
	 * @param offset
	 *            int
	 * @param count
	 *            int
	 * @param arg
	 *            java.lang.String
	 */
	public void replaceData(int offset, int count, String arg) throws DOMException {
		if (!isDataEditable()) {
			throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, new String());
		}
		if (arg == null || arg.length() == 0) {
			deleteData(offset, count);
			return;
		}
		if (count == 0) {
			insertData(offset, arg);
			return;
		}
		if (offset < 0 || count < 0) {
			throw new DOMException(DOMException.INDEX_SIZE_ERR, new String());
		}

		String source = getSource();
		if (source == null || source.length() == 0) {
			throw new DOMException(DOMException.INDEX_SIZE_ERR, new String());
		}

		StringPair pair = substringSourceExcluded(source, offset, count);
		if (pair == null)
			return; // error
		StringBuffer buffer = new StringBuffer(source.length() + arg.length());
		String first = pair.getFirst();
		if (first != null)
			buffer.append(first);
		source = getSource(arg);
		if (source != null)
			buffer.append(source);
		String second = pair.getSecond();
		if (second != null)
			buffer.append(second);
		setTextSource(buffer.toString());
	}

	/**
	 */
	IStructuredDocumentRegion replaceStructuredDocumentRegion(IStructuredDocumentRegion newStructuredDocumentRegion, IStructuredDocumentRegion oldStructuredDocumentRegion) {
		if (oldStructuredDocumentRegion == null)
			return null;
		if (newStructuredDocumentRegion == null)
			return removeStructuredDocumentRegion(oldStructuredDocumentRegion);

		IStructuredDocumentRegion flatNode = getStructuredDocumentRegion();
		if (flatNode == null)
			return null; // error

		if (flatNode == oldStructuredDocumentRegion) {
			setStructuredDocumentRegion(newStructuredDocumentRegion);
			return oldStructuredDocumentRegion;
		}

		if (flatNode instanceof StructuredDocumentRegionProxy) {
			StructuredDocumentRegionProxy proxy = (StructuredDocumentRegionProxy) flatNode;
			if (proxy.getStructuredDocumentRegion() == oldStructuredDocumentRegion) {
				if (newStructuredDocumentRegion instanceof StructuredDocumentRegionProxy) {
					// proxy must not be nested
					setStructuredDocumentRegion(newStructuredDocumentRegion);
				}
				else {
					proxy.setStructuredDocumentRegion(newStructuredDocumentRegion);
				}
				return oldStructuredDocumentRegion;
			}
			return null; // error
		}

		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) {
					container.replaceStructuredDocumentRegion(newStructuredDocumentRegion, i);
					return oldStructuredDocumentRegion;
				}

				if (content instanceof StructuredDocumentRegionProxy) {
					StructuredDocumentRegionProxy proxy = (StructuredDocumentRegionProxy) content;
					if (proxy.getStructuredDocumentRegion() == oldStructuredDocumentRegion) {
						if (newStructuredDocumentRegion instanceof StructuredDocumentRegionProxy) {
							// proxy must not be nested
							container.replaceStructuredDocumentRegion(newStructuredDocumentRegion, i);
						}
						else {
							proxy.setStructuredDocumentRegion(newStructuredDocumentRegion);
						}
						return oldStructuredDocumentRegion;
					}
				}
			}
			return null; // error
		}

		return null; // error
	}

	/**
	 */
	void resetStructuredDocumentRegions() {
		String source = getSource();
		if (source != null && source.length() > 0)
			this.fSource = source;
		super.resetStructuredDocumentRegions();
	}

	/**
	 * getData method
	 * 
	 * @return java.lang.String
	 */
	public void setData(String data) throws DOMException {
		if (!isDataEditable()) {
			throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, new String());
		}

		this.fSource = null;
		super.setData(data);
	}

	/**
	 */
	public void setSource(String source) throws InvalidCharacterException {
		if (!isDataEditable()) {
			throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, new String());
		}

		SourceValidator validator = new SourceValidator(this);
		if (validator.validateSource(source))
			setTextSource(source);
	}

	/**
	 */
	void setStructuredDocumentRegion(IStructuredDocumentRegion flatNode) {
		super.setStructuredDocumentRegion(flatNode);
		if (flatNode != null)
			this.fSource = null;
	}

	/**
	 */
	public void setTextSource(String source) {
		if (!isDataEditable()) {
			throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, new String());
		}

		this.fSource = source;

		notifyValueChanged();
	}

	/**
	 */
	public void setValueSource(String source) {
		if (!isDataEditable()) {
			throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, new String());
		}

		SourceValidator validator = new SourceValidator(this);
		setTextSource(validator.convertSource(source));
	}

	/**
	 * splitText method
	 * 
	 * @return org.w3c.dom.Text
	 * @param offset
	 *            int
	 */
	public Text splitText(int offset) throws DOMException {
		if (!isDataEditable()) {
			throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, new String());
		}
		if (offset < 0) {
			throw new DOMException(DOMException.INDEX_SIZE_ERR, new String());
		}
		int length = getLength();
		if (offset > length) {
			throw new DOMException(DOMException.INDEX_SIZE_ERR, new String());
		}
		Document document = getOwnerDocument();
		if (document == null)
			return null;

		String source = null;
		if (offset < length) {
			int count = length - offset;
			source = substringSource(offset, count);
			deleteData(offset, count);
		}
		TextImpl text = (TextImpl) document.createTextNode(null);
		if (source != null)
			text.setTextSource(source);

		Node parent = getParentNode();
		if (parent != null)
			parent.insertBefore(text, getNextSibling());

		return text;
	}

	/**
	 */
	Text splitText(IStructuredDocumentRegion nextStructuredDocumentRegion) {
		if (nextStructuredDocumentRegion == null)
			return null;

		IStructuredDocumentRegion flatNode = getStructuredDocumentRegion();
		if (flatNode == null || !(flatNode instanceof StructuredDocumentRegionContainer))
			return null; // error

		StructuredDocumentRegionContainer container = (StructuredDocumentRegionContainer) flatNode;
		int count = container.getStructuredDocumentRegionCount();
		int index = 0;
		for (; index < count; index++) {
			if (container.getStructuredDocumentRegion(index) == nextStructuredDocumentRegion)
				break;
		}
		if (index >= count) {
			// this is the case nextStructuredDocumentRegion is a new
			// IStructuredDocumentRegion
			// search gap by offset
			int offset = nextStructuredDocumentRegion.getStart();
			for (index = 0; index < count; index++) {
				IStructuredDocumentRegion content = container.getStructuredDocumentRegion(index);
				if (content == null)
					continue; // error
				if (content.getStart() >= offset)
					break;
			}
			if (index >= count)
				return null; // error
		}
		if (index == 0)
			return this; // nothing to do

		Document document = getOwnerDocument();
		if (document == null)
			return null; // error
		Node parent = getParentNode();
		if (parent == null)
			return null; // error
		TextImpl nextText = (TextImpl) document.createTextNode(null);
		if (nextText == null)
			return null; // error

		for (; index < count; count--) {
			nextText.appendStructuredDocumentRegion(container.removeStructuredDocumentRegion(index));
		}

		// normalize IStructuredDocumentRegion
		if (index == 1) {
			setStructuredDocumentRegion(container.getStructuredDocumentRegion(0));
		}

		parent.insertBefore(nextText, getNextSibling());
		return nextText;
	}

	/**
	 * Retruns data for the range
	 */
	private String substringData(String data, int offset, int count) throws DOMException {
		// sure offset and count are non-negative
		if (count == 0)
			return new String();
		if (data == null) {
			throw new DOMException(DOMException.INDEX_SIZE_ERR, new String());
		}
		int length = data.length();
		if (offset > length) {
			throw new DOMException(DOMException.INDEX_SIZE_ERR, new String());
		}
		int end = offset + count;
		if (end > length) {
			throw new DOMException(DOMException.INDEX_SIZE_ERR, new String());
		}
		return data.substring(offset, end);
	}

	/**
	 * Returns source for the range specified by: offset: data offset count:
	 * data count
	 */
	private String substringSource(int offset, int count) throws DOMException {
		// sure offset and count are non-negative
		if (this.fSource != null)
			return substringSource(this.fSource, offset, count);

		String data = super.getData();
		if (data != null && data.length() > 0) {
			data = substringData(data, offset, count);
			if (data == null)
				return new String();
			String source = getSource(data);
			if (source != null)
				return source;
		}

		return substringSource(getSource(), offset, count);
	}

	/**
	 * Returns source for the range specified by: offset: data offset count:
	 * data count
	 */
	private String substringSource(String source, int offset, int count) throws DOMException {
		// sure offset and count are non-negative
		if (count == 0)
			return new String();
		if (source == null) {
			throw new DOMException(DOMException.INDEX_SIZE_ERR, new String());
		}

		int length = source.length();
		int end = offset + count;

		// find character reference
		int ref = source.indexOf('&');
		while (ref >= 0) {
			if (ref >= end)
				break;
			int refEnd = source.indexOf(';', ref + 1);
			if (refEnd > ref + 1) {
				String name = source.substring(ref + 1, refEnd);
				if (getCharValue(name) != null) {
					// found, shift for source offsets
					int refCount = refEnd - ref;
					if (ref < offset)
						offset += refCount;
					if (ref < end)
						end += refCount;
					ref = refEnd;
				}
			}
			ref = source.indexOf('&', ref + 1);
		}

		if (offset > length || end > length) {
			throw new DOMException(DOMException.INDEX_SIZE_ERR, new String());
		}

		return source.substring(offset, end);
	}

	/**
	 * Returns sources before and after the range specified by: offset: data
	 * offset count: data count
	 */
	private StringPair substringSourceExcluded(String source, int offset, int count) throws DOMException {
		// sure offset and count are non-negative
		if (source == null) {
			if (offset == 0 && count == 0)
				return new StringPair(null, null);
			throw new DOMException(DOMException.INDEX_SIZE_ERR, new String());
		}

		int length = source.length();
		int end = offset + count;

		// find character reference
		int ref = source.indexOf('&');
		while (ref >= 0) {
			if (ref >= end)
				break;
			int refEnd = source.indexOf(';', ref + 1);
			if (refEnd > ref + 1) {
				String name = source.substring(ref + 1, refEnd);
				if (getCharValue(name) != null) {
					// found, shift for source offsets
					int refCount = refEnd - ref;
					if (ref < offset)
						offset += refCount;
					if (ref < end)
						end += refCount;
					ref = refEnd;
				}
			}
			ref = source.indexOf('&', ref + 1);
		}

		if (offset > length || end > length) {
			throw new DOMException(DOMException.INDEX_SIZE_ERR, new String());
		}

		String first = (offset > 0 ? source.substring(0, offset) : null);
		String second = (end < length ? source.substring(end, length) : null);
		return new StringPair(first, second);
	}

	public String getWholeText() {
		throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Not Implemented in this version."); //$NON-NLS-1$
	}
    /**
	 * Replaces the text of the current node and all logically-adjacent text
	 * nodes with the specified text. All logically-adjacent text nodes are
	 * removed including the current node unless it was the recipient of the
	 * replacement text. <br>
	 * This method returns the node which received the replacement text. The
	 * returned node is:
	 * <ul>
	 * <li><code>null</code>, when the replacement text is the empty
	 * string; </li>
	 * <li>the current node, except when the current node is read-only; </li>
	 * <li> a new <code>Text</code> node of the same type (
	 * <code>Text</code> or <code>CDATASection</code>) as the current
	 * node inserted at the location of the replacement. </li>
	 * </ul>
	 * <br>
	 * For instance, in the above example calling
	 * <code>replaceWholeText</code> on the <code>Text</code> node that
	 * contains "bar" with "yo" in argument results in the following: <br>
	 * Where the nodes to be removed are read-only descendants of an
	 * <code>EntityReference</code>, the <code>EntityReference</code>
	 * must be removed instead of the read-only nodes. If any
	 * <code>EntityReference</code> to be removed has descendants that are
	 * not <code>EntityReference</code>, <code>Text</code>, or
	 * <code>CDATASection</code> nodes, the <code>replaceWholeText</code>
	 * method must fail before performing any modification of the document,
	 * raising a <code>DOMException</code> with the code
	 * <code>NO_MODIFICATION_ALLOWED_ERR</code>. <br>
	 * For instance, in the example below calling
	 * <code>replaceWholeText</code> on the <code>Text</code> node that
	 * contains "bar" fails, because the <code>EntityReference</code> node
	 * "ent" contains an <code>Element</code> node which cannot be removed.
	 * 
	 * @param content
	 *            The content of the replacing <code>Text</code> node.
	 * @return The <code>Text</code> node created with the specified
	 *         content.
	 * @exception DOMException
	 *                NO_MODIFICATION_ALLOWED_ERR: Raised if one of the
	 *                <code>Text</code> nodes being replaced is readonly.
	 * @see DOM Level 3
	 */
    public Text replaceWholeText(String content)
                                 throws DOMException {
		throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Not implemented"); //$NON-NLS-1$
    }
}
