/*******************************************************************************
 * Copyright (c) 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
 *******************************************************************************/
package org.eclipse.wst.jsdt.web.core.internal.java;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;

import org.eclipse.core.filebuffers.FileBuffers;
import org.eclipse.core.filebuffers.ITextFileBuffer;
import org.eclipse.core.filebuffers.ITextFileBufferManager;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.Position;
import org.eclipse.wst.jsdt.web.core.internal.Logger;
import org.eclipse.wst.sse.core.StructuredModelManager;
import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
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.ITextRegion;
import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionCollection;
import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionContainer;
import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionList;
import org.eclipse.wst.sse.core.utils.StringUtils;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
import org.eclipse.wst.xml.core.internal.regions.DOMRegionContext;

/**
 * Translates a JSP document into a HttpServlet. Keeps two way mapping from java
 * translation to the original JSP source, which can be obtained through
 * getJava2JspRanges() and getJsp2JavaRanges().
 * 
 * @author pavery
 */
public class JSPTranslator {

	// for debugging
	private static final boolean DEBUG;

	private static final boolean DEBUG_SAVE_OUTPUT = "true".equalsIgnoreCase(Platform.getDebugOption("org.eclipse.wst.jsdt.web.core/debug/jsptranslationstodisk")); //$NON-NLS-1$  //$NON-NLS-2$

	public static final String ENDL = "\n"; //$NON-NLS-1$


	static {
		String value = Platform.getDebugOption("org.eclipse.wst.jsdt.web.core/debug/jspjavamapping"); //$NON-NLS-1$
		DEBUG = value != null && value.equalsIgnoreCase("true"); //$NON-NLS-1$
		
	}
	
	private IStructuredDocumentRegion fCurrentNode;
	
	private String fClassname;

	/* map of ALL ranges */
	HashMap fJsToHTMLRanges = new HashMap();

	/**
	 * save JSP document text for later use may just want to read this from the
	 * file or strucdtured document depending what is available
	 */
	private StringBuffer fJspTextBuffer = new StringBuffer();

	private IProgressMonitor fProgressMonitor = null;

	private StringBuffer fResult; // the

	// final
	private ArrayList rawImports = new ArrayList(); // traslated

	StringBuffer fScriptText = new StringBuffer();

	private IStructuredDocument fStructuredDocument = null;

	private IDOMModel fStructuredModel = null;

	/* use java script by default */
	private boolean isGlobalJs = true;

	private int scriptOffset = 0;
	
	private ArrayList importLocationsInHtml = new ArrayList();

	private void advanceNextNode() {
		setCurrentNode(getCurrentNode().getNext());

	}

	protected void append(StringBuffer buf) {
		/*
		 * if (getCursorOwner() == buf) { fCursorPosition = fResult.length() +
		 * getRelativeOffset(); }
		 */
		// fCursorPosition = fResult.length();
		fResult.append(buf.toString());
	}

	/**
	 * put the final java document together
	 */
	private final void buildResult() {

		// to build the java document this is the order:
		// 
		// + default imports
		// + user imports
		// + class header
		// [+ error page]
		// + user declarations
		// + service method header
		// + try/catch start
		// + user code
		// + try/catch end
		// + service method footer

		// fResult = new StringBuffer(fImplicitImports.length() +
		// fUserImports.length() + fClassHeader.length() +
		// fUserDeclarations.length() + fServiceHeader.length() +
		// fTryCatchStart.length() // try/catch
		// // start
		// + fUserCode.length() + fTryCatchEnd.length() // try/catch
		// // end
		// + fFooter.length());

		fResult = new StringBuffer(fScriptText.length());
		int javaOffset = 0;
		append(fScriptText);
		javaOffset += fScriptText.length();

		// user imports
		//updateRanges(fImportRanges, javaOffset);
		// append(fUserImports);
		// javaOffset += fUserImports.length();

		//fJava2JspRanges.putAll(fJsContentRanges);
		// fJava2JspRanges.putAll(fImportRanges);

	}

