/*******************************************************************************
 * Copyright (c) 2000, 2018 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.aspectj.org.eclipse.jdt.core;

import java.util.StringTokenizer;
import java.util.regex.Pattern;

import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.aspectj.org.eclipse.jdt.core.compiler.*;
import org.aspectj.org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.aspectj.org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
import org.aspectj.org.eclipse.jdt.internal.compiler.parser.Scanner;
import org.aspectj.org.eclipse.jdt.internal.compiler.parser.ScannerHelper;
import org.aspectj.org.eclipse.jdt.internal.compiler.parser.TerminalTokens;
import org.aspectj.org.eclipse.jdt.internal.core.*;
import org.aspectj.org.eclipse.jdt.internal.core.util.Messages;

/**
 * Provides methods for checking Java-specific conventions such as name syntax.
 * <p>
 * This class provides static methods and constants only.
 * </p>
 * @noinstantiate This class is not intended to be instantiated by clients.
 */
public final class JavaConventions {

	private static final char DOT= '.';
    private static final Pattern DOT_DOT = Pattern.compile("(\\.)(\\1)+"); //$NON-NLS-1$
    private static final Pattern PREFIX_JAVA = Pattern.compile("java$"); //$NON-NLS-1$
	private static final Scanner SCANNER = new Scanner(false /*comment*/, true /*whitespace*/, false /*nls*/, ClassFileConstants.JDK1_3 /*sourceLevel*/, null/*taskTag*/, null/*taskPriorities*/, true /*taskCaseSensitive*/);

	private JavaConventions() {
		// Not instantiable
	}

	/**
	 * Returns whether the given package fragment root paths are considered
	 * to overlap.
	 * <p>
	 * Two root paths overlap if one is a prefix of the other, or they point to
	 * the same location. However, a JAR is allowed to be nested in a root.
	 *
	 * @param rootPath1 the first root path
	 * @param rootPath2 the second root path
	 * @return true if the given package fragment root paths are considered to overlap, false otherwise
	 * @deprecated Overlapping roots are allowed in 2.1
	 */
	public static boolean isOverlappingRoots(IPath rootPath1, IPath rootPath2) {
		if (rootPath1 == null || rootPath2 == null) {
			return false;
		}
		return rootPath1.isPrefixOf(rootPath2) || rootPath2.isPrefixOf(rootPath1);
	}

	/*
	 * Returns the current identifier extracted by the scanner (without unicode
	 * escapes) from the given id and for the given source and compliance levels.
	 * Returns <code>null</code> if the id was not valid
	 */
	private static synchronized char[] scannedIdentifier(String id, String sourceLevel, String complianceLevel) {
		if (id == null) {
			return null;
		}
		// Set scanner for given source and compliance levels
		SCANNER.sourceLevel = sourceLevel == null ? ClassFileConstants.JDK1_3 : CompilerOptions.versionToJdkLevel(sourceLevel);
		SCANNER.complianceLevel = complianceLevel == null ? ClassFileConstants.JDK1_3 : CompilerOptions.versionToJdkLevel(complianceLevel);

		try {
			SCANNER.setSource(id.toCharArray());
			int token = SCANNER.scanIdentifier();
			if (token != TerminalTokens.TokenNameIdentifier) return null;
			if (SCANNER.currentPosition == SCANNER.eofPosition) { // to handle case where we had an ArrayIndexOutOfBoundsException
				try {
					return SCANNER.getCurrentIdentifierSource();
				} catch (ArrayIndexOutOfBoundsException e) {
					return null;
				}
			} else {
				return null;
			}
		}
		catch (InvalidInputException e) {
			return null;
		}
	}

	/**
	 * Validate the given compilation unit name.
	 * <p>
	 * A compilation unit name must obey the following rules:
	 * <ul>
	 * <li> it must not be null
	 * <li> it must be suffixed by a dot ('.') followed by one of the
	 *       {@link JavaCore#getJavaLikeExtensions() Java-like extensions}
	 * <li> its prefix must be a valid identifier
	 * <li> it must not contain any characters or substrings that are not valid
	 *		   on the file system on which workspace root is located.
	 * </ul>
	 * </p>
	 * @param name the name of a compilation unit
	 * @return a status object with code <code>IStatus.OK</code> if
	 *		the given name is valid as a compilation unit name, otherwise a status
	 *		object indicating what is wrong with the name
	 * @deprecated Use {@link #validateCompilationUnitName(String id, String sourceLevel, String complianceLevel)} instead
	 */
	public static IStatus validateCompilationUnitName(String name) {
		return validateCompilationUnitName(name,CompilerOptions.VERSION_1_3,CompilerOptions.VERSION_1_3);
	}

