/*******************************************************************************
 * Copyright (c) 2000, 2009 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.core.tests.dom;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import junit.framework.Test;
import junit.framework.TestSuite;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.wst.jsdt.core.IJavaScriptProject;
import org.eclipse.wst.jsdt.core.IJavaScriptUnit;
import org.eclipse.wst.jsdt.core.JavaScriptCore;
import org.eclipse.wst.jsdt.core.JavaScriptModelException;
import org.eclipse.wst.jsdt.core.compiler.IProblem;
import org.eclipse.wst.jsdt.core.dom.AST;
import org.eclipse.wst.jsdt.core.dom.ASTNode;
import org.eclipse.wst.jsdt.core.dom.ASTParser;
import org.eclipse.wst.jsdt.core.dom.ArrayType;
import org.eclipse.wst.jsdt.core.dom.Block;
import org.eclipse.wst.jsdt.core.dom.Comment;
import org.eclipse.wst.jsdt.core.dom.Expression;
import org.eclipse.wst.jsdt.core.dom.ExpressionStatement;
import org.eclipse.wst.jsdt.core.dom.FieldDeclaration;
import org.eclipse.wst.jsdt.core.dom.FunctionDeclaration;
import org.eclipse.wst.jsdt.core.dom.FunctionInvocation;
import org.eclipse.wst.jsdt.core.dom.FunctionRef;
import org.eclipse.wst.jsdt.core.dom.FunctionRefParameter;
import org.eclipse.wst.jsdt.core.dom.IBinding;
import org.eclipse.wst.jsdt.core.dom.ITypeBinding;
import org.eclipse.wst.jsdt.core.dom.IfStatement;
import org.eclipse.wst.jsdt.core.dom.JSdoc;
import org.eclipse.wst.jsdt.core.dom.JavaScriptUnit;
import org.eclipse.wst.jsdt.core.dom.MemberRef;
import org.eclipse.wst.jsdt.core.dom.Name;
import org.eclipse.wst.jsdt.core.dom.PackageDeclaration;
import org.eclipse.wst.jsdt.core.dom.PrimitiveType;
import org.eclipse.wst.jsdt.core.dom.QualifiedName;
import org.eclipse.wst.jsdt.core.dom.ReturnStatement;
import org.eclipse.wst.jsdt.core.dom.SimpleName;
import org.eclipse.wst.jsdt.core.dom.SimpleType;
import org.eclipse.wst.jsdt.core.dom.Statement;
import org.eclipse.wst.jsdt.core.dom.TagElement;
import org.eclipse.wst.jsdt.core.dom.TextElement;
import org.eclipse.wst.jsdt.core.dom.Type;
import org.eclipse.wst.jsdt.core.dom.TypeDeclaration;
import org.eclipse.wst.jsdt.core.dom.TypeDeclarationStatement;
import org.eclipse.wst.jsdt.core.dom.VariableDeclarationFragment;
import org.eclipse.wst.jsdt.core.dom.VariableDeclarationStatement;
import org.eclipse.wst.jsdt.internal.compiler.parser.ScannerHelper;

public class ASTConverterJavadocTest extends ConverterTestSetup {

	// Flag to know whether Converter directory should be copied from org.eclipse.wst.jsdt.core.tests.model project
	static protected boolean COPY_DIR = true;

	// Test counters
	protected static int[] TEST_COUNTERS = { 0, 0, 0, 0 };
	// Unicode tests
	protected static boolean UNICODE = false;
	// Unix tests
	final boolean unix;
	static final String UNIX_SUPPORT = System.getProperty("unix");
	// Doc Comment support
	static final String DOC_COMMENT_SUPPORT = System.getProperty("doc.support");
	final String docCommentSupport;

	// List of comments read from source of test
	private final int LINE_COMMENT = 100;
	private final int BLOCK_COMMENT =200;
	private final int DOC_COMMENT = 300;
	List comments = new ArrayList();
	private String chars;
	// List of tags contained in each comment read from test source.
	List allTags = new ArrayList();
	// Current compilation unit
	protected IJavaScriptUnit sourceUnit;
	// Test package binding
	protected boolean resolveBinding = true;
	protected boolean packageBinding = true;
	// AST Level
	/** @deprecated using deprecated code */
	protected int astLevel = AST.JLS2;
	protected int savedLevel;
	// Debug
	protected String prefix = "";
	protected boolean debug = false;
	protected StringBuffer problems;
	protected String compilerOption = JavaScriptCore.IGNORE;
	protected List failures;
	protected boolean stopOnFailure = true;
	// Project
	protected IJavaScriptProject currentProject;
	Map savedOptions = null;

	/**
	 * @param name
	 * @param support
	 */
	public ASTConverterJavadocTest(String name, String support, String unix) {
		super(name);
		this.docCommentSupport = support;
		this.unix = "true".equals(unix);
	}
	/**
	 * @param name
	 */
	public ASTConverterJavadocTest(String name) {
		this(name, JavaScriptCore.ENABLED, UNIX_SUPPORT);
	}

	public static Test suite() {
		TestSuite suite = new Suite(ASTConverterJavadocTest.class.getName());		
//		String param = System.getProperty("unicode");
//		if ("true".equals(param)) {
//			unicode = true;
//		}
//		String param = System.getProperty("unix");
//		if ("true".equals(param)) {
//			unix = true;
//		}
		if (true) {
			if (DOC_COMMENT_SUPPORT == null) {
				buildSuite(suite, JavaScriptCore.ENABLED);
				buildSuite(suite, JavaScriptCore.DISABLED);
			} else {
				String support = DOC_COMMENT_SUPPORT==null ? JavaScriptCore.DISABLED : (DOC_COMMENT_SUPPORT.equals(JavaScriptCore.DISABLED)?JavaScriptCore.DISABLED:JavaScriptCore.ENABLED);
				buildSuite(suite, support);
			}
			return suite;
		}

		// Run test cases subset
		COPY_DIR = false;
		System.err.println("WARNING: only subset of tests will be executed!!!");
		suite.addTest(new ASTConverterJavadocTest("testBug165525"));
		return suite;
	}

	public static void buildSuite(TestSuite suite, String support) {
		Class c = ASTConverterJavadocTest.class;
		Method[] methods = c.getMethods();
		for (int i = 0, max = methods.length; i < max; i++) {
			if (methods[i].getName().startsWith("test")) { //$NON-NLS-1$
				suite.addTest(new ASTConverterJavadocTest(methods[i].getName(), support, UNIX_SUPPORT));
			}
		}
		// when unix support not specified, also run using unix format
		if (UNIX_SUPPORT == null && JavaScriptCore.ENABLED.equals(support)) {
			for (int i = 0, max = methods.length; i < max; i++) {
				if (methods[i].getName().startsWith("test")) { //$NON-NLS-1$
					suite.addTest(new ASTConverterJavadocTest(methods[i].getName(), support, "true"));
				}
			}
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.wst.jsdt.core.tests.model.AbstractJavaModelTests#copyDirectory(java.io.File, java.io.File)
	 */
	protected void copyDirectory(File sourceDir, File targetDir) throws IOException {
		if (COPY_DIR) {
			super.copyDirectory(sourceDir, targetDir);
		} else {
			targetDir.mkdirs();
			File sourceFile = new File(sourceDir, ".project");
			File targetFile = new File(targetDir, ".project");
			targetFile.createNewFile();
			copy(sourceFile, targetFile);
			sourceFile = new File(sourceDir, ".classpath");
			targetFile = new File(targetDir, ".classpath");
			targetFile.createNewFile();
			copy(sourceFile, targetFile);
		}
	}
	/* (non-Javadoc)
	 * @see junit.framework.TestCase#getName()
	 */
	public String getName() {
		String strUnix = unix ? " - Unix" : "";
		return "Doc "+docCommentSupport+strUnix+" - "+super.getName();
	}
	/* (non-Javadoc)
	 * @see junit.framework.TestCase#setUp()
	 */
	protected void setUp() throws Exception {
		super.setUp();
		TEST_COUNTERS[0]++;
		failures = new ArrayList();
		problems = new StringBuffer();
		workingCopies = null;
		savedLevel = astLevel;
	}
	/* (non-Javadoc)
	 * @see junit.framework.TestCase#tearDown()
	 */
	protected void tearDown() throws Exception {
		int size = failures.size();
		String title = size+" positions/bindings were incorrect in "+getName();
		if (size == 0) {
			TEST_COUNTERS[1]++;
		} else if (problems.length() > 0) {
			if (debug) {
				System.out.println("Compilation warnings/errors occured:");
				System.out.println(problems.toString());
			}
			TEST_COUNTERS[2]++;
		} else {
			TEST_COUNTERS[3]++;
			System.out.println(title+":");
			for (int i=0; i<size; i++) {
				System.out.println("	- "+failures.get(i));
			}
		}
//		if (!stopOnFailure) {
			assertTrue(title, size==0 || problems.length() > 0);
//		}
		super.tearDown();
		
		// Restore saved ast level
		astLevel = savedLevel;
	}

	/* (non-Javadoc)
	 * @see junit.framework.TestCase#tearDown()
	 */
	public void tearDownSuite() throws Exception {
		// put default options on project
		if (currentProject != null && savedOptions != null) {
			currentProject.setOptions(savedOptions);
		}
		super.tearDownSuite();
		if (TEST_COUNTERS[0] != TEST_COUNTERS[1]) {
			NumberFormat intFormat = NumberFormat.getInstance();
			intFormat.setMinimumIntegerDigits(3);
			intFormat.setMaximumIntegerDigits(3);
			System.out.println("=====================================");
			System.out.println(intFormat.format(TEST_COUNTERS[0])+" tests have been executed:");
			System.out.println("  - "+intFormat.format(TEST_COUNTERS[1])+" tests have been actually executed.");
			System.out.println("  - "+intFormat.format(TEST_COUNTERS[2])+" tests were skipped due to compilation errors.");
			System.out.println("  - "+intFormat.format(TEST_COUNTERS[3])+" tests failed.");
		}
	}

	public ASTNode runConversion(char[] source, String unitName, IJavaScriptProject project) {
		ASTParser parser = ASTParser.newParser(astLevel);
		parser.setSource(source);
		parser.setUnitName(unitName);
		parser.setProject(project);
		parser.setResolveBindings(resolveBinding);
		return parser.createAST(null);
	}

	public ASTNode runConversion(char[] source, String unitName, IJavaScriptProject project, Map options) {
		if (project == null) {
			ASTParser parser = ASTParser.newParser(astLevel);
			parser.setSource(source);
			parser.setUnitName(unitName);
			parser.setCompilerOptions(options);
			parser.setResolveBindings(resolveBinding);
			return parser.createAST(null);
		}
		return runConversion(source, unitName, project);
	}

// NOT USED
//	class ASTConverterJavadocFlattener extends ASTVisitor {
//
//		/**
//		 * The string buffer into which the serialized representation of the AST is
//		 * written.
//		 */
//		private StringBuffer buffer;
//		
//		private String comment;
//		
//		/**
//		 * Creates a new AST printer.
//		 */
//		ASTConverterJavadocFlattener(String comment) {
//			buffer = new StringBuffer();
//			comment = comment;
//		}
//		
//		/**
//		 * Returns the string accumulated in the visit.
//		 *
//		 * @return the serialized 
//		 */
//		public String getResult() {
//			return buffer.toString();
//		}
//		
//		/**
//		 * Resets this printer so that it can be used again.
//		 */
//		public void reset() {
//			buffer.setLength(0);
//		}
//
//		/*
//		 * @see ASTVisitor#visit(ArrayType)
//		 */
//		public boolean visit(ArrayType node) {
//			node.getComponentType().accept(this);
//			buffer.append("[]");//$NON-NLS-1$
//			return false;
//		}
//	
//		/*
//		 * @see ASTVisitor#visit(BlockComment)
//		 * @since 3.0
//		 */
//		public boolean visit(BlockComment node) {
//			buffer.append(comment);
//			return false;
//		}
//	
//		/*
//		 * @see ASTVisitor#visit(Javadoc)
//		 */
//		public boolean visit(Javadoc node) {
//			
//			// ignore deprecated node.getComment()
//			buffer.append("/**");//$NON-NLS-1$
//			ASTNode e = null;
//			int start = 3;
//			for (Iterator it = node.tags().iterator(); it.hasNext(); ) {
//				e = (ASTNode) it.next();
//				try {
//					buffer.append(comment.substring(start, e.getStartPosition()-node.getStartPosition()));
//					start = e.getStartPosition()-node.getStartPosition();
//				} catch (IndexOutOfBoundsException ex) {
//					// do nothing
//				}
//				e.accept(this);
//				start += e.getLength();
//			}
//			buffer.append(comment.substring(start, node.getLength()));
//			return false;
//		}
//	
//		/*
//		 * @see ASTVisitor#visit(LineComment)
//		 * @since 3.0
//		 */
//		public boolean visit(LineComment node) {
//			buffer.append(comment);
//			return false;
//		}
//	
//		/*
//		 * @see ASTVisitor#visit(MemberRef)
//		 * @since 3.0
//		 */
//		public boolean visit(MemberRef node) {
//			if (node.getQualifier() != null) {
//				node.getQualifier().accept(this);
//			}
//			buffer.append("#");//$NON-NLS-1$
//			node.getName().accept(this);
//			return true;
//		}
//		
//		/*
//		 * @see ASTVisitor#visit(FunctionRef)
//		 * @since 3.0
//		 */
//		public boolean visit(FunctionRef node) {
//			if (node.getQualifier() != null) {
//				node.getQualifier().accept(this);
//			}
//			buffer.append("#");//$NON-NLS-1$
//			node.getName().accept(this);
//			buffer.append("(");//$NON-NLS-1$
//			for (Iterator it = node.parameters().iterator(); it.hasNext(); ) {
//				FunctionRefParameter e = (FunctionRefParameter) it.next();
//				e.accept(this);
//				if (it.hasNext()) {
//					buffer.append(",");//$NON-NLS-1$
//				}
//			}
//			buffer.append(")");//$NON-NLS-1$
//			return true;
//		}
//		
//		/*
//		 * @see ASTVisitor#visit(FunctionRefParameter)
//		 * @since 3.0
//		 */
//		public boolean visit(FunctionRefParameter node) {
//			node.getType().accept(this);
//			if (node.getName() != null) {
//				buffer.append(" ");//$NON-NLS-1$
//				node.getName().accept(this);
//			}
//			return true;
//		}
//
//		/*
//		 * @see ASTVisitor#visit(TagElement)
//		 * @since 3.0
//		 */
//		public boolean visit(TagElement node) {
//			Javadoc javadoc = null;
//			int start = 0;
//			if (node.isNested()) {
//				// nested tags are always enclosed in braces
//				buffer.append("{");//$NON-NLS-1$
//				javadoc = (Javadoc) node.getParent().getParent();
//				start++;
//			} else {
//				javadoc = (Javadoc) node.getParent();
//			}
//			start += node.getStartPosition()-javadoc.getStartPosition();
//			if (node.getTagName() != null) {
//				buffer.append(node.getTagName());
//				start += node.getTagName().length();
//			}
//			for (Iterator it = node.fragments().iterator(); it.hasNext(); ) {
//				ASTNode e = (ASTNode) it.next();
//				try {
//					buffer.append(comment.substring(start, e.getStartPosition()-javadoc.getStartPosition()));
//					start = e.getStartPosition()-javadoc.getStartPosition();
//				} catch (IndexOutOfBoundsException ex) {
//					// do nothing
//				}
//				start += e.getLength();
//				e.accept(this);
//			}
//			if (node.isNested()) {
//				buffer.append("}");//$NON-NLS-1$
//			}
//			return true;
//		}
//		
//		/*
//		 * @see ASTVisitor#visit(TextElement)
//		 * @since 3.0
//		 */
//		public boolean visit(TextElement node) {
//			buffer.append(node.getText());
//			return false;
//		}
//
//		/*
//		 * @see ASTVisitor#visit(PrimitiveType)
//		 */
//		public boolean visit(PrimitiveType node) {
//			buffer.append(node.getPrimitiveTypeCode().toString());
//			return false;
//		}
//	
//		/*
//		 * @see ASTVisitor#visit(QualifiedName)
//		 */
//		public boolean visit(QualifiedName node) {
//			node.getQualifier().accept(this);
//			buffer.append(".");//$NON-NLS-1$
//			node.getName().accept(this);
//			return false;
//		}
//
//		/*
//		 * @see ASTVisitor#visit(SimpleName)
//		 */
//		public boolean visit(SimpleName node) {
//			buffer.append(node.getIdentifier());
//			return false;
//		}
//
//		/*
//		 * @see ASTVisitor#visit(SimpleName)
//		 */
//		public boolean visit(SimpleType node) {
//			node.getName().accept(this);
//			return false;
//		}
//	}

	private char getNextChar(char[] source, int idx) {
			// get next char
			char ch = source[idx];
			int charLength = 1;
			int pos = idx;
			chars = null;
			if (ch == '\\' && source[idx+1] == 'u') {
				//-------------unicode traitement ------------
				int c1, c2, c3, c4;
				charLength++;
				while (source[idx+charLength] == 'u') charLength++;
				if (((c1 = ScannerHelper.getNumericValue(source[idx+charLength++])) > 15
					|| c1 < 0)
					|| ((c2 = ScannerHelper.getNumericValue(source[idx+charLength++])) > 15 || c2 < 0)
					|| ((c3 = ScannerHelper.getNumericValue(source[idx+charLength++])) > 15 || c3 < 0)
					|| ((c4 = ScannerHelper.getNumericValue(source[idx+charLength++])) > 15 || c4 < 0)) {
					return ch;
				}
				ch = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
				chars = new String(source, pos, charLength);
			}
			return ch;
	}
	/*
	 * Convert Javadoc source to match Javadoc.toString().
	 * Store converted comments and their corresponding tags respectively
	 * in comments and allTags fields
	 */
	protected void setSourceComment(char[] source) throws ArrayIndexOutOfBoundsException {
		comments = new ArrayList();
		allTags = new ArrayList();
		StringBuffer buffer = null;
		int comment = 0;
		boolean end = false, lineStarted = false;
		String tag = null;
		List tags = new ArrayList();
		int length = source.length;
		char previousChar=0, currentChar=0;
		for (int i=0; i<length;) {
			previousChar = currentChar;
			// get next char
			currentChar = getNextChar(source, i);
			i += (chars==null) ? 1 : chars.length();

			// 
			switch (comment) {
				case 0: 
					switch (currentChar) {
						case '/':
							comment = 1; // first char for comments...
							buffer = new StringBuffer();
							if (chars == null) buffer.append(currentChar);
							else buffer.append(chars);
							break;
						case '\'':
							while (i<length) {
								// get next char
								currentChar = getNextChar(source, i);
								i += (chars==null) ? 1 : chars.length();
								if (currentChar == '\\') {
									// get next char
									currentChar = getNextChar(source, i);
									i += (chars==null) ? 1 : chars.length();
								} else {
									if (currentChar == '\'') {
										break;
									}
								}
							}
							break;
						case '"':
							while (i<length) {
								// get next char
								currentChar = getNextChar(source, i);
								i += (chars==null) ? 1 : chars.length();
								if (currentChar == '\\') {
									// get next char
									currentChar = getNextChar(source, i);
									i += (chars==null) ? 1 : chars.length();
								} else {
									if (currentChar == '"') {
										// get next char
										currentChar = getNextChar(source, i);
										if (currentChar == '"') {
											i += (chars==null) ? 1 : chars.length();
										} else {
											break;
										}
									}
								}
							}
							break;
					}
					break;
				case 1: // first '/' has been found...
					switch (currentChar) {
						case '/':
							if (chars == null) buffer.append(currentChar);
							else buffer.append(chars);
							comment = LINE_COMMENT;
							break;
						case '*':
							if (chars == null) buffer.append(currentChar);
							else buffer.append(chars);
							comment = 2; // next step
							break;
						default:
							comment = 0;
							break;
					}
					break;
				case 2: // '/*' has been found...
					if (currentChar == '*') {
						comment = 3; // next step...
					} else {
						comment = BLOCK_COMMENT;
					}
					if (chars == null) buffer.append(currentChar);
					else buffer.append(chars);
					break;
				case 3: // '/**' has bee found, verify that's not an empty block comment
					if (currentChar == '/') { // empty block comment
						if (chars == null) buffer.append(currentChar);
						else buffer.append(chars);
						comments.add(buffer.toString());
						allTags.add(new ArrayList());
						comment = 0;
						break;
					}
					// do not break, directly go to next case...
					comment = DOC_COMMENT;
				case DOC_COMMENT:
					if (tag != null) {
						if (currentChar >= 'a' && currentChar <= 'z') {
							tag += currentChar;
						} else {
							tags.add(tag);
							tag = null;
						}
					}
					switch (currentChar) {
						case '@':
							if (!lineStarted || previousChar == '{') {
								tag = "";
								lineStarted = true;
							}
							break;
						case '\r':
						case '\n':
							lineStarted = false;
							break;
						case '*':
							break;
						default:
							if (!Character.isWhitespace(currentChar)) {
								lineStarted = true;
							}
					}
				case BLOCK_COMMENT:
					if (chars == null) buffer.append(currentChar);
					else buffer.append(chars);
					if (end && currentChar == '/') {
						comment = 0;
						lineStarted = false;
						comments.add(buffer.toString());
						allTags.add(tags);
						tags = new ArrayList();
					}
					end = currentChar == '*';
					break;
				case LINE_COMMENT:
					if (currentChar == '\r' || currentChar == '\n') {
						/*
						if (currentChar == '\r' && source[i+1] == '\n') {
							buffer.append(source[++i]);
						}
						*/
						comment = 0;
						comments.add(buffer.toString());
						allTags.add(tags);
					} else {
						if (chars == null) buffer.append(currentChar);
						else buffer.append(chars);
					}
					break;
				default:
					// do nothing
					break;
			}
		}
	}

	/*
	 * Convert Javadoc source to match Javadoc.toString().
	 * Store converted comments and their corresponding tags respectively
	 * in comments and allTags fields
	 */
	char[] getUnicodeSource(char[] source) {
		int length = source.length;
		int unicodeLength = length*6;
		char[] unicodeSource = new char[unicodeLength];
		int u=0;
		for (int i=0; i<length; i++) {
			// get next char
			if (source[i] == '\\' && source[i+1] == 'u') {
				//-------------unicode traitement ------------
				int c1, c2, c3, c4;
				unicodeSource[u++] = source[i];
				unicodeSource[u++] = source[++i];
				if (((c1 = ScannerHelper.getNumericValue(source[i+1])) > 15
					|| c1 < 0)
					|| ((c2 = ScannerHelper.getNumericValue(source[i+2])) > 15 || c2 < 0)
					|| ((c3 = ScannerHelper.getNumericValue(source[i+3])) > 15 || c3 < 0)
					|| ((c4 = ScannerHelper.getNumericValue(source[i+4])) > 15 || c4 < 0)) {
					throw new RuntimeException("Invalid unicode in source at "+i);
				}
				for (int j=0; j<4; j++) unicodeSource[u++] = source[++i];
			} else {
				unicodeSource[u++] = '\\';
				unicodeSource[u++] = 'u';
				unicodeSource[u++] = '0';
				unicodeSource[u++] = '0';
				int val = source[i]/16;
				unicodeSource[u++] = (char) (val<10 ? val+ 0x30 : val-10+0x61);
				val = source[i]%16;
				unicodeSource[u++] = (char) (val<10 ? val+ 0x30 : val-10+0x61);
			}
		}
		// Return one well sized array
		if (u != unicodeLength) {
			char[] result = new char[u];
			System.arraycopy(unicodeSource, 0, result, 0, u);
			return result;
		}
		return unicodeSource;
	}

	/*
	 * Convert Javadoc source to match Javadoc.toString().
	 * Store converted comments and their corresponding tags respectively
	 * in comments and allTags fields
	 */
	char[] getUnixSource(char[] source) {
		int length = source.length;
		int unixLength = length;
		char[] unixSource = new char[unixLength];
		int u=0;
		for (int i=0; i<length; i++) {
			// get next char
			if (source[i] == '\r' && source[i+1] == '\n') {
				i++;
			}
			unixSource[u++] = source[i];
		}
		// Return one well sized array
		if (u != unixLength) {
			char[] result = new char[u];
			System.arraycopy(unixSource, 0, result, 0, u);
			return result;
		}
		return unixSource;
	}
	
	/*
	 * Return all tags number for a given Javadoc
	 */
	int allTags(JSdoc docComment) {
		int all = 0;
		// Count main tags
		Iterator tags = docComment.tags().listIterator();
		while (tags.hasNext()) {
			TagElement tagElement = (TagElement) tags.next();
			if (tagElement.getTagName() != null) {
				all++;
			}
			Iterator fragments = tagElement.fragments().listIterator();
			while (fragments.hasNext()) {
				ASTNode node = (ASTNode) fragments.next();
				if (node.getNodeType() == ASTNode.TAG_ELEMENT) {
					all++;
				}
			}
		}
		return all;
	}

	/*
	 * Add a failure to the list. Use only one method as it easier to put breakpoint to
	 * debug failure when it occurs...
	 */
	private void addFailure(String msg) {
		failures.add(msg);
	}

	/*
	 * Put the failure message in list instead of throwing exception immediately.
	 * This allow to store several failures per test...
	 * @see tearDown method which finally throws the execption to signal that test fails.
	 */
	protected void assumeTrue(String msg, boolean cond) {
		if (!cond) {
			addFailure(msg);
			if (stopOnFailure) assertTrue(msg, cond);
		}
	}

	/*
	 * Put the failure message in list instead of throwing exception immediately.
	 * This allow to store several failures per test...
	 * @see tearDown method which finally throws the execption to signal that test fails.
	 */
	protected void assumeNull(String msg, Object obj) {
		if (obj != null) {
			addFailure(msg);
			if (stopOnFailure) assertNull(msg, obj);
		}
	}

	/*
	 * Put the failure message in list instead of throwing exception immediately.
	 * This allow to store several failures per test...
	 * @see tearDown method which finally throws the execption to signal that test fails.
	 */
	protected void assumeNotNull(String msg, Object obj) {
		if (obj == null) {
			addFailure(msg);
			if (stopOnFailure) assertNotNull(msg, obj);
		}
	}

	/*
	 * Put the failure message in list instead of throwing exception immediately.
	 * This allow to store several failures per test...
	 * @see tearDown method which finally throws the execption to signal that test fails.
	 */
	protected void assumeEquals(String msg, int expected, int actual) {
		if (expected != actual) {
			addFailure(msg+", expected="+expected+" actual="+actual);
			if (stopOnFailure) assertEquals(msg, expected, actual);
		}
	}

	/*
	 * Put the failure message in list instead of throwing exception immediately.
	 * This allow to store several failures per test...
	 * @see tearDown method which finally throws the execption to signal that test fails.
	 */
	protected void assumeEquals(String msg, Object expected, Object actual) {
		if (expected == null && actual == null)
			return;
		if (expected != null && expected.equals(actual))
			return;
		addFailure(msg+", expected:<"+expected+"> actual:<"+actual+'>');
		if (stopOnFailure) assertEquals(msg, expected, actual);
	}

	/*
	 * Verify positions of tags in source
	 */
	private void verifyPositions(JSdoc docComment, char[] source) {
		boolean stop = stopOnFailure;
//		stopOnFailure = false;
		// Verify javadoc start and end position
		int start = docComment.getStartPosition();
		int end = start+docComment.getLength()-1;
		assumeTrue(prefix+"Misplaced javadoc start at <"+start+">: "+docComment, source[start++] == '/' && source[start++] == '*' && source[start++] == '*');
		// Get first meaningful character
		int tagStart = start;
		// Verify tags
		Iterator tags = docComment.tags().listIterator();
		while (tags.hasNext()) {
			while (source[tagStart] == '*' || Character.isWhitespace(source[tagStart])) {
				tagStart++; // purge non-stored characters
			}
			TagElement tagElement = (TagElement) tags.next();
			int teStart = tagElement.getStartPosition();
			assumeEquals(prefix+"Wrong start position <"+teStart+"> for tag element: "+tagElement, tagStart, teStart);
			verifyPositions(tagElement, source);
			tagStart += tagElement.getLength();
		}
		while (source[tagStart] == '*' || Character.isWhitespace(source[tagStart])) {
			tagStart++; // purge non-stored characters
		}
		assumeTrue(prefix+"Misplaced javadoc end at <"+tagStart+'>', source[tagStart-1] == '*' && source[tagStart] == '/');
		assumeEquals(prefix+"Wrong javadoc length at <"+end+">: ", tagStart, end);
		stopOnFailure = stop;
		assertTrue(!stop || failures.size()==0);
	}

	/**
	 * Verify positions of fragments in source
	 * @deprecated using deprecated code
	 */
	private void verifyPositions(TagElement tagElement, char[] source) {
		String text = null;
		// Verify tag name
		String tagName = tagElement.getTagName();
		int tagStart = tagElement.getStartPosition();
		if (tagElement.isNested()) {
			assumeEquals(prefix+"Wrong start position <"+tagStart+"> for "+tagElement, '{', source[tagStart++]);
		}
		if (tagName != null) {
			text= new String(source, tagStart, tagName.length());
			assumeEquals(prefix+"Misplaced tag name at <"+tagStart+">: ", tagName, text);
			tagStart += tagName.length();
		}
		// Verify each fragment
		ASTNode previousFragment = null;
		Iterator elements = tagElement.fragments().listIterator();
		while (elements.hasNext()) {
			ASTNode fragment = (ASTNode) elements.next();
			if (fragment.getNodeType() == ASTNode.TEXT_ELEMENT) {
				if (previousFragment == null && TagElement.TAG_PARAM.equals(tagName) && ((TextElement)fragment).getText().equals("<")) { // special case here for @param <E> syntax
					int start = tagStart;
					// verify '<'
					while (source[start] == ' ' || Character.isWhitespace(source[start])) {
						start++; // purge white characters
					}
					text = new String(source, start, fragment.getLength());
					assumeEquals(prefix+"Misplaced text element at <"+fragment.getStartPosition()+">: ", text, ((TextElement) fragment).getText());
					start += fragment.getLength();
					// verify simple name
					assumeTrue(prefix+"Unexpected fragment end for "+tagElement, elements.hasNext());
					fragment = (ASTNode) elements.next();
					while (source[start] == ' ' || Character.isWhitespace(source[start])) {
						start++; // purge white characters
					}
					assumeEquals(prefix+"Unexpected node type for tag element "+tagElement, ASTNode.SIMPLE_NAME, fragment.getNodeType());
					Name name = (Name) fragment;
					verifyNamePositions(start, name, source);
					start += fragment.getLength();
					// verify simple name
					assumeTrue(prefix+"Unexpected fragment end for "+tagElement, elements.hasNext());
					fragment = (ASTNode) elements.next();
					while (source[start] == ' ' || Character.isWhitespace(source[start])) {
						start++; // purge white characters
					}
					text = new String(source, start, fragment.getLength());
					assumeEquals(prefix+"Misplaced text element at <"+fragment.getStartPosition()+">: ", text, ((TextElement) fragment).getText());
					start += fragment.getLength();
					// reset fragment as simple name to avoid issue with next text element
					fragment = name;
					tagStart += (start- tagStart) - name.getLength();
				} else {
					if (previousFragment == null) {
						if (tagName != null && (source[tagStart] == '\r' || source[tagStart] == '\n')) {
							while (source[tagStart] == '*' || Character.isWhitespace(source[tagStart])) {
								tagStart++; // purge non-stored characters
							}
						}
					} else {
						if (previousFragment.getNodeType() == ASTNode.TEXT_ELEMENT) {
							assumeTrue(prefix+"Wrong length at <"+previousFragment.getStartPosition()+"> for text element "+previousFragment, (source[tagStart] == '\r' /* && source[tagStart+1] == '\n' */ || source[tagStart] == '\n'));
							while (source[tagStart] == '*' || Character.isWhitespace(source[tagStart])) {
								tagStart++; // purge non-stored characters
							}
						} else if (TagElement.TAG_PARAM.equals(tagName) && previousFragment.getNodeType() == ASTNode.SIMPLE_NAME && ((TextElement)fragment).getText().equals(">")) {
							while (source[tagStart] == ' ' || Character.isWhitespace(source[tagStart])) {
								tagStart++; // purge white characters
							}
						} else {
							int start = tagStart;
							boolean newLine = false;
							while (source[start] == '*' || Character.isWhitespace(source[start])) {
								start++; // purge non-stored characters
								if (source[tagStart] == '\r' || source[tagStart] == '\n') {
									newLine = true;
								}
							}
							if (newLine) tagStart = start;
						}
					}
					text = new String(source, tagStart, fragment.getLength());
					assumeEquals(prefix+"Misplaced text element at <"+fragment.getStartPosition()+">: ", text, ((TextElement) fragment).getText());
				}
			} else {
				while (source[tagStart] == '*' || Character.isWhitespace(source[tagStart])) {
					tagStart++; // purge non-stored characters
				}
				if (fragment.getNodeType() == ASTNode.SIMPLE_NAME || fragment.getNodeType() == ASTNode.QUALIFIED_NAME) {
					verifyNamePositions(tagStart, (Name) fragment, source);
				} else if (fragment.getNodeType() == ASTNode.TAG_ELEMENT) {
					TagElement inlineTag = (TagElement) fragment;
					assumeEquals(prefix+"Tag element <"+inlineTag+"> has wrong start position", tagStart, inlineTag.getStartPosition());
					verifyPositions(inlineTag, source);
				} else if (fragment.getNodeType() == ASTNode.MEMBER_REF) {
					MemberRef memberRef = (MemberRef) fragment;
					// Store start position
					int start = tagStart;
					// Verify qualifier position
					Name qualifier = memberRef.getQualifier();
					if (qualifier != null) {
						verifyNamePositions(start, qualifier, source);
						start += qualifier.getLength();
						while (source[start] == '*' || Character.isWhitespace(source[start])) {
							start++; // purge non-stored characters
						}
					}
					// Verify member separator position
					assumeEquals(prefix+"Misplaced # separator at <"+start+"> for member ref "+memberRef, '#', source[start]);
					start++;
					while (source[start] == '*' || Character.isWhitespace(source[start])) {
						start++; // purge non-stored characters
					}
					// Verify member name position
					Name name = memberRef.getName();
					text = new String(source, start, name.getLength());
					assumeEquals(prefix+"Misplaced member ref at <"+start+">: ", text, name.toString());
					verifyNamePositions(start, name, source);
				} else if (fragment.getNodeType() == ASTNode.FUNCTION_REF) {
					FunctionRef methodRef = (FunctionRef) fragment;
					// Store start position
					int start = tagStart;
					// Verify qualifier position
					Name qualifier = methodRef.getQualifier();
					if (qualifier != null) {
						verifyNamePositions(start, qualifier, source);
						start += qualifier.getLength();
						while (source[start] == '*' || Character.isWhitespace(source[start])) {
							start++; // purge non-stored characters
						}
					}
					// Verify member separator position
					assumeEquals(prefix+"Misplaced # separator at <"+start+"> for method ref: "+methodRef, '#', source[start]);
					start++;
					while (source[start] == '*' || Character.isWhitespace(source[start])) {
						start++; // purge non-stored characters
					}
					// Verify member name position
					Name name = methodRef.getName();
					int nameLength = name.getLength();
					text = new String(source, start, nameLength);
					if (!text.equals(name.toString())) { // may have qualified constructor reference for inner classes
						if (methodRef.getQualifier().isQualifiedName()) {
							text = new String(source, start, methodRef.getQualifier().getLength());
							assumeEquals(prefix+"Misplaced method ref name at <"+start+">: ", text, methodRef.getQualifier().toString());
							while (source[start] != '.' || Character.isWhitespace(source[start])) {
								start++; // purge non-stored characters
							}
							start++;
						} else {
							while (source[start] != '.' || Character.isWhitespace(source[start])) {
								start++; // purge non-stored characters
							}
							start++;
							text = new String(source, start, nameLength);
							assumeEquals(prefix+"Misplaced method ref name at <"+start+">: ", text, name.toString());
						}
					}
					verifyNamePositions(start, name, source);
					start += nameLength;
					// Verify arguments starting open parenthesis
					while (source[start] == '*' || Character.isWhitespace(source[start])) {
						start++; // purge non-stored characters
					}
//					assumeEquals(prefix+"Misplaced ( at <"+start+"> for method ref: "+methodRef, '(', source[start]);
					if (source[start] == '(') { // now method reference may have no parenthesis...
						start++;
						// Verify parameters
						Iterator parameters = methodRef.parameters().listIterator();
						while (parameters.hasNext()) {
							FunctionRefParameter param = (FunctionRefParameter) parameters.next();
							boolean lastParam = !parameters.hasNext();
							// Verify parameter type positions
							while (source[start] == '*' || Character.isWhitespace(source[start])) {
								 start++; // purge non-stored characters
							}
							Type type = param.getType();
							if (type.isSimpleType()) {
								verifyNamePositions(start, ((SimpleType)type).getName(), source);
							} else if (type.isPrimitiveType()) {
								text = new String(source, start, type.getLength());
								assumeEquals(prefix+"Misplaced method ref parameter type at <"+start+"> for method ref: "+methodRef, text, type.toString());
							} else if (type.isArrayType()) {
								Type elementType = ((ArrayType) param.getType()).getElementType();
								if (elementType.isSimpleType()) {
									verifyNamePositions(start, ((SimpleType)elementType).getName(), source);
								} else if (elementType.isPrimitiveType()) {
									text = new String(source, start, elementType.getLength());
									assumeEquals(prefix+"Misplaced method ref parameter type at <"+start+"> for method ref: "+methodRef, text, elementType.toString());
								}
							}
							start += type.getLength();
							// if last param then perhaps a varargs
							while (Character.isWhitespace(source[start])) { // do NOT accept '*' in parameter declaration
								 start++; // purge non-stored characters
							}
							if (lastParam && this.astLevel != AST.JLS2 && param.isVarargs()) {
								for (int p=0;p<3;p++) {
									assumeTrue(prefix+"Missing ellipsis for vararg method ref parameter at <"+start+"> for method ref: "+methodRef, source[start++]=='.');
								}
							}
							// Verify parameter name positions
							while (Character.isWhitespace(source[start])) { // do NOT accept '*' in parameter declaration
								 start++; // purge non-stored characters
							}
							name = param.getName();
							if (name != null) {
								text = new String(source, start, name.getLength());
								assumeEquals(prefix+"Misplaced method ref parameter name at <"+start+"> for method ref: "+methodRef, text, name.toString());
								start += name.getLength();
							}
							// Verify end parameter declaration
							while (source[start] == '*' || Character.isWhitespace(source[start])) {
								start++;
							}
							assumeTrue(prefix+"Misplaced parameter end at <"+start+"> for method ref: "+methodRef, source[start] == ',' || source[start] == ')');
							start++;
							if (source[start] == ')') {
								break;
							}
						}
					}
				}
			}
			tagStart += fragment.getLength();
			previousFragment = fragment;
		}
		if (tagElement.isNested()) {
			assumeEquals(prefix+"Wrong end character at <"+tagStart+"> for "+tagElement, '}', source[tagStart++]);
		}
	}

	/*
	 * Verify each name component positions.
	 */
	private void verifyNamePositions(int nameStart, Name name, char[] source) {
		if (name.isQualifiedName()) {
			QualifiedName qualified = (QualifiedName) name;
			int start = qualified.getName().getStartPosition();
			String str = new String(source, start, qualified.getName().getLength());
			assumeEquals(prefix+"Misplaced or wrong name for qualified name: "+name, str, qualified.getName().toString());
			verifyNamePositions(nameStart, ((QualifiedName) name).getQualifier(), source);
		}
		String str = new String(source, nameStart, name.getLength());
		if (str.indexOf('\n') < 0) { // cannot compare if text contains new line
			assumeEquals(prefix+"Misplaced name for qualified name: ", str, name.toString());
		} else if (debug) {
			System.out.println(prefix+"Name contains new line for qualified name: "+name);
		}
	}

	/*
	 * Verify that bindings of Javadoc comment structure are resolved or not.
	 * For expected unresolved binding, verify that following text starts with 'Unknown'
	 */
	private void verifyBindings(JSdoc docComment) {
		boolean stop = stopOnFailure;
//		stopOnFailure = false;
		// Verify tags
		Iterator tags = docComment.tags().listIterator();
		while (tags.hasNext()) {
			verifyBindings((TagElement) tags.next());
		}
		stopOnFailure = stop;
		assertTrue(!stop || failures.size()==0);
	}

	/*
	 * Verify that bindings of Javadoc tag structure are resolved or not.
	 * For expected unresolved binding, verify that following text starts with 'Unknown'
	 */
	private void verifyBindings(TagElement tagElement) {
		// Verify each fragment
		Iterator elements = tagElement.fragments().listIterator();
		IBinding previousBinding = null;
		ASTNode previousFragment = null;
		boolean resolvedBinding = false;
		while (elements.hasNext()) {
			ASTNode fragment = (ASTNode) elements.next();
			if (fragment.getNodeType() == ASTNode.TEXT_ELEMENT) {
				TextElement text = (TextElement) fragment;
				if (resolvedBinding) {
					if (previousBinding == null) {
						assumeTrue(prefix+"Reference '"+previousFragment+"' should be bound!", text.getText().trim().indexOf("Unknown")>=0);
					} else {
						assumeTrue(prefix+"Unknown reference '"+previousFragment+"' should NOT be bound!", text.getText().trim().indexOf("Unknown")<0);
					}
				}
				previousBinding = null;
				resolvedBinding = false;
			} else if (fragment.getNodeType() == ASTNode.TAG_ELEMENT) {
				verifyBindings((TagElement) fragment);
				previousBinding = null;
				resolvedBinding = false;
			} else {
				resolvedBinding = true;
				if (fragment.getNodeType() == ASTNode.SIMPLE_NAME) {
					previousBinding = ((Name)fragment).resolveBinding();
				} else if (fragment.getNodeType() == ASTNode.QUALIFIED_NAME) {
					QualifiedName name = (QualifiedName) fragment;
					previousBinding = name.resolveBinding();
					verifyNameBindings(name);
				} else if (fragment.getNodeType() == ASTNode.MEMBER_REF) {
					MemberRef memberRef = (MemberRef) fragment;
					previousBinding = memberRef.resolveBinding();
					if (previousBinding != null) {
						SimpleName name = memberRef.getName();
						assumeNotNull(prefix+""+name+" binding was not foundfound in "+fragment, name.resolveBinding());
						verifyNameBindings(memberRef.getQualifier());
					}
				} else if (fragment.getNodeType() == ASTNode.FUNCTION_REF) {
					FunctionRef methodRef = (FunctionRef) fragment;
					previousBinding = methodRef.resolveBinding();
					if (previousBinding != null) {
						SimpleName methodName = methodRef.getName();
						IBinding methNameBinding = methodName.resolveBinding();
						Name methodQualifier = methodRef.getQualifier();
						// TODO (frederic) Replace the two following lines by commented block when bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=62650 will be fixed
						assumeNotNull(prefix+""+methodName+" binding was not found in "+fragment, methNameBinding);
						verifyNameBindings(methodQualifier);
						/*
						if (methodQualifier == null) {
							if (methNameBinding == null) {
								char firstChar = methodName.getIdentifier().charAt(0);
								if (Character.isUpperCase(firstChar)) {
									// assume that selector starting with uppercase is for constructor => signal that binding is null
									System.out.println(prefix+"Binding for selector of  '"+methodRef+"' is null.");
								}
							} else {
								if (methNameBinding.getName().equals(methodName.getIdentifier())) { // binding is not null only for constructor
									assumeNotNull(prefix+""+methodName+" binding was not found!",methNameBinding);
								} else {
									assumeNull(prefix+""+methodName+" binding should be null!", methNameBinding);
								}
							}
						} else {
							SimpleName methodSimpleType = null;
							if (methodQualifier.isQualifiedName()) {
								methodSimpleType = ((QualifiedName)methodQualifier).getName();
							} else {
								methodSimpleType = (SimpleName) methodQualifier;
							}
							if (methodSimpleType.getIdentifier().equals(methodName.getIdentifier())) { // binding is not null only for constructor
								assumeNotNull(prefix+""+methodName+" binding was not found!",methNameBinding);
							} else {
								assumeNull(prefix+""+methodName+" binding should be null!", methNameBinding);
							}
							verifyNameBindings(methodRef.getQualifier());
						}
						*/
						Iterator parameters = methodRef.parameters().listIterator();
						while (parameters.hasNext()) {
							FunctionRefParameter param = (FunctionRefParameter) parameters.next();
							Type type = param.getType();
							assumeNotNull(prefix+""+type+" binding was not found in "+fragment, type.resolveBinding());
							if (type.isSimpleType()) {
								verifyNameBindings(((SimpleType)type).getName());
							} else if (type.isArrayType()) {
								Type elementType = ((ArrayType) param.getType()).getElementType();
								assumeNotNull(prefix+""+elementType+" binding was not found in "+fragment, elementType.resolveBinding());
								if (elementType.isSimpleType()) {
									verifyNameBindings(((SimpleType)elementType).getName());
								}
							}
							//	Do not verify parameter name as no binding is expected for them
						}
					}
				}
			}
			previousFragment = fragment;
		}
		assumeTrue(prefix+"Reference '"+(previousFragment==null?tagElement:previousFragment)+"' should be bound!", (!resolvedBinding || previousBinding != null));
	}

	/*
	 * Verify each name component binding.
	 */
	private void verifyNameBindings(Name name) {
		if (name != null) {
			IBinding binding = name.resolveBinding();
			if (name.toString().indexOf("Unknown") > 0) {
				assumeNull(prefix+name+" binding should be null!", binding);
			} else {
				assumeNotNull(prefix+name+" binding was not found!", binding);
			}
			SimpleName simpleName = null;
			int index = 0;
			while (name.isQualifiedName()) {
				simpleName = ((QualifiedName) name).getName();
				binding = simpleName.resolveBinding();
				if (simpleName.getIdentifier().equalsIgnoreCase("Unknown")) {
					assumeNull(prefix+simpleName+" binding should be null!", binding);
				} else {
					assumeNotNull(prefix+simpleName+" binding was not found!", binding);
				}
				if (index > 0 && packageBinding) {
					assumeEquals(prefix+"Wrong binding type!", IBinding.PACKAGE, binding.getKind());
				}
				index++;
				name = ((QualifiedName) name).getQualifier();
				binding = name.resolveBinding();
				if (name.toString().indexOf("Unknown") > 0) {
					assumeNull(prefix+name+" binding should be null!", binding);
				} else {
					assumeNotNull(prefix+name+" binding was not found!", binding);
				}
				if (packageBinding) {
					assumeEquals(prefix+"Wrong binding type!", IBinding.PACKAGE, binding.getKind());
				}
			}
		}
	}

	/* (non-Javadoc)
	 * @see junit.framework.TestCase#setUp()
	 */
	protected void verifyComments(String test) throws JavaScriptModelException {
		IJavaScriptUnit[] units = getCompilationUnits("Converter" , "src", "javadoc."+test); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
		for (int i=0; i<units.length; i++) {
			verifyComments(units[i]);
		}
	}

	/*
	 * Verify the comments of a compilation unit.
	 */
	protected void verifyWorkingCopiesComments() throws JavaScriptModelException {
		assumeNotNull("No working copies to verify!", workingCopies);
		int length = workingCopies.length;
		assumeTrue("We need to have at least one working copy to verify!", length>0);
		for (int i=0; i<length; i++) {
			verifyComments(workingCopies[i]);
		}
	}

	/*
	 * Verify the comments of a compilation unit.
	 */
	protected JavaScriptUnit verifyComments(IJavaScriptUnit unit) throws JavaScriptModelException {
		// Get test file
		sourceUnit = unit;
		prefix = unit.getElementName()+": ";

		// Get current project
		String sourceStr = sourceUnit.getSource();
		if (savedOptions != null && !sourceUnit.getJavaScriptProject().getElementName().equals(currentProject.getElementName())) {
			currentProject.setOptions(savedOptions);
			savedOptions = null;
		}
		currentProject = sourceUnit.getJavaScriptProject();
		if (savedOptions == null) savedOptions = currentProject.getOptions(false);

		// set up java project options
		currentProject.setOption(JavaScriptCore.COMPILER_PB_INVALID_JAVADOC, compilerOption);
		currentProject.setOption(JavaScriptCore.COMPILER_PB_MISSING_JAVADOC_TAGS, compilerOption);
		currentProject.setOption(JavaScriptCore.COMPILER_PB_MISSING_JAVADOC_COMMENTS, compilerOption);
		currentProject.setOption(JavaScriptCore.COMPILER_PB_METHOD_WITH_CONSTRUCTOR_NAME, JavaScriptCore.IGNORE);
		currentProject.setOption(JavaScriptCore.COMPILER_DOC_COMMENT_SUPPORT, docCommentSupport);

		// Verify source regardings converted comments
		char[] source = sourceStr.toCharArray();
		String fileName = unit.getPath().toString();
		try {
			return verifyComments(fileName, source);
		}
		catch (RuntimeException ex) {
			TEST_COUNTERS[3]++;
			throw ex;
		}
	}

	protected JavaScriptUnit verifyComments(String fileName, char[] source) {
		return verifyComments(fileName, source, null);
	}

	protected JavaScriptUnit verifyComments(String fileName, char[] source, Map options) {

		// Verify comments either in unicode or not
		char[] testedSource = source;
		if (UNICODE) {
			testedSource = getUnicodeSource(source);
		}

		// Verify comments either in unicode or not
		else if (unix) {
			testedSource = getUnixSource(source);
		}
		
		// Get comments infos from test file
		setSourceComment(testedSource);

		// Create DOM AST nodes hierarchy		
		List unitComments = null;
		String sourceLevel = null;
		String complianceLevel = null;
		if (currentProject != null) {
			if (astLevel == AST.JLS3) {
				complianceLevel = currentProject.getOption(JavaScriptCore.COMPILER_COMPLIANCE, true);
				sourceLevel = currentProject.getOption(JavaScriptCore.COMPILER_SOURCE, true);
				currentProject.setOption(JavaScriptCore.COMPILER_COMPLIANCE, JavaScriptCore.VERSION_1_5);
				currentProject.setOption(JavaScriptCore.COMPILER_SOURCE, JavaScriptCore.VERSION_1_5);
			}
		}
		JavaScriptUnit compilUnit = (JavaScriptUnit) runConversion(testedSource, fileName, currentProject, options);
		if (compilerOption.equals(JavaScriptCore.ERROR)) {
			assumeEquals(prefix+"Unexpected problems", 0, compilUnit.getProblems().length); //$NON-NLS-1$
		} else if (compilerOption.equals(JavaScriptCore.WARNING)) {
			IProblem[] problemsList = compilUnit.getProblems();
			int length = problemsList.length;
			if (length > 0) {
				problems.append("  - "+prefix+length+" problems:"); //$NON-NLS-1$
				for (int i = 0; i < problemsList.length; i++) {
					problems.append("	+ ");
					problems.append(problemsList[i]);
					problems.append("\n");
				}
			}
		}
		unitComments = compilUnit.getCommentList();
		assumeNotNull(prefix+"Unexpected problems", unitComments);
		
		// Basic comments verification
		int size = unitComments.size();
		assumeEquals(prefix+"Wrong number of comments!", comments.size(), size);

		// Verify comments positions and bindings
		for (int i=0; i<size; i++) {
			Comment comment = (Comment) unitComments.get(i);
			List tags = (List) allTags.get(i);
			// Verify flattened content
			String stringComment = (String) comments.get(i);
//			ASTConverterJavadocFlattener printer = new ASTConverterJavadocFlattener(stringComment);
//			comment.accept(printer);
			String text = new String(testedSource, comment.getStartPosition(), comment.getLength());
			assumeEquals(prefix+"Flattened comment does NOT match source!", stringComment, text);
			// Verify javdoc tags positions and bindings
			if (comment.isDocComment()) {
				JSdoc docComment = (JSdoc)comment;
				if (docCommentSupport.equals(JavaScriptCore.ENABLED)) {
					assumeEquals(prefix+"Invalid tags number in javadoc:\n"+docComment+"\n", tags.size(), allTags(docComment));
					verifyPositions(docComment, testedSource);
					if (resolveBinding) {
						verifyBindings(docComment);
					}
				} else {
					assumeEquals("Javadoc should be flat!", 0, docComment.tags().size());
				}
			}
		}
		
		/* Verify each javadoc: not implemented yet
		Iterator types = compilUnit.types().listIterator();
		while (types.hasNext()) {
			TypeDeclaration typeDeclaration = (TypeDeclaration) types.next();
			verifyJavadoc(typeDeclaration.getJavadoc());
		}
		*/

		if (sourceLevel != null) {
			currentProject.setOption(JavaScriptCore.COMPILER_COMPLIANCE, complianceLevel);
			currentProject.setOption(JavaScriptCore.COMPILER_SOURCE, sourceLevel);
		}
		// Return compilation unit for possible further verifications
		return compilUnit;
	}

	/* 
	 * Verify each javadoc
	 * Not implented yet
	private void verifyJavadoc(Javadoc docComment) {
	}
	*/

	/**
	 * Check javadoc for FunctionDeclaration
	 */
	public void test000() throws JavaScriptModelException {
		verifyComments("test000");
	}

	/**
	 * Check javadoc for invalid syntax
	 */
	public void test001() throws JavaScriptModelException {
		verifyComments("test001");
	}

	/**
	 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=50781"
	 */
	public void test002() throws JavaScriptModelException {
		verifyComments("test002");
	}

	/**
	 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=50784"
	 */
	public void test003() throws JavaScriptModelException {
		verifyComments("test003");
	}

	/**
	 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=50785"
	 */
	public void test004() throws JavaScriptModelException {
		verifyComments("test004");
	}

	/**
	 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=50838"
	 */
	public void test005() throws JavaScriptModelException {
		verifyComments("test005");
	}

	/**
	 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=50877"
	 */
	public void test006() throws JavaScriptModelException {
		verifyComments("test006");
	}

	/**
	 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=50877"
	 */
	public void test007() throws JavaScriptModelException {
		verifyComments("test007");
	}

	/**
	 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=50877"
	 */
	public void test008() throws JavaScriptModelException {
		verifyComments("test008");
	}

	/**
	 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=50877"
	 */
	public void test009() throws JavaScriptModelException {
		verifyComments("test009");
	}

	/**
	 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=50880"
	 */
	public void test010() throws JavaScriptModelException {
		verifyComments("test010");
	}

	/**
	 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=47396"
	 */
	public void test011() throws JavaScriptModelException {
		problems = new StringBuffer();
		sourceUnit = getCompilationUnit("Converter" , "src", "javadoc.test011", "Test.js"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
		ASTNode result = runConversion(sourceUnit, true);
		assumeNotNull("No compilation unit", result);
	}

	/**
	 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=50938"
	 */
	public void test012() throws JavaScriptModelException {
		verifyComments("test012");
	}

	/**
	 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=51104"
	 */
	public void test013() throws JavaScriptModelException {
		verifyComments("test013");
	}

	/**
	 * Verify that text on next line following empty tag element
	 * is well positionned.
	 */
	public void test014() throws JavaScriptModelException {
		verifyComments("test014");
	}

	/**
	 * Verify that we do not report failure when types are written on several lines
	 * in Javadoc comments.
	 */
	public void test015() throws JavaScriptModelException {
		verifyComments("test015");
	}

	/**
	 * Verify DefaultCommentMapper heuristic to get leading and trailing comments
	 */
	protected void verifyMapper(String folder, int count, int[] indexes) throws JavaScriptModelException {
		IJavaScriptUnit[] units = getCompilationUnits("Converter" , "src", "javadoc."+folder); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
		for (int i=0; i<units.length; i++) {
			sourceUnit = units[i];
			ASTNode result = runConversion(sourceUnit, false);
			final JavaScriptUnit compilUnit = (JavaScriptUnit) result;
			assumeEquals(prefix+"Wrong number of problems", 0, compilUnit.getProblems().length); //$NON-NLS-1$
			assumeEquals(prefix+"Wrong number of comments", count, compilUnit.getCommentList().size());
			// Verify first method existence
			ASTNode node = getASTNode((JavaScriptUnit) result, 0, 0);
			assumeNotNull("We should get a non-null ast node", node);
			assumeTrue("Not a method declaration", node.getNodeType() == ASTNode.FUNCTION_DECLARATION); //$NON-NLS-1$
			FunctionDeclaration method = (FunctionDeclaration) node;
			// Verify first method extended positions
			int commentStart = method.getStartPosition();
			if (indexes[0]>=0) {
				Comment comment = (Comment) compilUnit.getCommentList().get(indexes[0]);
				commentStart = comment.getStartPosition();
			}
			int startPosition = compilUnit.getExtendedStartPosition(method);
			assumeEquals("Method "+node+" does not start at the right position", commentStart, startPosition);
			int methodEnd = startPosition + compilUnit.getExtendedLength(method) - 1;
			int commentEnd = method.getStartPosition() + method.getLength() - 1;
			if (indexes[1]>=0) {
				Comment comment = (Comment) compilUnit.getCommentList().get(indexes[1]);
				commentEnd = comment.getStartPosition() + comment.getLength() - 1;
			}
			assumeEquals("Method "+node+" does not have the correct length", commentEnd, methodEnd);
			// Verify second method existence
			node = getASTNode((JavaScriptUnit) result, 0, 1);
			assumeNotNull("We should get a non-null ast node", node);
			assumeTrue("Not a method declaration", node.getNodeType() == ASTNode.FUNCTION_DECLARATION); //$NON-NLS-1$
			method = (FunctionDeclaration) node;
			// Verify second method extended positions
			commentStart = method.getStartPosition();
			if (indexes[2]>=0) {
				Comment comment = (Comment) compilUnit.getCommentList().get(indexes[2]);
				commentStart = comment.getStartPosition();
			}
			startPosition = compilUnit.getExtendedStartPosition(method);
			assumeEquals("Method "+node+" does not start at the right position", commentStart, startPosition);
			methodEnd = startPosition + compilUnit.getExtendedLength(method) - 1;
			commentEnd = method.getStartPosition() + method.getLength() - 1;
			if (indexes[3]>=0) {
				Comment comment = (Comment) compilUnit.getCommentList().get(indexes[3]);
				commentEnd = comment.getStartPosition() + comment.getLength() - 1;
			}
			assumeEquals("Method "+node+" does not have the correct length", commentEnd, methodEnd);
		}
	}

	/**
	 * Verify DefaultCommentMapper heuristic to get leading and trailing comments
	 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=53445"
	 */
	public void test100() throws JavaScriptModelException {
		verifyMapper("test100", 16, new int[] {2,7,8,15});
	}
	public void test101() throws JavaScriptModelException {
		verifyMapper("test101", 8, new int[] {1,3,4,7});
	}
	public void test102() throws JavaScriptModelException {
		verifyMapper("test102", 16, new int[] {4,9,10,13});
	}
	public void test103() throws JavaScriptModelException {
		verifyMapper("test103", 8, new int[] {2,4,5,6});
	}
	public void test104() throws JavaScriptModelException {
		verifyMapper("test104", 16, new int[] {2,7,8,15});
	}
	public void test105() throws JavaScriptModelException {
		verifyMapper("test105", 16, new int[] {-1,11,-1,15});
	}
	public void test106() throws JavaScriptModelException {
		verifyMapper("test106", 8, new int[] {-1,5,-1,7});
	}
	public void test107() throws JavaScriptModelException {
		verifyMapper("test107", 16, new int[] {2,7,8,-1});
	}
	public void test108() throws JavaScriptModelException {
		verifyMapper("test108", 8, new int[] {1,3,4,-1});
	}

	/**
	 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=54776"
	 */
	public void testBug54776() throws JavaScriptModelException {
		sourceUnit = getCompilationUnit("Converter" , "src", "javadoc.testBug54776", "Test.js"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
		ASTNode result = runConversion(sourceUnit, false);
		final JavaScriptUnit compilUnit = (JavaScriptUnit) result;
		assumeEquals(prefix+"Wrong number of problems", 0, compilUnit.getProblems().length); //$NON-NLS-1$
		assumeEquals(prefix+"Wrong number of comments", 2, compilUnit.getCommentList().size());
		// get comments range
		Comment comment = (Comment) compilUnit.getCommentList().get(0);
		int commentStart = comment.getStartPosition();
		int extendedLength = ((Comment) compilUnit.getCommentList().get(1)).getStartPosition()-commentStart+comment.getLength();
		// get method invocation in field initializer
		ASTNode node = getASTNode((JavaScriptUnit) result, 0);
		assumeNotNull("We should get a non-null ast node", node);
		assumeTrue("Not a type declaration", node.getNodeType() == ASTNode.TYPE_DECLARATION); //$NON-NLS-1$
		TypeDeclaration typeDecl = (TypeDeclaration) node;
		FieldDeclaration[] fields = typeDecl.getFields();
		assumeEquals("We should have a field declaration", 1, fields.length);
		List fragments = fields[0].fragments();
		assumeEquals("We should have a variable fragment", 1, fragments.size());
		VariableDeclarationFragment fragment = (VariableDeclarationFragment) fragments.get(0);
		Expression expression = fragment.getInitializer();
		assumeTrue("We should get an expression", expression instanceof FunctionInvocation);
		FunctionInvocation methodInvocation = (FunctionInvocation) expression;
		// verify  that methodinvocation extended range includes leading and trailing comment
		int methodStart = compilUnit.getExtendedStartPosition(methodInvocation);
		assumeEquals("Method invocation "+methodInvocation+" does not start at the right position", commentStart, methodStart);
		int methodLength = compilUnit.getExtendedLength(methodInvocation);
		assumeEquals("Method invocation "+methodInvocation+" does not have the correct length", extendedLength, methodLength);
	}

	/**
	 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=55221"
	 */
	public void testBug55221a() throws JavaScriptModelException {
		sourceUnit = getCompilationUnit("Converter" , "src", "javadoc.testBug55221.a", "Test.js"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
		ASTNode result = runConversion(sourceUnit, false);
		final JavaScriptUnit compilUnit = (JavaScriptUnit) result;
		assumeEquals(prefix+"Wrong number of problems", 0, compilUnit.getProblems().length); //$NON-NLS-1$
		assumeEquals(prefix+"Wrong number of comments", 1, compilUnit.getCommentList().size());
		// Get comment range
		Comment comment = (Comment) compilUnit.getCommentList().get(0);
		int commentStart = comment.getStartPosition();
		// get first method
		ASTNode node = getASTNode(compilUnit, 0, 0);
		assumeNotNull("We should get a non-null ast node", node);
		assumeTrue("Not a method declaration", node.getNodeType() == ASTNode.FUNCTION_DECLARATION); //$NON-NLS-1$
		FunctionDeclaration method = (FunctionDeclaration) node;
		// verify that first method does not include comment
		int methodStart = compilUnit.getExtendedStartPosition(method);
		assumeEquals("Method "+method+" does not start at the right position", method.getStartPosition(), methodStart);
		int methodLength = compilUnit.getExtendedLength(method);
		assumeEquals("Method declaration "+method+" does not end at the right position",method.getLength(), methodLength);
		// get method body
		node = method.getBody();
		assumeNotNull("We should get a non-null ast node", node);
		assumeTrue("Not a block", node.getNodeType() == ASTNode.BLOCK); //$NON-NLS-1$
		Block block = (Block) node;
		// verify that body does not include following comment
		int blockStart = compilUnit.getExtendedStartPosition(block);
		assumeEquals("Body block "+block+" does not start at the right position", block.getStartPosition(), blockStart);
		int blockLength = compilUnit.getExtendedLength(block);
		assumeEquals("Body block "+block+" does not have the correct length", block.getLength(), blockLength);
		// get second method
		node = getASTNode(compilUnit, 0, 1);
		assumeNotNull("We should get a non-null ast node", node);
		assumeTrue("Not a method declaration", node.getNodeType() == ASTNode.FUNCTION_DECLARATION); //$NON-NLS-1$
		method = (FunctionDeclaration) node;
		// verify that second method start includes comment
		assumeEquals("Method declaration "+method+" does not start at the right position", commentStart, method.getStartPosition());
	}
	public void testBug55221b() throws JavaScriptModelException {
		sourceUnit = getCompilationUnit("Converter" , "src", "javadoc.testBug55221.b", "Test.js"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
		ASTNode result = runConversion(sourceUnit, false);
		final JavaScriptUnit compilUnit = (JavaScriptUnit) result;
		assumeEquals(prefix+"Wrong number of problems", 0, compilUnit.getProblems().length); //$NON-NLS-1$
		assumeEquals(prefix+"Wrong number of comments", 1, compilUnit.getCommentList().size());
		// Get comment range
		Comment comment = (Comment) compilUnit.getCommentList().get(0);
		int commentStart = comment.getStartPosition();
		// get first method
		ASTNode node = getASTNode(compilUnit, 0, 0);
		assumeNotNull("We should get a non-null ast node", node);
		assumeTrue("Not a method declaration", node.getNodeType() == ASTNode.FUNCTION_DECLARATION); //$NON-NLS-1$
		FunctionDeclaration method = (FunctionDeclaration) node;
		// verify that first method does not include comment
		int methodStart = compilUnit.getExtendedStartPosition(method);
		assumeEquals("Method "+method+" does not start at the right position", method.getStartPosition(), methodStart);
		int methodLength = compilUnit.getExtendedLength(method);
		assumeEquals("Method declaration "+method+" does not end at the right position",method.getLength(), methodLength);
		// get method body
		node = method.getBody();
		assumeNotNull("We should get a non-null ast node", node);
		assumeTrue("Not a block", node.getNodeType() == ASTNode.BLOCK); //$NON-NLS-1$
		Block block = (Block) node;
		// verify that body does not include following comment
		int blockStart = compilUnit.getExtendedStartPosition(block);
		assumeEquals("Body block "+block+" does not start at the right position", block.getStartPosition(), blockStart);
		int blockLength = compilUnit.getExtendedLength(block);
		assumeEquals("Body block "+block+" does not have the correct length", block.getLength(), blockLength);
		// get second method
		node = getASTNode(compilUnit, 0, 1);
		assumeNotNull("We should get a non-null ast node", node);
		assumeTrue("Not a method declaration", node.getNodeType() == ASTNode.FUNCTION_DECLARATION); //$NON-NLS-1$
		method = (FunctionDeclaration) node;
		// verify that second method start includes comment
		assumeEquals("Method declaration "+method+" does not start at the right position", commentStart, method.getStartPosition());
	}
	public void testBug55221c() throws JavaScriptModelException {
		sourceUnit = getCompilationUnit("Converter" , "src", "javadoc.testBug55221.c", "Test.js"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
		ASTNode result = runConversion(sourceUnit, false);
		final JavaScriptUnit compilUnit = (JavaScriptUnit) result;
		assumeEquals(prefix+"Wrong number of problems", 0, compilUnit.getProblems().length); //$NON-NLS-1$
		assumeEquals(prefix+"Wrong number of comments", 1, compilUnit.getCommentList().size());
		// Get comment range
		Comment comment = (Comment) compilUnit.getCommentList().get(0);
		int commentStart = comment.getStartPosition();
		int commentEnd = commentStart+comment.getLength()-1;
		// get first method
		ASTNode node = getASTNode(compilUnit, 0, 0);
		assumeNotNull("We should get a non-null ast node", node);
		assumeTrue("Not a method declaration", node.getNodeType() == ASTNode.FUNCTION_DECLARATION); //$NON-NLS-1$
		FunctionDeclaration method = (FunctionDeclaration) node;
		// verify that first method includes comment
		int methodStart = compilUnit.getExtendedStartPosition(method);
		assumeEquals("Method "+method+" does not start at the right position", method.getStartPosition(), methodStart);
		int methodLength = compilUnit.getExtendedLength(method);
		assumeEquals("Method "+method+" does not end at the right position", commentEnd, methodStart+methodLength-1);
		// get method body
		node = method.getBody();
		assumeNotNull("We should get a non-null ast node", node);
		assumeTrue("Not a block", node.getNodeType() == ASTNode.BLOCK); //$NON-NLS-1$
		Block block = (Block) node;
		// verify that body includes following comment
		int blockStart = compilUnit.getExtendedStartPosition(block);
		assumeEquals("Body block "+block+" does not start at the right position", block.getStartPosition(), blockStart);
		int blockLength = compilUnit.getExtendedLength(block);
		assumeEquals("Body block "+block+" does not end at the right position", commentEnd, blockStart+blockLength-1);
		// get second method
		node = getASTNode(compilUnit, 0, 1);
		assumeNotNull("We should get a non-null ast node", node);
		assumeTrue("Not a method declaration", node.getNodeType() == ASTNode.FUNCTION_DECLARATION); //$NON-NLS-1$
		method = (FunctionDeclaration) node;
		// verify that second method does not include comment
		methodStart = compilUnit.getExtendedStartPosition(method);
		assumeEquals("Method "+method+" does not start at the right position", method.getStartPosition(), methodStart);
		methodLength = compilUnit.getExtendedLength(method);
		assumeEquals("Method declaration "+method+" does not end at the right position",method.getLength(), methodLength);
	}
	/** @deprecated using deprecated code */
	public void testBug55221d() throws JavaScriptModelException {
		sourceUnit = getCompilationUnit("Converter" , "src", "javadoc.testBug55221.d", "Test.js"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
		ASTNode result = runConversion(sourceUnit, false);
		final JavaScriptUnit compilUnit = (JavaScriptUnit) result;
		assumeEquals(prefix+"Wrong number of problems", 0, compilUnit.getProblems().length); //$NON-NLS-1$
		assumeEquals(prefix+"Wrong number of comments", 2, compilUnit.getCommentList().size());
		// get first method
		ASTNode node = getASTNode(compilUnit, 0, 0);
		assumeNotNull("We should get a non-null ast node", node);
		assumeTrue("Not a method declaration", node.getNodeType() == ASTNode.FUNCTION_DECLARATION); //$NON-NLS-1$
		FunctionDeclaration method = (FunctionDeclaration) node;
		// verify that first method includes comment
		int methodStart = compilUnit.getExtendedStartPosition(method);
		assumeEquals("Method "+method+" does not start at the right position", method.getStartPosition(), methodStart);
		int methodLength = compilUnit.getExtendedLength(method);
		assumeEquals("Method "+method+" does not have the right length", methodLength, method.getLength());
		// get return type
		node = method.getReturnType();
		assumeNotNull("We should get a non-null ast node", node);
		assumeTrue("Not return type", node.getNodeType() == ASTNode.PRIMITIVE_TYPE); //$NON-NLS-1$
		PrimitiveType returnType = (PrimitiveType) node;
		// verify that return type includes following comment
		int returnStart = compilUnit.getExtendedStartPosition(returnType);
		assumeEquals("Return type "+returnType+" does not start at the right position", returnType.getStartPosition(), returnStart);
		int returnLength = compilUnit.getExtendedLength(returnType);
		assumeEquals("Return type "+returnType+" does not have the right length", returnType.getLength(), returnLength);
	}
	public void testBug55223a() throws JavaScriptModelException {
//		stopOnFailure = false;
		sourceUnit = getCompilationUnit("Converter" , "src", "javadoc.testBug55223", "TestA.js"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
		ASTNode result = runConversion(sourceUnit, false);
		final JavaScriptUnit compilUnit = (JavaScriptUnit) result;
		assumeEquals(prefix+"Wrong number of problems", 0, compilUnit.getProblems().length); //$NON-NLS-1$
		assumeEquals(prefix+"Wrong number of comments", 2, compilUnit.getCommentList().size());
		// get method
		ASTNode node = getASTNode(compilUnit, 0, 0);
		assumeNotNull("We should get a non-null ast node", node);
		assumeEquals("Not a method declaration", ASTNode.FUNCTION_DECLARATION, node.getNodeType()); //$NON-NLS-1$
		FunctionDeclaration method = (FunctionDeclaration) node;
		// get method body
		node = method.getBody();
		assumeNotNull("We should get a non-null ast node", node);
		assumeEquals("Not a block", ASTNode.BLOCK, node.getNodeType()); //$NON-NLS-1$
		Block block = (Block) node;
		// verify block statements start/end positions
		Iterator statements = block.statements().iterator();
		int idx = 0;
		while (statements.hasNext()) {
			node = (ExpressionStatement) statements.next();
			assumeEquals("Not a block", ASTNode.EXPRESSION_STATEMENT, node.getNodeType()); //$NON-NLS-1$
			ExpressionStatement statement = (ExpressionStatement) node;
			int statementStart = statement.getStartPosition();
			int statementEnd = statementStart + statement.getLength() - 1;
			if (idx < 2) {
				// Get comment range
				Comment comment = (Comment) compilUnit.getCommentList().get(idx);
				int commentStart = comment.getStartPosition();
				statementEnd = commentStart+comment.getLength()-1;
			}
			int extendedStart = compilUnit.getExtendedStartPosition(statement);
			assumeEquals("Statement "+statement+" does not start at the right position", statementStart, extendedStart);
			int extendedEnd = extendedStart + compilUnit.getExtendedLength(statement) - 1;
			assumeEquals("Statement "+statement+" does not end at the right position", statementEnd, extendedEnd);
			idx++;
		}
	}
	/** @deprecated using deprecated code */
	public void testBug55223b() throws JavaScriptModelException {
		sourceUnit = getCompilationUnit("Converter" , "src", "javadoc.testBug55223", "TestB.js"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
		ASTNode result = runConversion(sourceUnit, false);
		final JavaScriptUnit compilUnit = (JavaScriptUnit) result;
		assumeEquals(prefix+"Wrong number of problems", 0, compilUnit.getProblems().length); //$NON-NLS-1$
		assumeEquals(prefix+"Wrong number of comments", 2, compilUnit.getCommentList().size());
		// Get comment range
		Comment comment = (Comment) compilUnit.getCommentList().get(1);
		int commentStart = comment.getStartPosition();
		// get method
		ASTNode node = getASTNode(compilUnit, 0, 0);
		assumeNotNull("We should get a non-null ast node", node);
		assumeEquals("Not a method declaration", ASTNode.FUNCTION_DECLARATION, node.getNodeType()); //$NON-NLS-1$
		FunctionDeclaration method = (FunctionDeclaration) node;
		// get return type
		node = method.getReturnType();
		assumeNotNull("We should get a non-null ast node", node);
		assumeTrue("Not return type", node.getNodeType() == ASTNode.SIMPLE_TYPE); //$NON-NLS-1$
		SimpleType returnType = (SimpleType) node;
		// verify that return type includes following comment
		int returnStart = compilUnit.getExtendedStartPosition(returnType);
		assumeEquals("Return type "+returnType+" does not start at the right position", commentStart, returnStart);
		int returnEnd = returnStart + compilUnit.getExtendedLength(returnType) - 1;
		assumeEquals("Return type "+returnType+" does not end at the right length", returnType.getStartPosition()+returnType.getLength()-1, returnEnd);
	}
	/*
	 * End DefaultCommentMapper verifications
	 */

	/**
	 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=48489"
	 */
	public void testBug48489() throws JavaScriptModelException {
		verifyComments("testBug48489");
	}

	/**
	 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=50898"
	 */
	public void testBug50898() throws JavaScriptModelException {
		IJavaScriptUnit unit = getCompilationUnit("Converter" , "src", "javadoc.testBug50898", "Test.js"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
		packageBinding = false;
		verifyComments(unit);
	}

	/**
	 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=51226"
	 */
	public void testBug51226() throws JavaScriptModelException {
		IJavaScriptUnit[] units = getCompilationUnits("Converter" , "src", "javadoc.testBug51226"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
		for (int i=0; i<units.length; i++) {
			ASTNode result = runConversion(units[i], false);
			final JavaScriptUnit unit = (JavaScriptUnit) result;
			assumeEquals(prefix+"Wrong number of problems", 0, unit.getProblems().length); //$NON-NLS-1$
			assumeEquals(prefix+"Wrong number of comments", 1, unit.getCommentList().size());
			Comment comment = (Comment) unit.getCommentList().get(0);
			assumeTrue(prefix+"Comment should be a Javadoc one", comment.isDocComment());
			if (docCommentSupport.equals(JavaScriptCore.ENABLED)) {
				JSdoc docComment = (JSdoc) comment;
				assumeEquals(prefix+"Wrong number of tags", 1, docComment.tags().size());
				TagElement tagElement = (TagElement) docComment.tags().get(0);
				assumeNull(prefix+"Wrong type of tag ["+tagElement+"]", tagElement.getTagName());
				assumeEquals(prefix+"Wrong number of fragments in tag ["+tagElement+"]", 1, tagElement.fragments().size());
				ASTNode fragment = (ASTNode) tagElement.fragments().get(0);
				assumeEquals(prefix+"Invalid type for fragment ["+fragment+"]", ASTNode.TEXT_ELEMENT, fragment.getNodeType());
				TextElement textElement = (TextElement) fragment;
				assumeEquals(prefix+"Invalid content for text element ", "Test", textElement.getText());
				if (debug) System.out.println(docComment+"\nsuccessfully verified.");
			}
		}
	}

	/**
	 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=51241"
	 */
	public void testBug51241() throws JavaScriptModelException {
		verifyComments("testBug51241");
	}

	/**
	 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=51363"
	 */
	public void testBug51363() throws JavaScriptModelException {
		sourceUnit = getCompilationUnit("Converter" , "src", "javadoc.testBug51363", "Test.js"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
		ASTNode result = runConversion(sourceUnit, false);
		final JavaScriptUnit unit = (JavaScriptUnit) result;
		assumeEquals(prefix+"Wrong number of problems", 0, unit.getProblems().length); //$NON-NLS-1$
		assumeEquals(prefix+"Wrong number of comments", 2, unit.getCommentList().size());
		// verify first comment
		Comment comment = (Comment) unit.getCommentList().get(0);
		assumeTrue(prefix+"Comment should be a line comment ", comment.isLineComment());
		String sourceStr = sourceUnit.getSource();
		int startPos = comment.getStartPosition()+comment.getLength();
		assumeEquals("Wrong length for line comment "+comment, "\\u000D\\u000A", sourceStr.substring(startPos, startPos+12));
		if (debug) System.out.println(comment+"\nsuccessfully verified.");
		// verify second comment
		comment = (Comment) unit.getCommentList().get(1);
		assumeTrue(prefix+"Comment should be a line comment", comment.isLineComment());
		sourceStr = sourceUnit.getSource();
		startPos = comment.getStartPosition()+comment.getLength();
		assumeEquals("Wrong length for line comment "+comment, "\\u000Dvoid", sourceStr.substring(startPos, startPos+10));
		if (debug) System.out.println(comment+"\nsuccessfully verified.");
//		verifyComments("testBug51363");
	}

	/**
	 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=51476"
	 */
	public void testBug51476() throws JavaScriptModelException {
		verifyComments("testBug51476");
	}

	/**
	 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=51478"
	 */
	public void testBug51478() throws JavaScriptModelException {
		verifyComments("testBug51478");
	}

	/**
	 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=51508"
	 */
	public void testBug51508() throws JavaScriptModelException {
		verifyComments("testBug51508");
	}

	/**
	 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=51650"
	 */
	public void testBug51650() throws JavaScriptModelException {
		verifyComments("testBug51650");
	}

	/**
	 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=51770"
	 */
	public void testBug51770() throws JavaScriptModelException {
		verifyComments("testBug51770");
	}

	/**
	 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=52908"
	 */
	public void testBug52908() throws JavaScriptModelException {
		verifyComments("testBug52908");
	}
	public void testBug52908a() throws JavaScriptModelException {
		verifyComments("testBug52908a");
	}
	public void testBug52908unicode() throws JavaScriptModelException {
		verifyComments("testBug52908unicode");
	}

	/**
	 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=53276"
	 */
	public void testBug53276() throws JavaScriptModelException {
		verifyComments("testBug53276");
	}

	/**
	 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=53075"
	 */
	public void testBug53075() throws JavaScriptModelException {
		IJavaScriptUnit unit = getCompilationUnit("Converter" , "src", "javadoc.testBug53075", "X.js"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
		boolean pb = packageBinding;
		packageBinding = false;
		JavaScriptUnit compilUnit = verifyComments(unit);
		if (docCommentSupport.equals(JavaScriptCore.ENABLED)) {
			Comment comment = (Comment) compilUnit.getCommentList().get(0);
			assumeTrue(prefix+"Comment should be a javadoc comment ", comment.isDocComment());
			JSdoc docComment = (JSdoc) comment;
			TagElement tagElement = (TagElement) docComment.tags().get(0);
			assumeEquals("Wrong tag type!", TagElement.TAG_LINK, tagElement.getTagName());
			tagElement = (TagElement) docComment.tags().get(1);
			assumeEquals("Wrong tag type!", TagElement.TAG_LINKPLAIN, tagElement.getTagName());
		}
		packageBinding = pb;
	}

	/**
	 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=53757"
	 */
	public void testBug53757() throws JavaScriptModelException {
		verifyComments("testBug53757");
	}

	/**
	 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=51600"
	 */
	public void testBug51600() throws JavaScriptModelException {
		verifyComments("testBug51600");
	}
	public void testBug51617() throws JavaScriptModelException {
		stopOnFailure = false;
		String [] unbound = { "e" };
		verifyComments("testBug51617");
		if (docCommentSupport.equals(JavaScriptCore.ENABLED)) {
			int size = unbound.length;
			for (int i=0, f=0; i<size; i++) {
				assertTrue("Invalid number of failures!", failures.size()>f);
				String failure = (String) failures.get(f);
				String expected = "Reference '"+unbound[i]+"' should be bound!";
				if (expected.equals(failure.substring(failure.indexOf(' ')+1))) {
					failures.remove(f);
				} else {
					f++;	// skip offending failure
					i--;	// stay on expected string
				}
			}
		}
		stopOnFailure = true;
	}
	public void testBug54424() throws JavaScriptModelException {
		stopOnFailure = false;
		String [] unbound = { "tho",
				"from",
				"A#getList(int,long,boolean)",
				"#getList(Object,java.util.AbstractList)",
				"from",
				"#getList(int from,long tho)",
				"to"
		};
		verifyComments("testBug54424");
		if (docCommentSupport.equals(JavaScriptCore.ENABLED)) {
			int size = unbound.length;
			for (int i=0, f=0; i<size; i++) {
				assertTrue("Invalid number of failures!", failures.size()>f);
				String failure = (String) failures.get(f);
				String expected = "Reference '"+unbound[i]+"' should be bound!";
				if (expected.equals(failure.substring(failure.indexOf(' ')+1))) {
					failures.remove(f);
				} else {
					f++;	// skip offending failure
					i--;	// stay on expected string
				}
			}
		}
		stopOnFailure = true;
	}

	/**
	 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=63044"
	 */
	public void testBug63044() throws JavaScriptModelException {
		verifyComments("testBug63044");
	}

	/**
	 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=51660"
	 */
	public void testBug51660() throws JavaScriptModelException {
		stopOnFailure = false;
		IJavaScriptUnit unit = getCompilationUnit("Converter" , "src", "javadoc.testBug51660", "Test.js"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
		JavaScriptUnit compilUnit = verifyComments(unit);
		if (docCommentSupport.equals(JavaScriptCore.ENABLED)) {
			String[] tagNames = {
				"@ejb",
				"@ejb",
				"@ejb",
				"@ejb",
				"@ejb",
				"@ejb",
				"@ejb(bean",
				"@ejb)bean",
				"@ejb",
				"@ejb+bean",
				"@ejb,bean",
				"@ejb-bean",
				"@ejb.bean",
				"@ejb/bean",
				"@ejb",
				"@ejb;bean",
				"@ejb",
				"@ejb=bean",
				"@ejb",
				"@ejb?bean",
				"@ejb@bean",
				"@ejb[bean",
				"@ejb\\bean",
				"@ejb]bean",
				"@ejb^bean",
				"@ejb`bean",
				"@ejb{bean",
				"@ejb|bean",
				"@ejb",
				"@ejb~bean",
				"@unknown"
			};
			String[] tagTexts = {
				"!bean test non-java id character '!' (val=33) in tag name",
				"\"bean test non-java id character '\"' (val=34) in tag name",
				"#bean test non-java id character '#' (val=35) in tag name",
				"%bean test non-java id character '%' (val=37) in tag name",
				"&bean test non-java id character '&' (val=38) in tag name",
				"'bean test non-java id character ''' (val=39) in tag name",
				" test non-java id character '(' (val=40) in tag name",
				" test non-java id character ')' (val=41) in tag name",
				"*bean test non-java id character '*' (val=42) in tag name",
				" test non-java id character '+' (val=43) in tag name",
				" test non-java id character ',' (val=44) in tag name",
				" test non-java id character '-' (val=45) in tag name",
				" test non-java id character '.' (val=46) in tag name",
				" test non-java id character '/' (val=47) in tag name",
				":bean test non-java id character ':' (val=58) in tag name",
				" test non-java id character ';' (val=59) in tag name",
				"<bean test non-java id character '<' (val=60) in tag name",
				" test non-java id character '=' (val=61) in tag name",
				">bean test non-java id character '>' (val=62) in tag name",
				" test non-java id character '?' (val=63) in tag name",
				" test non-java id character '@' (val=64) in tag name",
				" test non-java id character '[' (val=91) in tag name",
				" test non-java id character '\\' (val=92) in tag name",
				" test non-java id character ']' (val=93) in tag name",
				" test non-java id character '^' (val=94) in tag name",
				" test non-java id character '`' (val=96) in tag name",
				" test non-java id character '{' (val=123) in tag name",
				" test non-java id character '|' (val=124) in tag name",
				"}bean test non-java id character '}' (val=125) in tag name",
				" test non-java id character '~' (val=126) in tag name",
				" test java id"
			};
			Comment comment = (Comment) compilUnit.getCommentList().get(0);
			assumeTrue(prefix+"Comment should be a javadoc comment ", comment.isDocComment());
			JSdoc docComment = (JSdoc) comment;
			int size = docComment.tags().size();
			for (int i=0; i<size; i++) {
				TagElement tagElement = (TagElement) docComment.tags().get(i);
				assumeEquals("Wrong tag name for:"+tagElement, tagNames[i], tagElement.getTagName());
				assumeEquals("Wrong fragments size for :"+tagElement, 1, tagElement.fragments().size());
				ASTNode fragment = (ASTNode) tagElement.fragments().get(0);
				assumeEquals("Wrong fragments type for :"+tagElement, ASTNode.TEXT_ELEMENT, fragment.getNodeType());
				TextElement textElement = (TextElement) fragment;
				assumeEquals("Wrong text for tag!", tagTexts[i], textElement.getText());
			}
		}
		stopOnFailure = true;
	}

	/**
	 * Bug 65174: Spurious "Javadoc: Missing reference" error
	 * @see "http://bugs.eclipse.org/bugs/show_bug.cgi?id=65174"
	 */
	public void testBug65174() throws JavaScriptModelException {
		verifyComments("testBug65174");
	}

	/**
	 * Bug 65253: [Javadoc] @@tag is wrongly parsed as @tag
	 * @see "http://bugs.eclipse.org/bugs/show_bug.cgi?id=65253"
	 */
	public void testBug65253() throws JavaScriptModelException {
		verifyComments("testBug65253");
	}

	/**
	 * Bug 65288: Javadoc: tag gets mangled when javadoc closing on same line without whitespace
	 * @see "http://bugs.eclipse.org/bugs/show_bug.cgi?id=65288"
	 */
	public void testBug65288() throws JavaScriptModelException {
		verifyComments("testBug65288");
	}

	/**
	 * Bug 68017: Javadoc processing does not detect missing argument to @return
	 * @see "http://bugs.eclipse.org/bugs/show_bug.cgi?id=68017"
	 */
	public void testBug68017() throws JavaScriptModelException {
		verifyComments("testBug68017");
	}

	/**
	 * Bug 68025: Javadoc processing does not detect some wrong links
	 * @see "http://bugs.eclipse.org/bugs/show_bug.cgi?id=68025"
	 */
	public void testBug68025() throws JavaScriptModelException {
		verifyComments("testBug68025");
	}

	/**
	 * Bug 69272: [Javadoc] Invalid malformed reference (missing separator)
	 * @see "http://bugs.eclipse.org/bugs/show_bug.cgi?id=69272"
	 */
	public void testBug69272() throws JavaScriptModelException {
		verifyComments("testBug69272");
	}

	/**
	 * Bug 69275: [Javadoc] Invalid warning on @see link
	 * @see "http://bugs.eclipse.org/bugs/show_bug.cgi?id=69275"
	 */
	public void testBug69275() throws JavaScriptModelException {
		verifyComments("testBug69275");
	}

	/**
	 * Bug 69302: [Javadoc] Invalid reference warning inconsistent with javadoc tool
	 * @see "http://bugs.eclipse.org/bugs/show_bug.cgi?id=69302"
	 */
	public void testBug69302() throws JavaScriptModelException {
		verifyComments("testBug69302");
	}

	/**
	 * Bug 68726: [Javadoc] Target attribute in @see link triggers warning
	 * @see "http://bugs.eclipse.org/bugs/show_bug.cgi?id=68726"
	 */
	public void testBug68726() throws JavaScriptModelException {
		verifyComments("testBug68726");
	}

	/**
	 * Bug 70892: [1.5][Javadoc] Compiler should parse reference for inline tag @value
	 * @see "http://bugs.eclipse.org/bugs/show_bug.cgi?id=70892"
	 * @deprecated using deprecated code
	 */
	public void testBug70892_JLS2() throws JavaScriptModelException {
		int level = astLevel;
		astLevel = AST.JLS2;
		verifyComments("testBug70892");
		astLevel = level;
	}
	public void testBug70892_JLS3() throws JavaScriptModelException {
		int level = astLevel;
		astLevel = AST.JLS3;
		verifyComments("testBug70892");
		astLevel = level;
	}

	/**
	 * Bug 51911: [Javadoc] @see method w/out ()
	 * @see "http://bugs.eclipse.org/bugs/show_bug.cgi?id=51911"
	 */
	public void testBug51911() throws JavaScriptModelException {
		verifyComments("testBug51911");
	}

	/**
	 * Bug 73348: [Javadoc] Missing description for return tag is not always warned
	 * @see "http://bugs.eclipse.org/bugs/show_bug.cgi?id=73348"
	 */
	public void testBug73348() throws JavaScriptModelException {
		verifyComments("testBug73348");
	}

	/**
	 * Bug 77644: [dom] AST node extended positions may be wrong while moving
	 * @see "http://bugs.eclipse.org/bugs/show_bug.cgi?id=77644"
	 */
	public void testBug77644() throws JavaScriptModelException {
		verifyComments("testBug77644");
	}

	/**
	 * Bug 79809: [1.5][dom][javadoc] Need better support for type parameter Javadoc tags
	 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=79809"
	 */
	public void testBug79809() throws JavaScriptModelException {
		workingCopies = new IJavaScriptUnit[1];
		astLevel = AST.JLS3;
		workingCopies[0] = getWorkingCopy("/Converter/src/javadoc/b79809/Test.js",
			"package javadoc.b79809;\n" +
			"/**\n" + 
			" * @param <E>  Class type parameter\n" + 
			" * @see Object\n" + 
			" */\n" + 
			"public class Test<E> {\n" + 
			"	/**\n" + 
			"	 * @param t\n" + 
			"	 * @param <T> Method type parameter\n" + 
			"	 */\n" + 
			"	<T> void foo(T t) {}\n" + 
			"}\n");
		verifyWorkingCopiesComments();
	}
	public void testBug79809b() throws JavaScriptModelException {
		workingCopies = new IJavaScriptUnit[1];
		astLevel = AST.JLS3;
		workingCopies[0] = getWorkingCopy("/Converter/src/javadoc/b79809/Test.js",
			"package javadoc.b79809;\n" + 
			"\n" + 
			"/**\n" + 
			" * New tags for 5.0\n" + 
			" *  - literal: {@literal a<B>c}\n" + 
			" *  - code: {@code abc}\n" + 
			" *  - value: {@value System#out}\n" + 
			" */\n" + 
			"public class Test {\n" + 
			"\n" + 
			"}\n");
		verifyWorkingCopiesComments();
	}

	/**
	 * Bug 79904: [1.5][dom][javadoc] TagElement range not complete for type parameter tags
	 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=79904"
	 */
	public void testBug79904() throws JavaScriptModelException {
		workingCopies = new IJavaScriptUnit[1];
		astLevel = AST.JLS3;
		workingCopies[0] = getWorkingCopy("/Converter/src/javadoc/b79904/Test.js",
			"package javadoc.b79904;\n" +
			"/**\n" + 
			" * @param <E>\n" + 
			" * @see Object\n" + 
			" */\n" + 
			"public class Test<E> {\n" + 
			"	/**\n" + 
			"	 * @param t\n" + 
			"	 * @param <T>\n" + 
			"	 */\n" + 
			"	<T> void foo(T t) {}\n" + 
			"}\n");
		verifyWorkingCopiesComments();
	}

	/**
	 * Bug 80221: [1.5][dom][javadoc] Need better support for type parameter Javadoc tags
	 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=80221"
	 */
	public void testBug80221() throws JavaScriptModelException {
		workingCopies = new IJavaScriptUnit[1];
		astLevel = AST.JLS3;
		workingCopies[0] = getWorkingCopy("/Converter/src/javadoc/b80221/Test.js",
			"package javadoc.b80221;\n" +
			"public class Test {\n" + 
			"	/**\n" + 
			"	 * @see Object Unknown: ref is not resolved due to compile error...\n" + 
			"	 */\n" + 
			"	public foo() {\n" + 
			"		return 1;\n" + 
			"	}\n" + 
			"}\n"
		);
		verifyWorkingCopiesComments();
	}

	/**
	 * Bug 80257: [1.5][javadoc][dom] Type references in javadocs should have generic binding, not raw
	 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=80257"
	 */
	public void testBug80257() throws JavaScriptModelException {
		workingCopies = new IJavaScriptUnit[1];
		astLevel = AST.JLS3;
		workingCopies[0] = getWorkingCopy("/Converter15/src/javadoc/b80257/Test.js",
			"package javadoc.b80257;\n" + 
			"import java.util.*;\n" + 
			"public class Test {\n" + 
			"	/**\n" + 
			"	 * @see ArrayList\n" + 
			"	 * @return {@link java.util.List}\n" + 
			"	 */\n" + 
			"	List<String> getList() {\n" + 
			"		return new ArrayList<String>();\n" + 
			"	}\n" + 
			"}\n"
			);
		JavaScriptUnit compilUnit = verifyComments(workingCopies[0]);
		if (docCommentSupport.equals(JavaScriptCore.ENABLED)) {
			// Do not need to verify following statement as we know it's ok as verifyComments did not fail
			JSdoc docComment = (JSdoc) compilUnit.getCommentList().get(0); // get javadoc comment
			TagElement firstTag = (TagElement) docComment.tags().get(0); // get first tag
			TagElement secondTag = (TagElement) docComment.tags().get(1); // get second tag
			TagElement inlineTag = (TagElement) secondTag.fragments().get(1); // get inline tag
			// Get tag simple name reference in first tag
			assertEquals("Invalid number of fragments for tag element: "+firstTag, 1, firstTag.fragments().size());
			ASTNode node = (ASTNode) firstTag.fragments().get(0);
			assertEquals("Invalid kind of name reference for tag element: "+firstTag, ASTNode.SIMPLE_NAME, node.getNodeType());
			SimpleName seeRef = (SimpleName) node;
			// Verify binding for simple name
			IBinding binding = seeRef.resolveBinding();
			assertTrue("Wrong kind of binding", binding instanceof ITypeBinding);
			// Get inline tag simple name reference in second tag
			assertEquals("Invalid number of fragments for inline tag element: "+inlineTag, 1, inlineTag.fragments().size());
			node = (ASTNode) inlineTag.fragments().get(0);
			assertEquals("Invalid kind of name reference for tag element: "+inlineTag, ASTNode.QUALIFIED_NAME, node.getNodeType());
			QualifiedName linkRef = (QualifiedName) node;
			// Verify binding for qualified name
			binding = linkRef.resolveBinding();
			assertTrue("Wrong kind of binding", binding instanceof ITypeBinding);
		}
	}

	/**
	 * Bug 83804: [1.5][javadoc] Missing Javadoc node for package declaration
	 * @see "http://bugs.eclipse.org/bugs/show_bug.cgi?id=83804"
	 */
	public void testBug83804() throws CoreException, JavaScriptModelException {
		astLevel = AST.JLS3;
		workingCopies = new IJavaScriptUnit[2];
		workingCopies[0] = getCompilationUnit("Converter15", "src", "javadoc.b83804", "package-info.js");
		workingCopies[1] = getCompilationUnit("Converter15", "src", "javadoc.b83804", "Test.js");
		verifyWorkingCopiesComments();
	}
	public void testBug83804a() throws CoreException, JavaScriptModelException {
		astLevel = AST.JLS3;
		workingCopies = new IJavaScriptUnit[2];
		workingCopies[0] = getCompilationUnit("Converter15", "src", "javadoc.b83804a", "package-info.js");
		workingCopies[1] = getCompilationUnit("Converter15", "src", "javadoc.b83804a", "Test.js");
		verifyWorkingCopiesComments();
	}

	/**
	 * Bug 84049: [javadoc][dom] Extended ranges wrong for method name without return type
	 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=84049"
	 */
	public void testBug84049() throws JavaScriptModelException {
		workingCopies = new IJavaScriptUnit[1];
		astLevel = AST.JLS3;
		workingCopies[0] = getWorkingCopy("/Converter15/src/javadoc/b84049/Test.js",
			"package javadoc.b84049;\n" + 
			"public class Test {\n" + 
			"	/**\n" + 
			"	 * @see Object\n" + 
			"	 */\n" + 
			"	foo() {\n" + 
			"	}\n" + 
			"}\n"
			);
		JavaScriptUnit compilUnit = (JavaScriptUnit) runConversion(workingCopies[0], true);
		if (docCommentSupport.equals(JavaScriptCore.ENABLED)) {
			ASTNode node = getASTNode(compilUnit, 0, 0);
			assertEquals("Invalid type for node: "+node, ASTNode.FUNCTION_DECLARATION, node.getNodeType());
			FunctionDeclaration methodDeclaration = (FunctionDeclaration) node;
			JSdoc methodJavadoc = methodDeclaration.getJavadoc();
			assertNotNull("FunctionDeclaration have a javadoc comment", methodJavadoc);
			int javadocStart = methodJavadoc.getStartPosition();
			assertEquals("Method declaration should include javadoc comment", methodDeclaration.getStartPosition(), javadocStart);
			SimpleName methodName = methodDeclaration.getName();
			int nameStart = methodName.getStartPosition();
			assertTrue("Method simple name should not include javadoc comment", nameStart > javadocStart+methodJavadoc.getLength());
			int extendedStart = compilUnit.getExtendedStartPosition(methodName);
			assertEquals("Method simple name start position should not be extended!", nameStart, extendedStart);
			int extendedLength = compilUnit.getExtendedLength(methodName);
			assertEquals("Method simple name length should not be extended!", methodName.getLength(), extendedLength);
		}
	}

	/**
	 * Bug 87845: [1.5][javadoc][dom] Type references in javadocs should have generic binding, not raw
	 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=87845"
	 */
	public void testBug87845() throws JavaScriptModelException {
		workingCopies = new IJavaScriptUnit[1];
		astLevel = AST.JLS3;
		workingCopies[0] = getWorkingCopy("/Converter15/src/javadoc/b87845/Test.js",
			"package javadoc.b87845;\n" + 
			"public class Test {\n" + 
			"	public void foo(int a, int b) {} \n" + 
			"	public void foo(int a, int... args) {}\n" + 
			"	public void foo(String... args) {}\n" + 
			"	public void foo(Exception str, boolean... args) {}\n" + 
			"	/**\n" + 
			"	* @see Test#foo(int, int)\n" + 
			"	* @see Test#foo(int, int[])\n" + 
			"	* @see Test#foo(int, int...)\n" + 
			"	* @see Test#foo(String[])\n" + 
			"	* @see Test#foo(String...)\n" + 
			"	* @see Test#foo(Exception, boolean[])\n" + 
			"	* @see Test#foo(Exception, boolean...)\n" + 
			"	*/\n" + 
			"	public void valid() {}\n" + 
			"	/**\n" + 
			"	* @see Test#foo(int)\n" + 
			"	* @see Test#foo(int, int, int)\n" + 
			"	* @see Test#foo()\n" + 
			"	* @see Test#foo(String)\n" + 
			"	* @see Test#foo(String, String)\n" + 
			"	* @see Test#foo(Exception)\n" + 
			"	* @see Test#foo(Exception, boolean)\n" + 
			"	* @see Test#foo(Exception, boolean, boolean)\n" + 
			"	*/\n" + 
			"	public void invalid() {}\n" + 
			"}\n"
		);
		JavaScriptUnit compilUnit = verifyComments(workingCopies[0]);
		if (docCommentSupport.equals(JavaScriptCore.ENABLED)) {
			// Do not need to verify following statement as we know it's ok as verifyComments did not fail
			JSdoc docComment = (JSdoc) compilUnit.getCommentList().get(0); // get first javadoc comment
			// Verify last parameter for all methods reference in javadoc comment
			List tags = docComment.tags();
			int size = tags.size();
			for (int i=0; i<size; i++) {
				TagElement tag = (TagElement) docComment.tags().get(i);				
				assertEquals("Invalid number of fragment for see reference: "+tag, 1, tag.fragments().size());
				ASTNode node = (ASTNode) tag.fragments().get(0);
				assertEquals("Invalid kind of name reference for tag element: "+tag, ASTNode.FUNCTION_REF, node.getNodeType());
				FunctionRef methodRef = (FunctionRef) node;
				List parameters = methodRef.parameters();
				int paramSize = parameters.size();
				for (int j=0; j<paramSize; j++) {
					node = (ASTNode) parameters.get(j);
					assertEquals("Invalid kind of method parameter: "+node, ASTNode.FUNCTION_REF_PARAMETER, node.getNodeType());
					FunctionRefParameter parameter = (FunctionRefParameter) node;
					if (j==(paramSize-1)) {
						switch (i) {
							case 2:
							case 4:
							case 6:
								assertTrue("Method parameter \""+parameter+"\" should be varargs!", parameter.isVarargs());
								break;
							default:
								assertFalse("Method parameter \""+parameter+"\" should not be varargs!", parameter.isVarargs());
								break;
						}
					} else {
						assertFalse("Method parameter \""+parameter+"\" should not be varargs!", parameter.isVarargs());
					}
				}
			}
		}
	}

	/**
	 * Bug 93880: [1.5][javadoc] Source range of PackageDeclaration does not include Javadoc child
	 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=93880"
	 */
	public void testBug93880_15a() throws JavaScriptModelException {
		workingCopies = new IJavaScriptUnit[1];
		astLevel = AST.JLS3;
		workingCopies[0] = getWorkingCopy("/Converter15/src/javadoc/b93880/Test.js",
			"/**\n" + 
			" * Javadoc\n" + 
			" */\n" + 
			"package javadoc.b93880;\n" + 
			"public class Test {\n" + 
			"}\n"
		);
		JavaScriptUnit compilUnit = verifyComments(workingCopies[0]);
		if (docCommentSupport.equals(JavaScriptCore.ENABLED)) {
			// Get package declaration declaration and javadoc
			PackageDeclaration packDecl = compilUnit.getPackage();
			JSdoc docComment = (JSdoc) compilUnit.getCommentList().get(0); // Do not need to verify following statement as we know it's ok as verifyComments did not fail

			// Verify package declaration javadoc
			assertTrue("Javadoc should be set on package declaration", docComment == packDecl.getJavadoc());

			// Verify package declaration declaration source start
			assertEquals("Source range of PackageDeclaration should include Javadoc child", docComment.getStartPosition(), packDecl.getStartPosition());
		}
	}
	public void testBug93880_15b() throws JavaScriptModelException {
		workingCopies = new IJavaScriptUnit[1];
		astLevel = AST.JLS3;
		workingCopies[0] = getWorkingCopy("/Converter15/src/javadoc/b93880/package-info.js",
			"/**\n" + 
			" * Javadoc for all package\n" + 
			" */\n" + 
			"package javadoc.b93880;"
		);
		JavaScriptUnit compilUnit = verifyComments(workingCopies[0]);
		if (docCommentSupport.equals(JavaScriptCore.ENABLED)) {
			// Get package declaration declaration and javadoc
			PackageDeclaration packDecl = compilUnit.getPackage();
			JSdoc docComment = (JSdoc) compilUnit.getCommentList().get(0); // Do not need to verify following statement as we know it's ok as verifyComments did not fail

			// Verify package declaration javadoc
			assertTrue("Javadoc should be set on package declaration", docComment == packDecl.getJavadoc());

			// Verify package declaration declaration source start
			assertEquals("Source range of PackageDeclaration should include Javadoc child", docComment.getStartPosition(), packDecl.getStartPosition());
		}
	}
	public void testBug93880_15c() throws JavaScriptModelException {
		workingCopies = new IJavaScriptUnit[1];
		astLevel = AST.JLS3;
		workingCopies[0] = getWorkingCopy("/Converter15/src/javadoc/b93880/package-info.js",
			"/**\n" + 
			" * Javadoc for all package\n" + 
			" */\n" + 
			"private package javadoc.b93880;"
		);
		JavaScriptUnit compilUnit = verifyComments(workingCopies[0]);
		if (docCommentSupport.equals(JavaScriptCore.ENABLED)) {
			// Get package declaration declaration and javadoc
			PackageDeclaration packDecl = compilUnit.getPackage();
			JSdoc docComment = (JSdoc) compilUnit.getCommentList().get(0); // Do not need to verify following statement as we know it's ok as verifyComments did not fail

			// Verify package declaration javadoc
			assertTrue("Javadoc should be set on package declaration", docComment == packDecl.getJavadoc());

			// Verify package declaration declaration source start
			assertEquals("Source range of PackageDeclaration should include Javadoc child", docComment.getStartPosition(), packDecl.getStartPosition());
		}
	}
	public void testBug93880_15d() throws JavaScriptModelException {
		workingCopies = new IJavaScriptUnit[1];
		astLevel = AST.JLS3;
		workingCopies[0] = getWorkingCopy("/Converter15/src/javadoc/b93880/package-info.js",
			"/**\n" + 
			" * Javadoc for all package\n" + 
			" */\n" + 
			"@Deprecated\n" + 
			"package javadoc.b93880;"
		);
		JavaScriptUnit compilUnit = verifyComments(workingCopies[0]);
		if (docCommentSupport.equals(JavaScriptCore.ENABLED)) {
			// Get package declaration declaration and javadoc
			PackageDeclaration packDecl = compilUnit.getPackage();
			assertNotNull("Compilation unit should have a package declaration", packDecl);
			JSdoc docComment = (JSdoc) compilUnit.getCommentList().get(0); // Do not need to verify following statement as we know it's ok as verifyComments did not fail

			// Verify package declaration javadoc
			assertTrue("Javadoc should be set on package declaration", docComment == packDecl.getJavadoc());

			// Verify package declaration declaration source start
			assertEquals("Source range of PackageDeclaration should include Javadoc child", docComment.getStartPosition(), packDecl.getStartPosition());
		}
	}
	public void testBug93880_15e() throws JavaScriptModelException {
		workingCopies = new IJavaScriptUnit[1];
		astLevel = AST.JLS3;
		workingCopies[0] = getWorkingCopy("/Converter15/src/javadoc/b93880/package-info.js",
			"/* (non-javadoc)\n" + 
			" * No comment\n" + 
			" */\n" + 
			"package javadoc.b93880;"
		);
		JavaScriptUnit compilUnit = verifyComments(workingCopies[0]);
		if (docCommentSupport.equals(JavaScriptCore.ENABLED)) {
			// Get package declaration declaration and javadoc
			PackageDeclaration packDecl = compilUnit.getPackage();
			List unitComments = compilUnit.getCommentList();
			assertEquals("Wrong number of comments", 1, unitComments.size());
			Comment comment = (Comment) unitComments.get(0);

			// Verify package declaration javadoc
			assertNull("Package declaration should not have any javadoc", packDecl.getJavadoc());

			// Verify package declaration declaration source start
			assertTrue("Source range of PackageDeclaration should NOT include Javadoc child", packDecl.getStartPosition() > comment.getStartPosition()+comment.getLength());
		}
	}
	public void testBug93880_14a() throws JavaScriptModelException {
		workingCopies = new IJavaScriptUnit[1];
		astLevel = AST.JLS3;
		workingCopies[0] = getWorkingCopy("/Converter15/src/javadoc/b93880/Test.js",
			"/**\n" + 
			" * Javadoc\n" + 
			" */\n" + 
			"package javadoc.b93880;\n" + 
			"public class Test {\n" + 
			"}\n"
		);
		JavaScriptUnit compilUnit = verifyComments(workingCopies[0]);
		if (docCommentSupport.equals(JavaScriptCore.ENABLED)) {
			// Get package declaration declaration and javadoc
			PackageDeclaration packDecl = compilUnit.getPackage();
			JSdoc docComment = (JSdoc) compilUnit.getCommentList().get(0); // Do not need to verify following statement as we know it's ok as verifyComments did not fail

			// Verify package declaration declaration source start
			assertEquals("Source range of PackageDeclaration should include Javadoc child", docComment.getStartPosition(), packDecl.getStartPosition());
		}
	}
	public void testBug93880_14b() throws JavaScriptModelException {
		workingCopies = new IJavaScriptUnit[1];
		astLevel = AST.JLS3;
		workingCopies[0] = getWorkingCopy("/Converter15/src/javadoc/b93880/package-info.js",
			"/**\n" + 
			" * Javadoc for all package\n" + 
			" */\n" + 
			"package javadoc.b93880;"
		);
		JavaScriptUnit compilUnit = verifyComments(workingCopies[0]);
		if (docCommentSupport.equals(JavaScriptCore.ENABLED)) {
			// Get package declaration declaration and javadoc
			PackageDeclaration packDecl = compilUnit.getPackage();
			JSdoc docComment = (JSdoc) compilUnit.getCommentList().get(0); // Do not need to verify following statement as we know it's ok as verifyComments did not fail

			// Verify package declaration declaration source start
			assertEquals("Source range of PackageDeclaration should include Javadoc child", docComment.getStartPosition(), packDecl.getStartPosition());
		}
	}
	public void testBug93880_14c() throws JavaScriptModelException {
		workingCopies = new IJavaScriptUnit[1];
		astLevel = AST.JLS3;
		workingCopies[0] = getWorkingCopy("/Converter15/src/javadoc/b93880/package-info.js",
			"/**\n" + 
			" * Javadoc for all package\n" + 
			" */\n" + 
			"private package javadoc.b93880;"
		);
		JavaScriptUnit compilUnit = verifyComments(workingCopies[0]);
		if (docCommentSupport.equals(JavaScriptCore.ENABLED)) {
			// Get package declaration declaration and javadoc
			PackageDeclaration packDecl = compilUnit.getPackage();
			JSdoc docComment = (JSdoc) compilUnit.getCommentList().get(0); // Do not need to verify following statement as we know it's ok as verifyComments did not fail

			// Verify package declaration declaration source start
			assertEquals("Source range of PackageDeclaration should include Javadoc child", docComment.getStartPosition(), packDecl.getStartPosition());
		}
	}
	public void testBug93880_14d() throws JavaScriptModelException {
		workingCopies = new IJavaScriptUnit[1];
		astLevel = AST.JLS3;
		workingCopies[0] = getWorkingCopy("/Converter15/src/javadoc/b93880/package-info.js",
			"/**\n" + 
			" * Javadoc for all package\n" + 
			" */\n" + 
			"@Deprecated\n" + 
			"package javadoc.b93880;"
		);
		JavaScriptUnit compilUnit = verifyComments(workingCopies[0]);
		if (docCommentSupport.equals(JavaScriptCore.ENABLED)) {
			// Get package declaration declaration and javadoc
			PackageDeclaration packDecl = compilUnit.getPackage();
			assertNotNull("Compilation unit should have a package declaration", packDecl);
			JSdoc docComment = (JSdoc) compilUnit.getCommentList().get(0); // Do not need to verify following statement as we know it's ok as verifyComments did not fail

			// Verify package declaration declaration source start
			assertEquals("Source range of PackageDeclaration should include Javadoc child", docComment.getStartPosition(), packDecl.getStartPosition());
		}
	}
	public void testBug93880_14e() throws JavaScriptModelException {
		workingCopies = new IJavaScriptUnit[1];
		astLevel = AST.JLS3;
		workingCopies[0] = getWorkingCopy("/Converter15/src/javadoc/b93880/package-info.js",
			"/* (non-javadoc)\n" + 
			" * No comment\n" + 
			" */\n" + 
			"package javadoc.b93880;"
		);
		JavaScriptUnit compilUnit = verifyComments(workingCopies[0]);
		if (docCommentSupport.equals(JavaScriptCore.ENABLED)) {
			// Get package declaration declaration and javadoc
			PackageDeclaration packDecl = compilUnit.getPackage();
			List unitComments = compilUnit.getCommentList();
			assertEquals("Wrong number of comments", 1, unitComments.size());
			Comment comment = (Comment) unitComments.get(0);

			// Verify package declaration declaration source start
			assertTrue("Source range of PackageDeclaration should NOT not include Javadoc child", packDecl.getStartPosition() > comment.getStartPosition()+comment.getLength());
		}
	}


	/**
	 * Bug 99507: [javadoc] Infinit loop in DocCommentParser
	 * @see "http://bugs.eclipse.org/bugs/show_bug.cgi?id=99507"
	 */
	public void testBug99507() throws JavaScriptModelException {
		workingCopies = new IJavaScriptUnit[1];
		workingCopies[0] = getWorkingCopy("/Converter15/src/javadoc/b99507/X.js",
			"package javadoc.b99507;\n" + 
			"public class X {\n" + 
			"}\n" +
			"/** @param test*/" 
		);
		verifyComments(workingCopies[0]);
	}
	public void testBug99507b() throws JavaScriptModelException {
        String source = "/**\n@param country*/";
		ASTParser parser = ASTParser.newParser(AST.JLS3);
		parser.setKind(ASTParser.K_COMPILATION_UNIT);
		parser.setSource(source.toCharArray());
		parser.createAST(null);
	}

	/**
	 * Bug 100041: [javadoc] Infinit loop in DocCommentParser
	 * @see "http://bugs.eclipse.org/bugs/show_bug.cgi?id=100041"
	 */
	public void testBug100041() throws JavaScriptModelException {
		workingCopies = new IJavaScriptUnit[1];
		workingCopies[0] = getWorkingCopy("/Converter15/src/javadoc/b100041/X.js",
			"package javadoc.b100041;\n" + 
			"class X {\n" +
			"	static Object object;\n" +
			"	static void foo() {\n" +
			"		/**\n" +
			"		 * javadoc comment.\n" +
			"		 */\n" +
			"		if (object instanceof String) {\n" +
			"			final String clr = null;\n" +
			"		}\n" +
			"	}\n" +
			"}"
		);
		JavaScriptUnit compilUnit = verifyComments(workingCopies[0]);
		if (docCommentSupport.equals(JavaScriptCore.ENABLED)) {
			// Get comment
			List unitComments = compilUnit.getCommentList();
			assertEquals("Wrong number of comments", 1, unitComments.size());
			Comment comment = (Comment) unitComments.get(0);
			int commentStart = comment.getStartPosition();
			int commentEnd = commentStart+comment.getLength();

			// Get local variable declaration
			ASTNode node = getASTNode(compilUnit, 0, 1, 0);
			assertEquals("Expected if statement for node: "+node, ASTNode.IF_STATEMENT, node.getNodeType());
			IfStatement ifStatement = (IfStatement) node;
			assertTrue("Invalid start position for IfStatement: "+ifStatement, ifStatement.getStartPosition() > commentEnd);
			Statement statement  = ifStatement.getThenStatement();
			assertEquals("Expected block for node: "+statement, ASTNode.BLOCK, statement.getNodeType());
			Block block = (Block) statement;
			assertTrue("Invalid start position for Block: "+block, block.getStartPosition() > commentEnd);
			List statements = block.statements();
			assertEquals("Invalid number of statements for block: "+block, 1, statements.size());
			statement = (Statement) statements.get(0);
			assertEquals("Expected variable declaration statement for node: "+statement, ASTNode.VARIABLE_DECLARATION_STATEMENT, statement.getNodeType());
			VariableDeclarationStatement varDecl = (VariableDeclarationStatement) statement;
			assertTrue("Invalid start position for : VariableDeclarationStatement"+varDecl, varDecl.getStartPosition() > commentEnd);
		}
	}
	public void testBug100041b() throws JavaScriptModelException {
		workingCopies = new IJavaScriptUnit[1];
		workingCopies[0] = getWorkingCopy("/Converter15/src/javadoc/b100041/X.js",
			"package javadoc.b100041;\n" + 
			"class X {\n" +
			"	static Object object;\n" +
			"	static void foo() {\n" +
			"		/**\n" +
			"		 * javadoc comment.\n" +
			"		 */\n" +
			"		if (object instanceof String)\n" +
			"			return;\n" +
			"	}\n" +
			"}"
		);
		JavaScriptUnit compilUnit = verifyComments(workingCopies[0]);
		if (docCommentSupport.equals(JavaScriptCore.ENABLED)) {
			// Get comment
			List unitComments = compilUnit.getCommentList();
			assertEquals("Wrong number of comments", 1, unitComments.size());
			Comment comment = (Comment) unitComments.get(0);
			int commentStart = comment.getStartPosition();
			int commentEnd = commentStart+comment.getLength();

			// Get local variable declaration
			ASTNode node = getASTNode(compilUnit, 0, 1, 0);
			assertEquals("Expected if statement for node: "+node, ASTNode.IF_STATEMENT, node.getNodeType());
			IfStatement ifStatement = (IfStatement) node;
			assertTrue("Invalid start position for IfStatement: "+ifStatement, ifStatement.getStartPosition() > commentEnd);
			Statement statement  = ifStatement.getThenStatement();
			assertEquals("Expected block for node: "+statement, ASTNode.RETURN_STATEMENT, statement.getNodeType());
			ReturnStatement returnStatement = (ReturnStatement) statement;
			assertTrue("Invalid start position for Block: "+returnStatement, returnStatement.getStartPosition() > commentEnd);
		}
	}
	public void testBug100041c() throws JavaScriptModelException {
		workingCopies = new IJavaScriptUnit[1];
		workingCopies[0] = getWorkingCopy("/Converter15/src/javadoc/b100041/Z.js",
			"package javadoc.b100041;\n" + 
			"public class Z {\n" + 
			"	/** C1 */\n" + 
			"	class Z1 {}\n" + 
			"	/** C2 */\n" + 
			"	Z1 z1;\n" + 
			"	/** C3 */\n" + 
			"	public static void foo(Object object) {\n" + 
			"		/** C4 */\n" + 
			"		class ZZ {\n" + 
			"			/** C5 */\n" + 
			"			ZZ zz;\n" + 
			"			/** C6 */\n" + 
			"			public void bar() {}\n" + 
			"		}\n" + 
			"	}\n" + 
			"}\n"
		);
		JavaScriptUnit compilUnit = verifyComments(workingCopies[0]);
		if (docCommentSupport.equals(JavaScriptCore.ENABLED)) {
			// Get comments
			List unitComments = compilUnit.getCommentList();
			int size = unitComments.size();
			assertEquals("Wrong number of comments", 6, size);
			JSdoc[] javadocs = new JSdoc[size];
			Iterator iterator = unitComments.iterator();
			for (int i=0; i<size; i++) {
				Comment comment = (Comment) iterator.next();
				assertEquals("Expect javadoc for comment: "+comment, ASTNode.JSDOC, comment.getNodeType());
				javadocs[i] = (JSdoc) comment;
			}

			// Verify member type declaration start
			ASTNode node = getASTNode(compilUnit, 0, 0);
			assertEquals("Expected type declaration for node: "+node, ASTNode.TYPE_DECLARATION, node.getNodeType());
			TypeDeclaration typeDeclaration = (TypeDeclaration) node;
			int javadocStart = javadocs[0].getStartPosition();
			assertEquals("Invalid start position for TypeDeclaration: "+typeDeclaration, typeDeclaration.getStartPosition(), javadocStart);

			// Verify field declaration start
			node = getASTNode(compilUnit, 0, 1);
			assertEquals("Expected field declaration for node: "+node, ASTNode.FIELD_DECLARATION, node.getNodeType());
			FieldDeclaration fieldDeclaration = (FieldDeclaration) node;
			javadocStart = javadocs[1].getStartPosition();
			assertEquals("Invalid start position for FieldDeclaration: "+fieldDeclaration, fieldDeclaration.getStartPosition(), javadocStart);

			// Verify method declaration start
			node = getASTNode(compilUnit, 0, 2);
			assertEquals("Expected method declaration for node: "+node, ASTNode.FUNCTION_DECLARATION, node.getNodeType());
			FunctionDeclaration methodDeclaration = (FunctionDeclaration) node;
			javadocStart = javadocs[2].getStartPosition();
			assertEquals("Invalid start position for FunctionDeclaration: "+methodDeclaration, methodDeclaration.getStartPosition(), javadocStart);

			// Verify local type declaration start
			node = getASTNode(compilUnit, 0, 2, 0);
			assertEquals("Expected type declaration for node: "+node, ASTNode.TYPE_DECLARATION_STATEMENT, node.getNodeType());
			typeDeclaration = (TypeDeclaration) ((TypeDeclarationStatement) node).getDeclaration();
			javadocStart = javadocs[3].getStartPosition();
			assertEquals("Invalid start position for TypeDeclaration: "+typeDeclaration, typeDeclaration.getStartPosition(), javadocStart);

			// Verify field declaration start
			List bodyDeclarations = typeDeclaration.bodyDeclarations();
			node = (ASTNode) bodyDeclarations.get(0);
			assertEquals("Expected field declaration for node: "+node, ASTNode.FIELD_DECLARATION, node.getNodeType());
			fieldDeclaration = (FieldDeclaration) node;
			javadocStart = javadocs[4].getStartPosition();
			assertEquals("Invalid start position for FieldDeclaration: "+fieldDeclaration, fieldDeclaration.getStartPosition(), javadocStart);

			// Verify method declaration start
			node = (ASTNode) bodyDeclarations.get(1);
			assertEquals("Expected method declaration for node: "+node, ASTNode.FUNCTION_DECLARATION, node.getNodeType());
			methodDeclaration = (FunctionDeclaration) node;
			javadocStart = javadocs[5].getStartPosition();
			assertEquals("Invalid start position for FunctionDeclaration: "+methodDeclaration, methodDeclaration.getStartPosition(), javadocStart);
		}
	}

	/**
	 * @bug 103304: [Javadoc] Wrong reference proposal for inner classes.
	 * @see "http://bugs.eclipse.org/bugs/show_bug.cgi?id=103304"
	 */
	public void testBug103304() throws JavaScriptModelException {
		this.packageBinding = false; // do NOT verify that qualification only can be package name
		workingCopies = new IJavaScriptUnit[1];
		workingCopies[0] = getWorkingCopy("/Converter15/src/javadoc/b103304/Test.js",
			"package javadoc.b103304;\n" + 
			"interface IAFAState {\n" + 
			"    public class ValidationException extends Exception {\n" + 
			"        public ValidationException(String variableName, IAFAState subformula) {\n" + 
			"            super(\"Variable \'\"+variableName+\"\' may be unbound in \'\"+subformula+\"\'\");\n" + 
			"        }\n" + 
			"    }\n" + 
			"}\n" +
			"public class Test {\n" + 
			"	/**\n" + 
			"	 * @see IAFAState.ValidationException#IAFAState.ValidationException(String, IAFAState)\n" + 
			"	 */\n" + 
			"	IAFAState.ValidationException valid;\n" + 
			"}\n"
		);
		JavaScriptUnit compilUnit = (JavaScriptUnit) runConversion(workingCopies[0], true);
		verifyWorkingCopiesComments();
		if (docCommentSupport.equals(JavaScriptCore.ENABLED)) {
			// Verify comment type
			Iterator unitComments = compilUnit.getCommentList().iterator();
			while (unitComments.hasNext()) {
				Comment comment = (Comment) unitComments.next();
				assertEquals("Comment should be javadoc", comment.getNodeType(), ASTNode.JSDOC);
				JSdoc javadoc = (JSdoc) comment;

				// Verify that there's always a method reference in tags
				List tags = javadoc.tags();
				int size = tags.size();
				for (int i=0; i<size; i++) {
					TagElement tag = (TagElement) javadoc.tags().get(i);				
					assertEquals("Invalid number of fragment for see reference: "+tag, 1, tag.fragments().size());
					ASTNode node = (ASTNode) tag.fragments().get(0);
					assertEquals("Invalid kind of name reference for tag element: "+tag, ASTNode.FUNCTION_REF, node.getNodeType());
				}
			}
		}
	}

	/**
	 * Bug 106581: [javadoc] null type binding for parameter in javadoc
	 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=106581"
	 */
	public void testBug106581() throws JavaScriptModelException {
		workingCopies = new IJavaScriptUnit[1];
		astLevel = AST.JLS3;
		workingCopies[0] = getWorkingCopy("/Converter15/src/javadoc/b106581/A.js",
			"package javadoc.b106581;\n" + 
			"public class A {\n" + 
			"    /**\n" + 
			"     * @param x\n" + 
			"     */ \n" + 
			"     public void foo(int x) {},\n" + 
			"}\n"
		);
		JavaScriptUnit compilUnit = verifyComments(workingCopies[0]);
		if (docCommentSupport.equals(JavaScriptCore.ENABLED)) {
			// Get comment
			List unitComments = compilUnit.getCommentList();
			assertEquals("Wrong number of comments", 1, unitComments.size());
			Comment comment = (Comment) unitComments.get(0);
			assertEquals("Comment should be javadoc", comment.getNodeType(), ASTNode.JSDOC);

			// Get local variable declaration
			JSdoc docComment = (JSdoc) comment;
			TagElement tag = (TagElement) docComment.tags().get(0);
			assertEquals("Invalid number of fragment for tag: "+tag, 1, tag.fragments().size());
			ASTNode node = (ASTNode) tag.fragments().get(0);
			assertEquals("Invalid kind of name reference for tag element: "+tag, ASTNode.SIMPLE_NAME, node.getNodeType());
			SimpleName simpleName = (SimpleName) node;
			assertNotNull("We should have a type binding for simple name: "+simpleName, simpleName.resolveTypeBinding());
		}
	}

	/**
	 * Bug 108622: [javadoc][dom] ASTNode not including javadoc
	 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=108622"
	 */
	public void testBug108622() throws JavaScriptModelException {
		workingCopies = new IJavaScriptUnit[1];
		astLevel = AST.JLS3;
		workingCopies[0] = getWorkingCopy("/Converter15/src/javadoc/b108622/Test.js",
			"package javadoc.b108622;\n" + 
			"/**\n" + 
			" * \n" + 
			" */\n" + 
			"public abstract class Test {\n" + 
			"\n" + 
			"	/**\n" + 
			"	 * \n" + 
			"	 */\n" + 
			"	public abstract Zork getFoo();\n" + 
			"\n" + 
			"	/**\n" + 
			"	 * \n" + 
			"	 */\n" + 
			"	public abstract void setFoo(Zork dept);\n" + 
			"\n" + 
			"}"
			);
		JavaScriptUnit compilUnit = (JavaScriptUnit) runConversion(workingCopies[0], true);
		if (docCommentSupport.equals(JavaScriptCore.ENABLED)) {
			// Verify first method
			ASTNode node = getASTNode(compilUnit, 0, 0);
			assertEquals("Invalid type for node: "+node, ASTNode.FUNCTION_DECLARATION, node.getNodeType());
			FunctionDeclaration methodDeclaration = (FunctionDeclaration) node;
			assertEquals("Invalid method name", "getFoo", methodDeclaration.getName().toString());
			JSdoc methodJavadoc = methodDeclaration.getJavadoc();
			assertNotNull("FunctionDeclaration have a javadoc comment", methodJavadoc);
			int javadocStart = methodJavadoc.getStartPosition();
			assertEquals("Method declaration should include javadoc comment", methodDeclaration.getStartPosition(), javadocStart);
			// Verify second method
			node = getASTNode(compilUnit, 0, 1);
			assertEquals("Invalid type for node: "+node, ASTNode.FUNCTION_DECLARATION, node.getNodeType());
			methodDeclaration = (FunctionDeclaration) node;
			assertEquals("Invalid method name", "setFoo", methodDeclaration.getName().toString());
			methodJavadoc = methodDeclaration.getJavadoc();
			assertNotNull("FunctionDeclaration have a javadoc comment", methodJavadoc);
			javadocStart = methodJavadoc.getStartPosition();
			assertEquals("Method declaration should include javadoc comment", methodDeclaration.getStartPosition(), javadocStart);
		}
	}

	/**
	 * Bug 113108: [API][comments] JavaScriptUnit.getNodeComments(ASTNode)
	 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=113108"
	 */
	public void testBug113108a() throws JavaScriptModelException {
		workingCopies = new IJavaScriptUnit[1];
		astLevel = AST.JLS3;
		workingCopies[0] = getWorkingCopy("/Converter15/src/javadoc/b113108/Test.js",
			"package javadoc.b113108;\n" + 
			"/** C0 */\n" +
			"public class Test {\n" + 
			"	/* C1 */\n" + 
			"	/** C2 */\n" + 
			"	// C3\n" + 
			"	public void foo() {\n" + 
			"		/* C4 */\n" + 
			"	}\n" + 
			"	/* C5 */\n" + 
			"	/** C6 */\n" + 
			"	// C7\n" + 
			"}"
			);
		JavaScriptUnit compilUnit = (JavaScriptUnit) runConversion(workingCopies[0], true);
		verifyWorkingCopiesComments();
		if (docCommentSupport.equals(JavaScriptCore.ENABLED)) {
			// Verify  method javadoc
			ASTNode node = getASTNode(compilUnit, 0, 0);
			assertEquals("Invalid type for node: "+node, ASTNode.FUNCTION_DECLARATION, node.getNodeType());
			FunctionDeclaration methodDeclaration = (FunctionDeclaration) node;
			assertEquals("Invalid method name", "foo", methodDeclaration.getName().toString());
			JSdoc methodJavadoc = methodDeclaration.getJavadoc();
			assertNotNull("FunctionDeclaration have a javadoc comment", methodJavadoc);
			int javadocStart = methodJavadoc.getStartPosition();
			assertEquals("Method declaration should include javadoc comment", methodDeclaration.getStartPosition(), javadocStart);
			// Verify method first leading and last trailing comment
			int index = compilUnit.firstLeadingCommentIndex(methodDeclaration);
			assertEquals("Invalid first leading comment for "+methodDeclaration, 1, index);
			index = compilUnit.lastTrailingCommentIndex(methodDeclaration);
			assertEquals("Invalid last trailing comment for "+methodDeclaration, 7, index);
		}
	}
	public void testBug113108b() throws JavaScriptModelException {
		workingCopies = new IJavaScriptUnit[1];
		astLevel = AST.JLS3;
		workingCopies[0] = getWorkingCopy("/Converter15/src/javadoc/b113108/Test.js",
			"package javadoc.b113108;\n" + 
			"/** C0 */\n" +
			"public class Test {\n" + 
			"	/** C1 */\n" + 
			"	// C2\n" + 
			"	/* C3 */\n" + 
			"	public void foo() {\n" + 
			"		// C4\n" + 
			"	}\n" + 
			"	/** C5 */\n" + 
			"	/// C6\n" + 
			"	/* C7 */\n" + 
			"}"
			);
		JavaScriptUnit compilUnit = (JavaScriptUnit) runConversion(workingCopies[0], true);
		verifyWorkingCopiesComments();
		if (docCommentSupport.equals(JavaScriptCore.ENABLED)) {
			// Verify  method javadoc
			ASTNode node = getASTNode(compilUnit, 0, 0);
			assertEquals("Invalid type for node: "+node, ASTNode.FUNCTION_DECLARATION, node.getNodeType());
			FunctionDeclaration methodDeclaration = (FunctionDeclaration) node;
			assertEquals("Invalid method name", "foo", methodDeclaration.getName().toString());
			JSdoc methodJavadoc = methodDeclaration.getJavadoc();
			assertNotNull("FunctionDeclaration have a javadoc comment", methodJavadoc);
			int javadocStart = methodJavadoc.getStartPosition();
			assertEquals("Method declaration should include javadoc comment", methodDeclaration.getStartPosition(), javadocStart);
			// Verify method first leading and last trailing comment
			int index = compilUnit.firstLeadingCommentIndex(methodDeclaration);
			assertEquals("Invalid first leading comment for "+methodDeclaration, 1, index);
			index = compilUnit.lastTrailingCommentIndex(methodDeclaration);
			assertEquals("Invalid last trailing comment for "+methodDeclaration, 7, index);
		}
	}
	public void testBug113108c() throws JavaScriptModelException {
		workingCopies = new IJavaScriptUnit[1];
		astLevel = AST.JLS3;
		workingCopies[0] = getWorkingCopy("/Converter15/src/javadoc/b113108/Test.js",
			"package javadoc.b113108;\n" + 
			"/** C0 */\n" +
			"public class Test {\n" + 
			"	// C1\n" + 
			"	/* C2 */\n" + 
			"	/** C3 */\n" + 
			"	public void foo() {\n" + 
			"		/** C4 */\n" + 
			"	}\n" + 
			"	// C5\n" + 
			"	/* C6 */\n" + 
			"	/** C7 */\n" + 
			"}"
			);
		JavaScriptUnit compilUnit = (JavaScriptUnit) runConversion(workingCopies[0], true);
		verifyWorkingCopiesComments();
		if (docCommentSupport.equals(JavaScriptCore.ENABLED)) {
			// Verify  method javadoc
			ASTNode node = getASTNode(compilUnit, 0, 0);
			assertEquals("Invalid type for node: "+node, ASTNode.FUNCTION_DECLARATION, node.getNodeType());
			FunctionDeclaration methodDeclaration = (FunctionDeclaration) node;
			assertEquals("Invalid method name", "foo", methodDeclaration.getName().toString());
			JSdoc methodJavadoc = methodDeclaration.getJavadoc();
			assertNotNull("FunctionDeclaration have a javadoc comment", methodJavadoc);
			int javadocStart = methodJavadoc.getStartPosition();
			assertEquals("Method declaration should include javadoc comment", methodDeclaration.getStartPosition(), javadocStart);
			// Verify method first leading and last trailing comment
			int index = compilUnit.firstLeadingCommentIndex(methodDeclaration);
			assertEquals("Invalid first leading comment for "+methodDeclaration, 1, index);
			index = compilUnit.lastTrailingCommentIndex(methodDeclaration);
			assertEquals("Invalid last trailing comment for "+methodDeclaration, 7, index);
		}
	}

	/**
	 * @bug 125676: [javadoc] @category should not read beyond end of line
	 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=125676"
	 */
	public void testBug125676() throws JavaScriptModelException {
		workingCopies = new IJavaScriptUnit[3];
		astLevel = AST.JLS3;
		workingCopies[0] = getWorkingCopy("/Converter15/src/javadoc/b125676/A.js",
			"package javadoc.b125676;\n" + 
			"public class A {\n" + 
			"        /**\n" + 
			"         * @category \n" + 
			"         * When searching for field matches, it will exclusively find read accesses, as\n" + 
			"         * opposed to write accesses. Note that some expressions are considered both\n" + 
			"         * as field read/write accesses: for example, x++; x+= 1;\n" + 
			"         * \n" + 
			"         * @since 2.0\n" + 
			"         */\n" + 
			"        int READ_ACCESSES = 4;\n" + 
			"}\n"
		);
		workingCopies[1] = getWorkingCopy("/Converter15/src/javadoc/b125676/B.js",
			"package javadoc.b125676;\n" + 
			"public class B {\n" + 
			"        /**\n" + 
			"         * @category test\n" + 
			"         */\n" + 
			"        int field1;\n" + 
			"        /**\n" + 
			"         * @category     test\n" + 
			"         */\n" + 
			"        int field2;\n" + 
			"        /**\n" + 
			"         * @category test    \n" + 
			"         */\n" + 
			"        int field3;\n" + 
			"        /**\n" + 
			"         * @category    test    \n" + 
			"         */\n" + 
			"        int field4;\n" + 
			"        /** @category test */\n" + 
			"        int field5;\n" + 
			"\n" + 
			"}\n"
		);
		workingCopies[2] = getWorkingCopy("/Converter15/src/javadoc/b125676/C.js",
			"package javadoc.b125676;\n" + 
			"public class C { \n" + 
			"        /**\n" + 
			"         * @category test mutli ids\n" + 
			"         */\n" + 
			"        int field1;\n" + 
			"        /**\n" + 
			"         * @category    test    mutli    ids   \n" + 
			"         */\n" + 
			"        int field2;\n" + 
			"        /** @category    test    mutli    ids*/\n" + 
			"        int field3;\n" + 
			"}\n"
		);
		verifyWorkingCopiesComments();
	}

	/**
	 * @bug 125903: [javadoc] Treat whitespace in javadoc tags as invalid tags
	 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=125903"
	 */
	public void testBug125903() throws JavaScriptModelException {
		workingCopies = new IJavaScriptUnit[1];
		astLevel = AST.JLS3;
		workingCopies[0] = getWorkingCopy("/Converter15/src/javadoc/b125903/Test.js",
			"package javadoc.b125903;\n" + 
			"/**\n" + 
			" * {@ link java.lang.String}\n" + 
			" * @ since 2.1\n" + 
			" */\n" + 
			"public class Test {\n" + 
			"\n" + 
			"}\n"
		);
		JavaScriptUnit compilUnit = (JavaScriptUnit) runConversion(workingCopies[0], true);
		verifyWorkingCopiesComments();
		if (docCommentSupport.equals(JavaScriptCore.ENABLED)) {
			// Verify  method javadoc
			ASTNode node = getASTNode(compilUnit, 0);
			assertEquals("Invalid type for node: "+node, ASTNode.TYPE_DECLARATION, node.getNodeType());
			TypeDeclaration typeDeclaration = (TypeDeclaration) node;
			JSdoc javadoc = typeDeclaration.getJavadoc();
			assertNotNull("TypeDeclaration should have a javadoc comment", javadoc);
			List tags = javadoc.tags();
			TagElement tag = (TagElement) tags.get(0);
			tag = (TagElement) tag.fragments().get(0);
			assertEquals("Tag name should be empty", tag.getTagName(), "@");
			tag = (TagElement) tags.get(1);
			assertEquals("Tag name should be empty", tag.getTagName(), "@");
		}
	}

	/**
	 * @bug 130752: [comments] first BlockComment parsed as LineComment
	 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=130752"
	 */
	public void testBug130752() throws JavaScriptModelException {
		workingCopies = new IJavaScriptUnit[1];
		workingCopies[0] = getWorkingCopy("/Converter15/src/javadoc/b130752/Test.js",
			"/* Ceci n'est pas\n" + 
			" * une ligne. */\n" + 
			"package javadoc.b130752;\n" + 
			"public class Test {\n" + 
			"}\n"
		);
		JavaScriptUnit compilUnit = (JavaScriptUnit) runConversion(workingCopies[0], true);
		verifyWorkingCopiesComments();
		if (docCommentSupport.equals(JavaScriptCore.ENABLED)) {
			// Verify comment type
			List unitComments = compilUnit.getCommentList();
			assertEquals("Wrong number of comments", 1, unitComments.size());
			Comment comment = (Comment) unitComments.get(0);
			assertEquals("Comment should be javadoc", comment.getNodeType(), ASTNode.BLOCK_COMMENT);
		}
	}
	public void testBug130752b() throws JavaScriptModelException {
		workingCopies = new IJavaScriptUnit[1];
		workingCopies[0] = getWorkingCopy("/Converter15/src/javadoc/b130752/Test.js",
			"// Line comment\n" + 
			"package javadoc.b130752;\n" + 
			"public class Test {\n" + 
			"}\n"
		);
		JavaScriptUnit compilUnit = (JavaScriptUnit) runConversion(workingCopies[0], true);
		verifyWorkingCopiesComments();
		if (docCommentSupport.equals(JavaScriptCore.ENABLED)) {
			// Verify comment type
			List unitComments = compilUnit.getCommentList();
			assertEquals("Wrong number of comments", 1, unitComments.size());
			Comment comment = (Comment) unitComments.get(0);
			assertEquals("Comment should be javadoc", comment.getNodeType(), ASTNode.LINE_COMMENT);
		}
	}
	public void testBug130752c() throws JavaScriptModelException {
		workingCopies = new IJavaScriptUnit[1];
		workingCopies[0] = getWorkingCopy("/Converter15/src/javadoc/b130752/Test.js",
			"/** Javadoc comment */\n" + 
			"package javadoc.b130752;\n" + 
			"public class Test {\n" + 
			"}\n"
		);
		JavaScriptUnit compilUnit = (JavaScriptUnit) runConversion(workingCopies[0], true);
		verifyWorkingCopiesComments();
		if (docCommentSupport.equals(JavaScriptCore.ENABLED)) {
			// Verify comment type
			List unitComments = compilUnit.getCommentList();
			assertEquals("Wrong number of comments", 1, unitComments.size());
			Comment comment = (Comment) unitComments.get(0);
			assertEquals("Comment should be javadoc", comment.getNodeType(), ASTNode.JSDOC);
		}
	}

}