	/**
	 * configure using an XMLNode
	 * 
	 * @param node
	 * @param monitor
	 */
	private void configure(IDOMNode node, IProgressMonitor monitor) {

		fProgressMonitor = monitor;
		fStructuredModel = node.getModel();
		String baseLocation = fStructuredModel.getBaseLocation();

		fStructuredDocument = fStructuredModel.getStructuredDocument();

		String className = createClassname(node);
		if (className.length() > 0) {
			setClassname(className);
		}
	}

	/**
	 * memory saving configure (no StructuredDocument in memory) currently
	 * doesn't handle included files
	 * 
	 * @param jspFile
	 * @param monitor
	 */
	private void configure(IFile jspFile, IProgressMonitor monitor) {
		// when configured on a file
		// fStructuredModel, fPositionNode, fModelQuery, fStructuredDocument
		// are all null
		fProgressMonitor = monitor;

		String className = createClassname(jspFile);
		if (className.length() > 0) {
			setClassname(className);
		}
	}

	/**
	 * @param node
	 * @return
	 */
	private String createClassname(IDOMNode node) {

		String classname = ""; //$NON-NLS-1$
		if (node != null) {
			String base = node.getModel().getBaseLocation();
			//classname = base;
			classname = JSP2ServletNameUtil.mangle(base);
		}
		return classname;
	}

	/**
	 * @param jspFile
	 * @return
	 */
	private String createClassname(IFile jspFile) {

		String classname = ""; //$NON-NLS-1$
		if (jspFile != null) {
			classname = JSP2ServletNameUtil.mangle(jspFile.getFullPath().toString());
			//classname = jspFile.getFullPath().toString();
		}
		return classname;
	}

	public String getClassname() {
		return this.fClassname != null ? this.fClassname : "GenericJSSourceFile"; //$NON-NLS-1$
	}

	final public IStructuredDocumentRegion getCurrentNode() {
		return fCurrentNode;
	}

	/**
	 * @return just the "shell" of a servlet, nothing contributed from the JSP
	 *         doc
	 */
	public final StringBuffer getEmptyTranslation() {
		reset();
		buildResult();
		return getTranslation();
	}

	public List getExcludedElements() {
		return null;
	}

	public IFile getFile() {
		IFile f = null;
		IStructuredModel sModel = StructuredModelManager.getModelManager().getExistingModelForRead(getStructuredDocument());
		try {
			if (sModel != null) {
				f = FileBuffers.getWorkspaceFileAtLocation(new Path(sModel.getBaseLocation()));
			}
		} finally {
			if (sModel != null) {
				sModel.releaseFromRead();
			}
		}
		return f;
	}

	
	public HashMap getJava2JspIndirectRanges() {
		// Return nothing for now
		return new HashMap();
	}

	/**
	 * map of ranges (positions) in java document to ranges in jsp document
	 * 
	 * @return a map of java positions to jsp positions.
	 */
	public HashMap getJava2JspRanges() {
		return fJsToHTMLRanges;
	}

	public HashMap getJava2JspUseBeanRanges() {
		// Return nothing for now
		return new HashMap();
	}

	/**
	 * map of ranges in jsp document to ranges in java document.
	 * 
	 * @return a map of jsp positions to java positions, or null if no
	 *         translation has occured yet (the map hasn't been built).
	 */
	public HashMap getJsp2JavaRanges() {
		if (fJsToHTMLRanges == null) {
			return null;
		}
		HashMap flipFlopped = new HashMap();
		Iterator keys = fJsToHTMLRanges.keySet().iterator();

		Object range = null;
		while (keys.hasNext()) {
			range = keys.next();
			// System.out.println("Offset:"+ p.offset + " length:" + p.length);
			flipFlopped.put(fJsToHTMLRanges.get(range), range);
		}
		return flipFlopped;
	}

	/**
	 * Only valid after a configure(...), translate(...) or
	 * translateFromFile(...) call
	 * 
	 * @return the text in the JSP file
	 */
	public final String getJspText() {
		return fJspTextBuffer.toString();
	}