	/**
	 * Validate the given compilation unit name for the given source and compliance levels.
	 * <p>
	 * A compilation unit name must obey the following rules:
	 * <ul>
	 * <li> it must not be null
	 * <li> it must be suffixed by a dot ('.') followed by one of the
	 *       {@link JavaCore#getJavaLikeExtensions() Java-like extensions}
	 * <li> its prefix must be a valid identifier
	 * <li> it must not contain any characters or substrings that are not valid
	 *		   on the file system on which workspace root is located.
	 * </ul>
	 * </p>
	 * @param name the name of a compilation unit
	 * @param sourceLevel the source level
	 * @param complianceLevel the compliance level
	 * @return a status object with code <code>IStatus.OK</code> if
	 *		the given name is valid as a compilation unit name, otherwise a status
	 *		object indicating what is wrong with the name
	 * @since 3.3
	 */
	public static IStatus validateCompilationUnitName(String name, String sourceLevel, String complianceLevel) {
		if (name == null) {
			return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.convention_unit_nullName, null);
		}
		if (!org.aspectj.org.eclipse.jdt.internal.core.util.Util.isJavaLikeFileName(name)) {
			return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.convention_unit_notJavaName, null);
		}
		String identifier;
		int index;
		index = name.lastIndexOf('.');
		if (index == -1) {
			return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.convention_unit_notJavaName, null);
		}
		identifier = name.substring(0, index);
		// JSR-175 metadata strongly recommends "package-info.java" as the
		// file in which to store package annotations and
		// the package-level spec (replaces package.html)
		if (!CharOperation.equals(identifier.toCharArray(), TypeConstants.PACKAGE_INFO_NAME)
				&& !CharOperation.equals(identifier.toCharArray(), TypeConstants.MODULE_INFO_NAME)) {
			IStatus status = validateIdentifier(identifier, sourceLevel, complianceLevel);
			if (!status.isOK()) {
				return status;
			}
		}
		IStatus status = ResourcesPlugin.getWorkspace().validateName(name, IResource.FILE);
		if (!status.isOK()) {
			return status;
		}
		return JavaModelStatus.VERIFIED_OK;
	}

	/**
	 * Validate the given .class file name.
	 * <p>
	 * A .class file name must obey the following rules:
	 * <ul>
	 * <li> it must not be null
	 * <li> it must include the <code>".class"</code> suffix
	 * <li> its prefix must be a valid identifier
	 * <li> it must not contain any characters or substrings that are not valid
	 *		   on the file system on which workspace root is located.
	 * </ul>
	 * </p>
	 * @param name the name of a .class file
	 * @return a status object with code <code>IStatus.OK</code> if
	 *		the given name is valid as a .class file name, otherwise a status
	 *		object indicating what is wrong with the name
	 * @since 2.0
	 * @deprecated Use {@link #validateClassFileName(String id, String sourceLevel, String complianceLevel)} instead
	 */
	public static IStatus validateClassFileName(String name) {
		return validateClassFileName(name, CompilerOptions.VERSION_1_3, CompilerOptions.VERSION_1_3);
	}

	/**
	 * Validate the given .class file name for the given source and compliance levels.
	 * <p>
	 * A .class file name must obey the following rules:
	 * <ul>
	 * <li> it must not be null
	 * <li> it must include the <code>".class"</code> suffix
	 * <li> its prefix must be a valid identifier
	 * <li> it must not contain any characters or substrings that are not valid
	 *		   on the file system on which workspace root is located.
	 * </ul>
	 * </p>
	 * @param name the name of a .class file
	 * @param sourceLevel the source level
	 * @param complianceLevel the compliance level
	 * @return a status object with code <code>IStatus.OK</code> if
	 *		the given name is valid as a .class file name, otherwise a status
	 *		object indicating what is wrong with the name
	 * @since 3.3
	 */
	public static IStatus validateClassFileName(String name, String sourceLevel, String complianceLevel) {
		if (name == null) {
			return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.convention_classFile_nullName, null);		}
		if (!org.aspectj.org.eclipse.jdt.internal.compiler.util.Util.isClassFileName(name)) {
			return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.convention_classFile_notClassFileName, null);
		}
		String identifier;
		int index;
		index = name.lastIndexOf('.');
		if (index == -1) {
			return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.convention_classFile_notClassFileName, null);
		}
		identifier = name.substring(0, index);
		// JSR-175 metadata strongly recommends "package-info.java" as the
		// file in which to store package annotations and
		// the package-level spec (replaces package.html)
		if (!CharOperation.equals(identifier.toCharArray(), TypeConstants.PACKAGE_INFO_NAME)
				&& !CharOperation.equals(identifier.toCharArray(), TypeConstants.MODULE_INFO_NAME)) {
			IStatus status = validateIdentifier(identifier, sourceLevel, complianceLevel);
			if (!status.isOK()) {
				return status;
			}
		}
		IStatus status = ResourcesPlugin.getWorkspace().validateName(name, IResource.FILE);
		if (!status.isOK()) {
			return status;
		}
		return JavaModelStatus.VERIFIED_OK;
	}

	/**
	 * Validate the given field name.
	 * <p>
	 * Syntax of a field name corresponds to VariableDeclaratorId (JLS2 8.3).
	 * For example, <code>"x"</code>.
	 *
	 * @param name the name of a field
	 * @return a status object with code <code>IStatus.OK</code> if
	 *		the given name is valid as a field name, otherwise a status
	 *		object indicating what is wrong with the name
	 * @deprecated Use {@link #validateFieldName(String id, String sourceLevel, String complianceLevel)} instead
	 */
	public static IStatus validateFieldName(String name) {
		return validateIdentifier(name, CompilerOptions.VERSION_1_3,CompilerOptions.VERSION_1_3);
	}

	/**
	 * Validate the given field name for the given source and compliance levels.
	 * <p>
	 * Syntax of a field name corresponds to VariableDeclaratorId (JLS2 8.3).
	 * For example, <code>"x"</code>.
	 *
	 * @param name the name of a field
	 * @param sourceLevel the source level
	 * @param complianceLevel the compliance level
	 * @return a status object with code <code>IStatus.OK</code> if
	 *		the given name is valid as a field name, otherwise a status
	 *		object indicating what is wrong with the name
	 * @since 3.3
	 */
	public static IStatus validateFieldName(String name, String sourceLevel, String complianceLevel) {
		return validateIdentifier(name, sourceLevel, complianceLevel);
	}

	/**
	 * Validate the given Java identifier.
	 * The identifier must not have the same spelling as a Java keyword,
	 * boolean literal (<code>"true"</code>, <code>"false"</code>), or null literal (<code>"null"</code>).
	 * See section 3.8 of the <em>Java Language Specification, Second Edition</em> (JLS2).
	 * A valid identifier can act as a simple type name, method name or field name.
	 *
	 * @param id the Java identifier
	 * @return a status object with code <code>IStatus.OK</code> if
	 *		the given identifier is a valid Java identifier, otherwise a status
	 *		object indicating what is wrong with the identifier
	 * @deprecated Use {@link #validateIdentifier(String id, String sourceLevel, String complianceLevel)} instead
	 */
	public static IStatus validateIdentifier(String id) {
		return validateIdentifier(id,CompilerOptions.VERSION_1_3,CompilerOptions.VERSION_1_3);
	}

	/**
	 * Validate the given Java identifier for the given source and compliance levels
	 * The identifier must not have the same spelling as a Java keyword,
	 * boolean literal (<code>"true"</code>, <code>"false"</code>), or null literal (<code>"null"</code>).
	 * See section 3.8 of the <em>Java Language Specification, Second Edition</em> (JLS2).
	 * A valid identifier can act as a simple type name, method name or field name.
	 *
	 * @param id the Java identifier
	 * @param sourceLevel the source level
	 * @param complianceLevel the compliance level
	 * @return a status object with code <code>IStatus.OK</code> if
	 *		the given identifier is a valid Java identifier, otherwise a status
	 *		object indicating what is wrong with the identifier
	 * @since 3.3
	 */
	public static IStatus validateIdentifier(String id, String sourceLevel, String complianceLevel) {
		if (scannedIdentifier(id, sourceLevel, complianceLevel) != null) {
			return JavaModelStatus.VERIFIED_OK;
		} else {
			return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.bind(Messages.convention_illegalIdentifier, id), null);
		}
	}

	/**
	 * Validate the given import declaration name.
	 * <p>
	 * The name of an import corresponds to a fully qualified type name
	 * or an on-demand package name as defined by ImportDeclaration (JLS2 7.5).
	 * For example, <code>"java.util.*"</code> or <code>"java.util.Hashtable"</code>.
	 *
	 * @param name the import declaration
	 * @return a status object with code <code>IStatus.OK</code> if
	 *		the given name is valid as an import declaration, otherwise a status
	 *		object indicating what is wrong with the name
	 * @deprecated Use {@link #validateImportDeclaration(String id, String sourceLevel, String complianceLevel)} instead
	 */
	public static IStatus validateImportDeclaration(String name) {
		return validateImportDeclaration(name,CompilerOptions.VERSION_1_3,CompilerOptions.VERSION_1_3);
	}

	/**
	 * Validate the given import declaration name for the given source and compliance levels.
	 * <p>
	 * The name of an import corresponds to a fully qualified type name
	 * or an on-demand package name as defined by ImportDeclaration (JLS2 7.5).
	 * For example, <code>"java.util.*"</code> or <code>"java.util.Hashtable"</code>.
	 *
	 * @param name the import declaration
	 * @param sourceLevel the source level
	 * @param complianceLevel the compliance level
	 * @return a status object with code <code>IStatus.OK</code> if
	 *		the given name is valid as an import declaration, otherwise a status
	 *		object indicating what is wrong with the name
	 * @since 3.3
	 */
	public static IStatus validateImportDeclaration(String name, String sourceLevel, String complianceLevel) {
		if (name == null || name.length() == 0) {
			return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.convention_import_nullImport, null);
		}
		if (name.charAt(name.length() - 1) == '*') {
			if (name.charAt(name.length() - 2) == '.') {
				return validatePackageName(name.substring(0, name.length() - 2), sourceLevel, complianceLevel);
			} else {
				return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.convention_import_unqualifiedImport, null);
			}
		}
		return validatePackageName(name, sourceLevel, complianceLevel);
	}

	/**
	 * Validate the given Java type name, either simple or qualified.
	 * For example, <code>"java.lang.Object"</code>, or <code>"Object"</code>.
	 * <p>
	 *
	 * @param name the name of a type
	 * @return a status object with code <code>IStatus.OK</code> if
	 *		the given name is valid as a Java type name,
	 *      a status with code <code>IStatus.WARNING</code>
	 *		indicating why the given name is discouraged,
	 *      otherwise a status object indicating what is wrong with
	 *      the name
	 * @deprecated Use {@link #validateJavaTypeName(String id, String sourceLevel, String complianceLevel)} instead
	 */
	public static IStatus validateJavaTypeName(String name) {
		return validateJavaTypeName(name, JavaCore.VERSION_1_3, JavaCore.VERSION_1_3);
	}

	/**
	 * Validate the given Java type name, either simple or qualified, for the given source and compliance levels.
	 * 
	 * <p>For example, <code>"java.lang.Object"</code>, or <code>"Object"</code>.</p>
	 * 
	 * <p>The source level and compliance level values should be taken from the constant defined inside
	 * {@link JavaCore} class. The constants are named <code>JavaCore#VERSION_1_x</code>, x being set
	 * between '1' and '8'.
	 * </p>
	 *
	 * @param name the name of a type
	 * @param sourceLevel the source level
	 * @param complianceLevel the compliance level
	 * @return a status object with code <code>IStatus.OK</code> if
	 *		the given name is valid as a Java type name,
	 *      a status with code <code>IStatus.WARNING</code>
	 *		indicating why the given name is discouraged,
	 *      otherwise a status object indicating what is wrong with
	 *      the name
	 * @since 3.3
	 * @see JavaCore#VERSION_1_1
	 * @see JavaCore#VERSION_1_2
	 * @see JavaCore#VERSION_1_3
	 * @see JavaCore#VERSION_1_4
	 * @see JavaCore#VERSION_1_5
	 * @see JavaCore#VERSION_1_6
	 * @see JavaCore#VERSION_1_7
	 * @see JavaCore#VERSION_1_8
	 * @see JavaCore#VERSION_9
	 */
	public static IStatus validateJavaTypeName(String name, String sourceLevel, String complianceLevel) {
		if (name == null) {
			return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.convention_type_nullName, null);
		}
		String trimmed = name.trim();
		if (!name.equals(trimmed)) {
			return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.convention_type_nameWithBlanks, null);
		}
		int index = name.lastIndexOf('.');
		char[] scannedID;
		if (index == -1) {
			// simple name
			scannedID = scannedIdentifier(name, sourceLevel, complianceLevel);
		} else {
			// qualified name
			String pkg = name.substring(0, index).trim();
			IStatus status = validatePackageName(pkg, sourceLevel, complianceLevel);
			if (!status.isOK()) {
				return status;
			}
			String type = name.substring(index + 1).trim();
			scannedID = scannedIdentifier(type, sourceLevel, complianceLevel);
		}

		if (scannedID != null) {
			IStatus status = ResourcesPlugin.getWorkspace().validateName(new String(scannedID), IResource.FILE);
			if (!status.isOK()) {
				return status;
			}
			if (CharOperation.contains('$', scannedID)) {
				return new Status(IStatus.WARNING, JavaCore.PLUGIN_ID, -1, Messages.convention_type_dollarName, null);
			}
			if ((scannedID.length > 0 && ScannerHelper.isLowerCase(scannedID[0]))) {
				return new Status(IStatus.WARNING, JavaCore.PLUGIN_ID, -1, Messages.convention_type_lowercaseName, null);
			}
			return JavaModelStatus.VERIFIED_OK;
		} else {
			return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.bind(Messages.convention_type_invalidName, name), null);
		}
	}

	/**
	 * Validate the given method name.
	 * The special names "&lt;init&gt;" and "&lt;clinit&gt;" are not valid.
	 * <p>
	 * The syntax for a method  name is defined by Identifier
	 * of MethodDeclarator (JLS2 8.4). For example "println".
	 *
	 * @param name the name of a method
	 * @return a status object with code <code>IStatus.OK</code> if
	 *		the given name is valid as a method name, otherwise a status
	 *		object indicating what is wrong with the name
	 * @deprecated Use {@link #validateMethodName(String id, String sourceLevel, String complianceLevel)} instead
	 */
	public static IStatus validateMethodName(String name) {
		return validateMethodName(name, CompilerOptions.VERSION_1_3,CompilerOptions.VERSION_1_3);
	}

	/**
	 * Validate the given method name for the given source and compliance levels.
	 * The special names "&lt;init&gt;" and "&lt;clinit&gt;" are not valid.
	 * <p>
	 * The syntax for a method  name is defined by Identifier
	 * of MethodDeclarator (JLS2 8.4). For example "println".
	 *
	 * @param name the name of a method
	 * @param sourceLevel the source level
	 * @param complianceLevel the compliance level
	 * @return a status object with code <code>IStatus.OK</code> if
	 *		the given name is valid as a method name, otherwise a status
	 *		object indicating what is wrong with the name
	 * @since 3.3
	 */
	public static IStatus validateMethodName(String name, String sourceLevel, String complianceLevel) {
		return validateIdentifier(name, sourceLevel,complianceLevel);
	}

	/**
	 * Validate the given package name.
	 * <p>
	 * The syntax of a package name corresponds to PackageName as
	 * defined by PackageDeclaration (JLS2 7.4). For example, <code>"java.lang"</code>.
	 * <p>
	 * Note that the given name must be a non-empty package name (that is, attempting to
	 * validate the default package will return an error status.)
	 * Also it must not contain any characters or substrings that are not valid
	 * on the file system on which workspace root is located.
	 *
	 * @param name the name of a package
	 * @return a status object with code <code>IStatus.OK</code> if
	 *		the given name is valid as a package name, otherwise a status
	 *		object indicating what is wrong with the name
	 * @deprecated Use {@link #validatePackageName(String id, String sourceLevel, String complianceLevel)} instead
	 */
	public static IStatus validatePackageName(String name) {
		return validatePackageName(name, CompilerOptions.VERSION_1_3,CompilerOptions.VERSION_1_3);
	}

	/**
	 * Validate the given package name for the given source and compliance levels.
	 * <p>
	 * The syntax of a package name corresponds to PackageName as
	 * defined by PackageDeclaration (JLS2 7.4). For example, <code>"java.lang"</code>.
	 * <p>
	 * Note that the given name must be a non-empty package name (that is, attempting to
	 * validate the default package will return an error status.)
	 * Also it must not contain any characters or substrings that are not valid
	 * on the file system on which workspace root is located.
	 *
	 * @param name the name of a package
	 * @param sourceLevel the source level
	 * @param complianceLevel the compliance level
	 * @return a status object with code <code>IStatus.OK</code> if
	 *		the given name is valid as a package name, otherwise a status
	 *		object indicating what is wrong with the name
	 * @since 3.3
	 */
	public static IStatus validatePackageName(String name, String sourceLevel, String complianceLevel) {

		if (name == null) {
			return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.convention_package_nullName, null);
		}
		int length;
		if ((length = name.length()) == 0) {
			return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.convention_package_emptyName, null);
		}
		if (name.charAt(0) == DOT || name.charAt(length-1) == DOT) {
			return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.convention_package_dotName, null);
		}
		if (CharOperation.isWhitespace(name.charAt(0)) || CharOperation.isWhitespace(name.charAt(name.length() - 1))) {
			return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.convention_package_nameWithBlanks, null);
		}
		if (DOT_DOT.matcher(name).find()) {
			return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.convention_package_consecutiveDotsName, null);
		}
		IWorkspace workspace = ResourcesPlugin.getWorkspace();
		StringTokenizer st = new StringTokenizer(name, "."); //$NON-NLS-1$
		boolean firstToken = true;
		IStatus warningStatus = null;
		while (st.hasMoreTokens()) {
			String typeName = st.nextToken();
			typeName = typeName.trim(); // grammar allows spaces
			char[] scannedID = scannedIdentifier(typeName, sourceLevel, complianceLevel);
			if (scannedID == null) {
				return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.bind(Messages.convention_illegalIdentifier, typeName), null);
			}
			IStatus status = workspace.validateName(new String(scannedID), IResource.FOLDER);
			if (!status.isOK()) {
				return status;
			}
			if (firstToken && scannedID.length > 0 && ScannerHelper.isUpperCase(scannedID[0])) {
				if (warningStatus == null) {
					warningStatus = new Status(IStatus.WARNING, JavaCore.PLUGIN_ID, -1, Messages.convention_package_uppercaseName, null);
				}
			}
			firstToken = false;
		}
		if (warningStatus != null) {
			return warningStatus;
		}
		return JavaModelStatus.VERIFIED_OK;
	}

	/**
	 * Validate the given module name for the given source and compliance levels.
	 * <p>
	 * The syntax of a module name corresponds to ModuleName as
	 * defined by ModuleDeclaration (JLS 7.6). For example, <code>"java.base"</code>.
	 * <p>
	 * Note that the given name must not be empty. Also each segment of the module
	 * name (separated by ".") must be a valid Java identifier as per JLS 3.8.
	 *
	 * @param name name of a module
	 * @param sourceLevel the source level
	 * @param complianceLevel the compliance level
	 * @return a status object with code <code>IStatus.OK</code> if
	 *		the given name is valid as a module name, otherwise a status
	 *		object indicating what is wrong with the name
	 * @since 3.14
	 */
	public static IStatus validateModuleName(String name, String sourceLevel, String complianceLevel) {

		if (name == null) {
			return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.convention_module_nullName, null);
		}
		int length;
		if ((length = name.length()) == 0) {
			return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.convention_module_emptyName, null);
		}

		if (name.charAt(0) == DOT || name.charAt(length-1) == DOT) {
			return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.convention_module_dotName, null);
		}
		if (CharOperation.isWhitespace(name.charAt(0)) || CharOperation.isWhitespace(name.charAt(name.length() - 1))) {
			return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.convention_module_nameWithBlanks, null);
		}
		if (DOT_DOT.matcher(name).find()) {
			return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.convention_module_consecutiveDotsName, null);
		}
		IWorkspace workspace = ResourcesPlugin.getWorkspace();
		StringTokenizer st = new StringTokenizer(name, "."); //$NON-NLS-1$
		boolean firstToken = true;
		IStatus warningStatus = null;
		while (st.hasMoreTokens()) {
			String segment = st.nextToken();
			segment = segment.trim(); // grammar allows spaces
			char[] scannedID = scannedIdentifier(segment, sourceLevel, complianceLevel);
			if (scannedID == null) {
				return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.bind(Messages.convention_illegalIdentifier, segment), null);
			}
			if (firstToken && PREFIX_JAVA.matcher(segment).find()) {
				warningStatus = new Status(IStatus.WARNING, JavaCore.PLUGIN_ID, -1, Messages.bind(Messages.convention_module_javaName), null);
			}
			IStatus status = workspace.validateName(new String(scannedID), IResource.FOLDER);
			if (!status.isOK()) {
				return status;
			}
			if (firstToken && scannedID.length > 0 && ScannerHelper.isUpperCase(scannedID[0])) {
				if (warningStatus == null) {
					warningStatus = new Status(IStatus.WARNING, JavaCore.PLUGIN_ID, -1, Messages.convention_module_uppercaseName, null);
				}
			}
			firstToken = false;
		}
		if (warningStatus != null) {
			return warningStatus;
		}
		return JavaModelStatus.VERIFIED_OK;
	}

	/**
	 * Validate a given classpath and output location for a project, using the following rules:
	 * <ul>
	 *   <li> Classpath entries cannot collide with each other; that is, all entry paths must be unique.
	 *   <li> The project output location path cannot be null, must be absolute and located inside the project.
	 *   <li> Specific output locations (specified on source entries) can be null, if not they must be located inside the project,
	 *   <li> A project entry cannot refer to itself directly (that is, a project cannot prerequisite itself).
     *   <li> Classpath entries or output locations cannot coincide or be nested in each other, except for the following scenarios listed below:
	 *      <ul><li> A source folder can coincide with its own output location, in which case this output can then contain library archives.
	 *                     However, a specific output location cannot coincide with any library or a distinct source folder than the one referring to it.<br>
	 *                     Note: Since 3.8, this behavior can be overridden by configuring {@link JavaCore#CORE_OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE}
	 *                     </li>
	 *              <li> A source/library folder can be nested in any source folder as long as the nested folder is excluded from the enclosing one. </li>
	 * 			<li> An output location can be nested in a source folder, if the source folder coincides with the project itself, or if the output
	 * 					location is excluded from the source folder.
	 *      </ul>
	 * </ul>
	 *
	 *  Note that the classpath entries are not validated automatically. Only bound variables or containers are considered
	 *  in the checking process (this allows to perform a consistency check on a classpath which has references to
	 *  yet non existing projects, folders, ...).
	 *  <p>
	 *  This validation is intended to anticipate classpath issues prior to assigning it to a project. In particular, it will automatically
	 *  be performed during the classpath setting operation (if validation fails, the classpath setting will not complete).
	 *  <p>
	 * @param javaProject the given java project
	 * @param rawClasspath the given classpath
	 * @param projectOutputLocation the given output location
	 * @return a status object with code <code>IStatus.OK</code> if
	 *		the given classpath and output location are compatible, otherwise a status
	 *		object indicating what is wrong with the classpath or output location
	 * @since 2.0
	 */
	public static IJavaModelStatus validateClasspath(IJavaProject javaProject, IClasspathEntry[] rawClasspath, IPath projectOutputLocation) {

		return ClasspathEntry.validateClasspath(javaProject, rawClasspath, projectOutputLocation);
	}

	/**
	 * Returns a Java model status describing the problem related to this classpath entry if any,
	 * a status object with code <code>IStatus.OK</code> if the entry is fine (that is, if the
	 * given classpath entry denotes a valid element to be referenced onto a classpath).
	 *
	 * @param project the given java project
	 * @param entry the given classpath entry
	 * @param checkSourceAttachment a flag to determine if source attachment should be checked
	 * @return a java model status describing the problem related to this classpath entry if any, a status object with code <code>IStatus.OK</code> if the entry is fine
	 * @since 2.0
	 */
	public static IJavaModelStatus validateClasspathEntry(IJavaProject project, IClasspathEntry entry, boolean checkSourceAttachment){
		return ClasspathEntry.validateClasspathEntry(project, entry, checkSourceAttachment, false/*not referred by container*/);
	}

	/**
	 * Validate the given type variable name.
	 * <p>
	 * Syntax of a type variable name corresponds to a Java identifier (JLS3 4.3).
	 * For example, <code>"E"</code>.
	 *
	 * @param name the name of a type variable
	 * @return a status object with code <code>IStatus.OK</code> if
	 *		the given name is valid as a type variable name, otherwise a status
	 *		object indicating what is wrong with the name
	 * @since 3.1
	 * @deprecated Use {@link #validateTypeVariableName(String id, String sourceLevel, String complianceLevel)} instead
	 */
	public static IStatus validateTypeVariableName(String name) {
		return validateIdentifier(name, CompilerOptions.VERSION_1_3,CompilerOptions.VERSION_1_3);
	}

	/**
	 * Validate the given type variable name for the given source and compliance levels.
	 * <p>
	 * Syntax of a type variable name corresponds to a Java identifier (JLS3 4.3).
	 * For example, <code>"E"</code>.
	 *
	 * @param name the name of a type variable
	 * @param sourceLevel the source level
	 * @param complianceLevel the compliance level
	 * @return a status object with code <code>IStatus.OK</code> if
	 *		the given name is valid as a type variable name, otherwise a status
	 *		object indicating what is wrong with the name
	 * @since 3.3
	 */
	public static IStatus validateTypeVariableName(String name, String sourceLevel, String complianceLevel) {
		return validateIdentifier(name, sourceLevel, complianceLevel);
	}

	/**
	 * Validate that all compiler options of the given project match keys and values
	 * described in {@link JavaCore#getDefaultOptions()} method.
	 *
	 * @param javaProject the given java project
	 * @param inheritJavaCoreOptions inherit project options from JavaCore or not.
	 * @return a status object with code <code>IStatus.OK</code> if all project
	 *		compiler options are valid, otherwise a status object indicating what is wrong
	 *		with the keys and their value.
	 * @since 3.1
	 * TODO (frederic) finalize for all possible options (JavaCore, DefaultCodeFormatterOptions, AssistOptions) and open to API
	 */
	/*
	public static IStatus validateCompilerOptions(IJavaProject javaProject, boolean inheritJavaCoreOptions)	  {
		return validateCompilerOptions(javaProject.getOptions(inheritJavaCoreOptions));
	}
	*/

	/**
	 * Validate that all compiler options of the given project match keys and values
	 * described in {@link JavaCore#getDefaultOptions()} method.
	 *
	 * @param compilerOptions Map of options
	 * @return a status object with code <code>IStatus.OK</code> if all
	 *		compiler options are valid, otherwise a status object indicating what is wrong
	 *		with the keys and their value.
	 * @since 3.1
	 */
	/*
	public static IStatus validateCompilerOptions(Map compilerOptions)	  {

		// Get current options
		String compliance = (String) compilerOptions.get(JavaCore.COMPILER_COMPLIANCE);
		String source = (String) compilerOptions.get(JavaCore.COMPILER_SOURCE);
		String target = (String) compilerOptions.get(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM);
		if (compliance == null && source == null && target == null) {
			return JavaModelStatus.VERIFIED_OK; // default is OK
		}

		// Initialize multi-status
		List errors = new ArrayList();

		// Set default for compliance if necessary (not set on project and not inherited...)
		if (compliance == null) {
			compliance = JavaCore.getOption(JavaCore.COMPILER_COMPLIANCE);
		}

		// Verify compliance level value and set source and target default if necessary
		long complianceLevel = 0;
		long sourceLevel = 0;
		long targetLevel = 0;
		if (JavaCore.VERSION_1_3.equals(compliance)) {
			complianceLevel = ClassFileConstants.JDK1_3;
			if (source == null) {
				source = JavaCore.VERSION_1_3;
				sourceLevel = ClassFileConstants.JDK1_3;
			}
			if (target == null) {
				target = JavaCore.VERSION_1_1;
				targetLevel = ClassFileConstants.JDK1_1;
			}
		} else if (JavaCore.VERSION_1_4.equals(compliance)) {
			complianceLevel = ClassFileConstants.JDK1_4;
			if (source == null) {
				source = JavaCore.VERSION_1_3;
				sourceLevel = ClassFileConstants.JDK1_3;
			}
			if (target == null) {
				target = JavaCore.VERSION_1_2;
				targetLevel = ClassFileConstants.JDK1_2;
			}
		} else if (JavaCore.VERSION_1_5.equals(compliance)) {
			complianceLevel = ClassFileConstants.JDK1_5;
			if (source == null) {
				source = JavaCore.VERSION_1_5;
				sourceLevel = ClassFileConstants.JDK1_5;
			}
			if (target == null) {
				target = JavaCore.VERSION_1_5;
				targetLevel = ClassFileConstants.JDK1_5;
			}
		} else {
			// compliance is not valid
			errors.add(new JavaModelStatus(IStatus.ERROR, Util.bind("convention.compiler.invalidCompilerOption", compliance==null?"":compliance, JavaCore.COMPILER_COMPLIANCE))); //$NON-NLS-1$ //$NON-NLS-2$
		}

		// Verify source value and set default for target if necessary
		 if (JavaCore.VERSION_1_4.equals(source)) {
			sourceLevel = ClassFileConstants.JDK1_4;
			if (target == null) {
				target = JavaCore.VERSION_1_4;
				targetLevel = ClassFileConstants.JDK1_4;
			}
		} else if (JavaCore.VERSION_1_5.equals(source)) {
			sourceLevel = ClassFileConstants.JDK1_5;
			if (target == null) {
				target = JavaCore.VERSION_1_5;
				targetLevel = ClassFileConstants.JDK1_5;
			}
		} else if (JavaCore.VERSION_1_3.equals(source)) {
			sourceLevel = ClassFileConstants.JDK1_3;
		} else {
			// source is not valid
			errors.add(new JavaModelStatus(IStatus.ERROR, Util.bind("convention.compiler.invalidCompilerOption", source==null?"":source, JavaCore.COMPILER_SOURCE))); //$NON-NLS-1$ //$NON-NLS-2$
		}

		// Verify target value
		 if (targetLevel == 0) {
			 targetLevel = CompilerOptions.versionToJdkLevel(target);
			 if (targetLevel == 0) {
				// target is not valid
				errors.add(new JavaModelStatus(IStatus.ERROR, Util.bind("convention.compiler.invalidCompilerOption", target==null?"":target, JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM))); //$NON-NLS-1$ //$NON-NLS-2$
			 }
		}

		// Check and set compliance/source/target compatibilities (only if they have valid values)
		if (complianceLevel != 0 && sourceLevel != 0 && targetLevel != 0) {
			// target must be 1.5 if source is 1.5
			if (sourceLevel >= ClassFileConstants.JDK1_5 && targetLevel < ClassFileConstants.JDK1_5) {
				errors.add(new JavaModelStatus(IStatus.ERROR, Util.bind("convention.compiler.incompatibleTargetForSource", target, JavaCore.VERSION_1_5))); //$NON-NLS-1$
			}
	   		else
		   		// target must be 1.4 if source is 1.4
	   			if (sourceLevel >= ClassFileConstants.JDK1_4 && targetLevel < ClassFileConstants.JDK1_4) {
					errors.add(new JavaModelStatus(IStatus.ERROR, Util.bind("convention.compiler.incompatibleTargetForSource", target, JavaCore.VERSION_1_4))); //$NON-NLS-1$
	   		}
			// target cannot be greater than compliance level
			if (complianceLevel < targetLevel){
				errors.add(new JavaModelStatus(IStatus.ERROR, Util.bind("convention.compiler.incompatibleComplianceForTarget", compliance, JavaCore.VERSION_1_4))); //$NON-NLS-1$
			}
			// compliance must be 1.5 if source is 1.5
			if (source.equals(JavaCore.VERSION_1_5) && complianceLevel < ClassFileConstants.JDK1_5) {
				errors.add(new JavaModelStatus(IStatus.ERROR, Util.bind("convention.compiler.incompatibleComplianceForSource", compliance, JavaCore.VERSION_1_5))); //$NON-NLS-1$
			} else
				// compliance must be 1.4 if source is 1.4
				if (source.equals(JavaCore.VERSION_1_4) && complianceLevel < ClassFileConstants.JDK1_4) {
					errors.add(new JavaModelStatus(IStatus.ERROR, Util.bind("convention.compiler.incompatibleComplianceForSource", compliance, JavaCore.VERSION_1_4))); //$NON-NLS-1$
			}
		}

		// Return status
		int size = errors.size();
		switch (size) {
			case 0:
				return JavaModelStatus.VERIFIED_OK;
			case 1:
				return (IStatus) errors.get(0);
			default:
				IJavaModelStatus[] allStatus = new IJavaModelStatus[size];
				errors.toArray(allStatus);
				return JavaModelStatus.newMultiStatus(allStatus);
		}
	}
	*/
}