	public IStructuredDocument getStructuredDocument() {
		return fStructuredDocument;
	}

	/**
	 * Only valid after a configure(...), translate(...) or
	 * translateFromFile(...) call
	 * 
	 * @return the current result (java translation) buffer
	 */
	public final StringBuffer getTranslation() {

		if (JSPTranslator.DEBUG) {
			StringBuffer debugString = new StringBuffer();
			try {
				Iterator it = fJsToHTMLRanges.keySet().iterator();
				while (it.hasNext()) {
					debugString.append("--------------------------------------------------------------\n"); //$NON-NLS-1$
					Position java = (Position) it.next();
					debugString.append("Java range:[" + java.offset + ":" + java.length + "]\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
					debugString.append("[" + fResult.toString().substring(java.offset, java.offset + java.length) + "]\n"); //$NON-NLS-1$ //$NON-NLS-2$
					debugString.append("--------------------------------------------------------------\n"); //$NON-NLS-1$
					debugString.append("|maps to...|\n"); //$NON-NLS-1$
					debugString.append("==============================================================\n"); //$NON-NLS-1$
					Position jsp = (Position) fJsToHTMLRanges.get(java);
					debugString.append("JSP range:[" + jsp.offset + ":" + jsp.length + "]\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
					debugString.append("[" + fJspTextBuffer.toString().substring(jsp.offset, jsp.offset + jsp.length) + "]\n"); //$NON-NLS-1$ //$NON-NLS-2$
					debugString.append("==============================================================\n"); //$NON-NLS-1$
					debugString.append("\n"); //$NON-NLS-1$
					debugString.append("\n"); //$NON-NLS-1$
				}
			} catch (Exception e) {
				Logger.logException("JSPTranslation error", e); //$NON-NLS-1$
			}
			Logger.log(Logger.INFO_DEBUG, debugString.toString());
		}

		if (JSPTranslator.DEBUG) {
			IProject project = getFile().getProject();
			String shortenedClassname = StringUtils.replace(getFile().getName(), ".", "_");
			String filename = shortenedClassname + ".js";
			IPath path = project.getFullPath().append("src/" + filename);
			try {
				IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(path);
				if (!file.exists()) {
					file.create(new ByteArrayInputStream(new byte[0]), true, new NullProgressMonitor());
				}
				ITextFileBufferManager textFileBufferManager = FileBuffers.getTextFileBufferManager();
				textFileBufferManager.connect(path, new NullProgressMonitor());
				ITextFileBuffer javaOutputBuffer = textFileBufferManager.getTextFileBuffer(path);
				javaOutputBuffer.getDocument().set(StringUtils.replace(fResult.toString(), getClassname(), shortenedClassname));
				javaOutputBuffer.commit(new NullProgressMonitor(), true);
				textFileBufferManager.disconnect(path, new NullProgressMonitor());
			} catch (Exception e) {
				// this is just for debugging, ignore
			}
			System.out.println("Updated translation: " + path);
		}

		return fResult;
	}

	/**
	 * 
	 * @return the status of the translator's progrss monitor, false if the
	 *         monitor is null
	 */
	private boolean isCanceled() {
		return (fProgressMonitor == null) ? false : fProgressMonitor.isCanceled();
	}

	/**
	 * Reinitialize some fields
	 */
	private void reset() {
		
		scriptOffset = 0;
		// reset progress monitor
		if (fProgressMonitor != null) {
			fProgressMonitor.setCanceled(false);
		}
		fScriptText = new StringBuffer();

		fResult = null;

		fCurrentNode = null;

		fJsToHTMLRanges.clear();
	
		fJspTextBuffer = new StringBuffer();
		
		rawImports.clear();
		
		importLocationsInHtml.clear();
		

	}

	public ArrayList getImportHtmlRanges() {
		return importLocationsInHtml;
	}
	
	/**
	 * So that the JSPTranslator can be reused.
	 */
	public void reset(IDOMNode node, IProgressMonitor progress) {

		// initialize some things on node
		configure(node, progress);
		reset();
		// set the jsp text buffer
		fJspTextBuffer.append(fStructuredDocument.get());
	}

	/**
	 * conservative version (no StructuredDocument/Model)
	 * 
	 * @param jspFile
	 * @param progress
	 */
	public void reset(IFile jspFile, IProgressMonitor progress) {

		// initialize some things on node
		configure(jspFile, progress);
		reset();
		// set the jsp text buffer
		setJspText(jspFile);
	}

	public void setClassname(String classname) {
		this.fClassname = classname;
	}

	private IStructuredDocumentRegion setCurrentNode(IStructuredDocumentRegion currentNode) {
		return this.fCurrentNode = currentNode;
	}

	protected void setDocumentContent(IDocument document, InputStream contentStream, String charset) {
		Reader in = null;
		try {
			in = new BufferedReader(new InputStreamReader(contentStream, charset), 2048);
			StringBuffer buffer = new StringBuffer(2048);
			char[] readBuffer = new char[2048];
			int n = in.read(readBuffer);
			while (n > 0) {
				buffer.append(readBuffer, 0, n);
				n = in.read(readBuffer);
			}
			document.set(buffer.toString());
		} catch (IOException x) {
			// ignore
		} finally {
			if (in != null) {
				try {
					in.close();
				} catch (IOException x) {
					// ignore
				}
			}
		}
	}

	/**
	 * Set the jsp text from an IFile
	 * 
	 * @param jspFile
	 */
	private void setJspText(IFile jspFile) {
		try {
			BufferedInputStream in = new BufferedInputStream(jspFile.getContents());
			BufferedReader reader = new BufferedReader(new InputStreamReader(in));
			String line = null;
			while ((line = reader.readLine()) != null) {
				fJspTextBuffer.append(line);
				fJspTextBuffer.append(JSPTranslator.ENDL);
			}
			reader.close();
		} catch (CoreException e) {
			Logger.logException(e);
		} catch (IOException e) {
			Logger.logException(e);
		}
	}

	/*
	 * returns string minus CDATA open and close text
	 */
	final public String stripCDATA(String text) {
		String resultText = ""; //$NON-NLS-1$
		String CDATA_OPEN = "<![CDATA["; //$NON-NLS-1$
		String CDATA_CLOSE = "]]>"; //$NON-NLS-1$
		int start = 0;
		int end = text.length();
		while (start < text.length()) {
			if (text.indexOf(CDATA_OPEN, start) > -1) {
				end = text.indexOf(CDATA_OPEN, start);
				resultText += text.substring(start, end);
				start = end + CDATA_OPEN.length();
			} else if (text.indexOf(CDATA_CLOSE, start) > -1) {
				end = text.indexOf(CDATA_CLOSE, start);
				resultText += text.substring(start, end);
				start = end + CDATA_CLOSE.length();
			} else {
				end = text.length();
				resultText += text.substring(start, end);
				break;
			}
		}
		return resultText;
	}

	public void translate() {
		setCurrentNode(fStructuredDocument.getFirstStructuredDocumentRegion());
		while (getCurrentNode() != null && !isCanceled()) {
			// System.out.println("Translator Looking at Node
			// type:"+getCurrentNode().getType()+"---------------------------------:");
			// System.out.println(new NodeHelper(getCurrentNode()));
			// i.println("/---------------------------------------------------");

			if (getCurrentNode().getType() == DOMRegionContext.XML_TAG_NAME) {

				NodeHelper nh = new NodeHelper(getCurrentNode());

				if ((!nh.isEndTag() || nh.isSelfClosingTag()) && nh.nameEquals("script")) {
					/*
					 * Handles the following cases: <script
					 * type="javascriptype"> <script language="javascriptype>
					 * <script src='' type=javascriptype> <script src=''
					 * language=javascripttype <script src=''> global js type.
					 * <script> (global js type)
					 */
					if (NodeHelper.isInArray(JsDataTypes.JSVALIDDATATYPES, nh.getAttributeValue("type"))
							|| NodeHelper.isInArray(JsDataTypes.JSVALIDDATATYPES, nh.getAttributeValue("language")) || isGlobalJs) {
						if (nh.containsAttribute(new String[] { "src" })) {
							// Handle import
							translateScriptImportNode(getCurrentNode());
						}
						//} else {
							// handle script section
						if (getCurrentNode().getNext() != null && getCurrentNode().getNext().getType() == DOMRegionContext.BLOCK_TEXT) {
							translateJSNode(getCurrentNode().getNext());
						}
						
					} // End search for <script> sections
				} else if (nh.containsAttribute(JsDataTypes.HTMLATREVENTS)) {
					/* Check for embeded JS events in any tags */
					translateInlineJSNode(getCurrentNode());
				} else if (nh.nameEquals("META") && nh.attrEquals("http-equiv", "Content-Script-Type") && nh.containsAttribute(new String[] { "content" })) {
					// <META http-equiv="Content-Script-Type" content="type">
					isGlobalJs = NodeHelper.isInArray(JsDataTypes.JSVALIDDATATYPES, nh.getAttributeValue("content"));
				} // End big if of JS types
			}
			if (getCurrentNode() != null) {
				advanceNextNode();
			}
		} // end while loop
		buildResult();

	}

	public void translateInlineJSNode(IStructuredDocumentRegion container) {
		// System.out
		// .println("JSPTranslator.translateInlineJSNode Entered
		// w/ScriptOffset:"
		// + scriptOffset);

		NodeHelper nh = new NodeHelper(container);
		// System.out.println("inline js node looking at:\n" + nh);
		/* start a function header.. will amend later */

		ITextRegionList t = container.getRegions();
		ITextRegion r;
		Iterator regionIterator = t.iterator();
		while (regionIterator.hasNext()) {
			r = (ITextRegion) regionIterator.next();
			if (r.getType() == DOMRegionContext.XML_TAG_ATTRIBUTE_NAME) {
				int start = r.getStart();
				int offset = r.getTextEnd();

				String tagAttrname = container.getText().substring(start, offset).trim();

				/*
				 * Attribute values aren't case sensative, also make sure next
				 * region is attrib value
				 */
				if (NodeHelper.isInArray(JsDataTypes.HTMLATREVENTS, tagAttrname)) {
					if (regionIterator.hasNext()) {
						regionIterator.next();
					}
					if (regionIterator.hasNext()) {
						r = ((ITextRegion) regionIterator.next());
					}

					if (r.getType() == DOMRegionContext.XML_TAG_ATTRIBUTE_VALUE) {

						int valStartOffset = container.getStartOffset(r);
						// int valEndOffset = r.getTextEnd();
						String rawText = container.getText().substring(r.getStart(), r.getTextEnd());

						Position inScript = new Position(scriptOffset, rawText.length());

						/* Quoted text starts +1 and ends -1 char */
						Position inHtml = new Position(valStartOffset, rawText.length());

						/*
						 * build the function. Addiotional function "baggage"
						 * not of concern to editor
						 */

						fJsToHTMLRanges.put(inScript, inHtml);
						fScriptText.append(rawText);
						scriptOffset = fScriptText.length();
						if (JSPTranslator.DEBUG) {
							System.out.println("START-----------------JS Translator Script loop---------------");
							System.out.println("Translated to:\n" + rawText + "\n");
							System.out.println("HTML Position:[" + inHtml.getOffset() + "," + inHtml.getLength() + "]");
							System.out.println("Script Position:[" + inScript.getOffset() + "," + inScript.getLength() + "]");
							System.out.println("Added (js) Text length:" + rawText.length());
							System.out.println("END-----------------JS Translator Script loop---------------");
						}
					}
				}
			}

		}
	}

	public ArrayList getRawImports() {
		return this.rawImports;
	}

	public void translateJSNode(IStructuredDocumentRegion container) {

		ITextRegionCollection containerRegion = container;
		Iterator regions = containerRegion.getRegions().iterator();
		ITextRegion region = null;
		while (regions.hasNext()) {
			region = (ITextRegion) regions.next();
			String type = region.getType();
			// content assist was not showing up in JSP inside a javascript
			// region
			if (type == DOMRegionContext.BLOCK_TEXT) {
				int scriptStart = container.getStartOffset();
				int scriptTextEnd = container.getEndOffset() - container.getStartOffset();

				//	   			
				// System.out.println("Container getStartOffset():" +
				// container.getStartOffset());
				// System.out.println("Container getEnd():" +
				// container.getEnd());
				// System.out.println("Container getEndOffset():" +
				// container.getEndOffset());
				// System.out.println("Container getType():" +
				// container.getType());
				//	   			
				// System.out.println("Region getStart():" + region.getStart());
				// System.out.println("Region getEnd():" + region.getStart());
				// System.out.println("Region getType():" + region.getType());
				// System.out.println("Container Text Length:" +
				// container.getText().length());
				//	   			
				// System.out.println("Container Text:" + container.getText());

				String regionText = container.getText().substring(region.getStart(), region.getEnd());
				int regionLength = regionText.length();
				Position inScript = new Position(scriptOffset, regionLength);
				Position inHtml = new Position(scriptStart, scriptTextEnd);
				if (JSPTranslator.DEBUG) {
					System.out.println("START-----------------JS Translator Script loop---------------");
					System.out.println("Translated to:\n" + regionText + "\n");
					System.out.println("HTML Position:[" + inHtml.getOffset() + "," + inHtml.getLength() + "]");
					System.out.println("Script Position:[" + inScript.getOffset() + "," + inScript.getLength() + "]");
					System.out.println("END-----------------JS Translator Script loop---------------");
					//				
				}
				fJsToHTMLRanges.put(inScript, inHtml);
				fScriptText.append(regionText);

				scriptOffset = fScriptText.length();
			}
		}
	}


	public void translateScriptImportNode(IStructuredDocumentRegion region) {
		NodeHelper nh = new NodeHelper(region);
		Position inHtml = new Position(region.getStartOffset(), region.getEndOffset());
		importLocationsInHtml.add(inHtml);
		addImport( nh.getAttributeValue("src") );
		
	}
	
	private void addImport(String importName) {
		if (importName != null && !importName.equals("") ) rawImports.add(importName);
	}

	/**
	 * @param r
	 *            the region to be unescaped (XMLContent, XML ENTITY REFERENCE,
	 *            or CDATA)
	 * @param sb
	 *            the stringbuffer to append the text to
	 * @return the number of characters removed in unescaping this text
	 */
	protected int unescapeRegion(ITextRegion r, StringBuffer sb) {
		String s = ""; //$NON-NLS-1$
		int lengthBefore = 0, lengthAfter = 0, cdata_tags_length = 0;
		if (r != null && (r.getType() == DOMRegionContext.XML_CONTENT || r.getType() == DOMRegionContext.XML_ENTITY_REFERENCE)) {
			lengthBefore = (getCurrentNode() != r) ? getCurrentNode().getFullText(r).length() : getCurrentNode().getFullText().length();
			s = EscapedTextUtil.getUnescapedText(getCurrentNode(), r);
			lengthAfter = s.length();
			sb.append(s);
		} else if (r != null && r.getType() == DOMRegionContext.XML_CDATA_TEXT) {
			if (r instanceof ITextRegionContainer) // only interested in
			// contents
			{
				// navigate to next region container (which should be a JSP
				// region)
				Iterator it = ((ITextRegionContainer) r).getRegions().iterator();
				ITextRegion temp = null;
				while (it.hasNext()) {
					temp = (ITextRegion) it.next();
					if (temp instanceof ITextRegionContainer || temp.getType() == DOMRegionContext.XML_CDATA_TEXT) {
						sb.append(getCurrentNode().getFullText(temp));
					} else if (temp.getType() == DOMRegionContext.XML_CDATA_OPEN || temp.getType() == DOMRegionContext.XML_CDATA_CLOSE) {
						cdata_tags_length += temp.getLength();
					}
				}
			}
		}
		return (lengthBefore - lengthAfter + cdata_tags_length);
	}

}