/**
 * Copyright (c) 2009 Mia-Software.
 * 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:
 *    Romain DERVAUX (Mia-Software) - initial API and implementation
 *******************************************************************************/
package org.eclipse.modisco.java.discoverer.internal.io.library;

import org.eclipse.gmt.modisco.java.ASTNode;
import org.eclipse.gmt.modisco.java.AbstractMethodDeclaration;
import org.eclipse.gmt.modisco.java.AbstractTypeDeclaration;
import org.eclipse.gmt.modisco.java.Annotation;
import org.eclipse.gmt.modisco.java.AnnotationMemberValuePair;
import org.eclipse.gmt.modisco.java.AnnotationTypeMemberDeclaration;
import org.eclipse.gmt.modisco.java.Archive;
import org.eclipse.gmt.modisco.java.ArrayInitializer;
import org.eclipse.gmt.modisco.java.ArrayType;
import org.eclipse.gmt.modisco.java.BodyDeclaration;
import org.eclipse.gmt.modisco.java.BooleanLiteral;
import org.eclipse.gmt.modisco.java.CharacterLiteral;
import org.eclipse.gmt.modisco.java.ClassDeclaration;
import org.eclipse.gmt.modisco.java.ClassFile;
import org.eclipse.gmt.modisco.java.EnumConstantDeclaration;
import org.eclipse.gmt.modisco.java.EnumDeclaration;
import org.eclipse.gmt.modisco.java.Expression;
import org.eclipse.gmt.modisco.java.FieldDeclaration;
import org.eclipse.gmt.modisco.java.InheritanceKind;
import org.eclipse.gmt.modisco.java.MethodDeclaration;
import org.eclipse.gmt.modisco.java.Model;
import org.eclipse.gmt.modisco.java.Modifier;
import org.eclipse.gmt.modisco.java.NumberLiteral;
import org.eclipse.gmt.modisco.java.Package;
import org.eclipse.gmt.modisco.java.ParameterizedType;
import org.eclipse.gmt.modisco.java.PrimitiveType;
import org.eclipse.gmt.modisco.java.SingleVariableAccess;
import org.eclipse.gmt.modisco.java.SingleVariableDeclaration;
import org.eclipse.gmt.modisco.java.StringLiteral;
import org.eclipse.gmt.modisco.java.TypeAccess;
import org.eclipse.gmt.modisco.java.TypeDeclaration;
import org.eclipse.gmt.modisco.java.TypeLiteral;
import org.eclipse.gmt.modisco.java.TypeParameter;
import org.eclipse.gmt.modisco.java.UnresolvedItem;
import org.eclipse.gmt.modisco.java.UnresolvedItemAccess;
import org.eclipse.gmt.modisco.java.VariableDeclarationFragment;
import org.eclipse.gmt.modisco.java.VisibilityKind;
import org.eclipse.gmt.modisco.java.WildCardType;
import org.eclipse.gmt.modisco.java.emf.JavaFactory;
import org.eclipse.jdt.core.Flags;
import org.eclipse.jdt.core.IAnnotation;
import org.eclipse.jdt.core.IClassFile;
import org.eclipse.jdt.core.IField;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IMember;
import org.eclipse.jdt.core.IMemberValuePair;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.ITypeParameter;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.Signature;
import org.eclipse.modisco.java.discoverer.internal.io.java.JDTVisitor;
import org.eclipse.modisco.java.discoverer.internal.io.java.JDTVisitorUtils;
import org.eclipse.modisco.java.discoverer.internal.io.java.binding.Binding;
import org.eclipse.modisco.java.discoverer.internal.io.java.binding.BindingManager;
import org.eclipse.modisco.java.discoverer.internal.io.java.binding.ClassBinding;
import org.eclipse.modisco.java.discoverer.internal.io.java.binding.FieldBinding;
import org.eclipse.modisco.java.discoverer.internal.io.java.binding.MethodBinding;
import org.eclipse.modisco.java.discoverer.internal.io.java.binding.PendingElement;
import org.eclipse.modisco.java.discoverer.internal.io.library.binding.JavaModelDelegateBindingFactory;

/**
 * The main class for populating the Java model from the JDT Java model of
 * {@link IClassFile class files}.
 *
 * @see Model
 */
public class ClassFileParser {

	/**
	 * the EMF factory
	 */
	private JavaFactory factory;

	/**
	 * the model
	 */
	private final Model model;

	/**
	 * the global {@code BindingManager}
	 */
	private BindingManager globalBindings;

	/**
	 * a {@code TypeFinder}
	 */
	private final TypeFinder typeFinder;

	/**
	 * the path of the currently visited class file
	 */
	private final String filePath;

	/**
	 * the {@code ClassFile} object associated with the .class file of the
	 * top-level type
	 */
	private ClassFile cuNode;

	/**
	 * the current package
	 */
	private Package currentPackage;

	/**
	 * the currently visited java type or method. Useful to retrieve type
	 * variable definition.
	 */
	private IMember currentlyVisitedJavaElement = null;

	public ClassFileParser(final JavaFactory factory, final Model resultModel,
			final BindingManager globalBindings, final TypeFinder typeFinder, final String filePath) {
		setFactory(factory);
		this.model = resultModel;
		setGlobalBindings(globalBindings);
		this.typeFinder = typeFinder;
		this.filePath = filePath;
	}

	/**
	 * Finds the type variable associated with the currently visited Java
	 * element (type or method) or with it's parent.
	 *
	 * @param name
	 *            the name of the type variable
	 * @return the {@code ITypeParameter}
	 */
	public ITypeParameter findTypeParameter(final String name) {
		IMember member = this.currentlyVisitedJavaElement;
		ITypeParameter typeParameter = null;
		while (member != null) {
			if (member.getElementType() == IJavaElement.METHOD) {
				typeParameter = ((IMethod) member).getTypeParameter(name);
			} else {
				typeParameter = ((IType) member).getTypeParameter(name);
			}
			if (typeParameter.exists()) {
				break;
			}
			member = member.getDeclaringType();
		}
		return typeParameter;
	}

	public TypeFinder getTypeFinder() {
		return this.typeFinder;
	}

	/**
	 * @see org.eclipse.modisco.java.discoverer.internal.io.java.JDTVisitor#initializeNode(ASTNode,
	 *      org.eclipse.jdt.core.dom.ASTNode)
	 */
	public void initializeNode(final ASTNode element) {
		element.setOriginalClassFile(this.cuNode);
	}

	public void parse(final IClassFile classFile) throws JavaModelException {

		IType type = classFile.getType();

		// we only want top level types
		if (!type.exists() || type.isAnonymous() || type.isLocal() || type.isMember()) {
			return;
		}

		// we check if this type has already been visited
		Binding id = JavaModelDelegateBindingFactory.getInstance().getBindingForElement(type, this);
		if (getGlobalBindings().containsTarget(id)) {
			return;
		}

		visitPackage(type.getPackageFragment());
		visitClassFile(classFile);

		Archive archive = LibraryReader.getArchive(classFile, getFactory(), this.model);
		if (archive != null) {
			// jar or zip file
			archive.getClassFiles().add(this.cuNode);
		} else {
			// folder
			this.model.getClassFiles().add(this.cuNode);
		}

		parse2(type, null);
	}

	/**
	 * Creation of the {@link ClassFile} object
	 *
	 * @param classFile
	 */
	protected void visitClassFile(final IClassFile classFile) {
		ClassFile element = getFactory().createClassFile();
		this.model.getClassFiles().add(element);

		element.setName(classFile.getElementName());
		element.setOriginalFilePath(this.filePath);
		element.setPackage(this.currentPackage);

		this.cuNode = element;
	}

	/**
	 * Visit the members (fields, methods and types) of the {@code type}.
	 *
	 * @param type
	 *            the java model {@code IType}
	 * @param enclosingType
	 *            the MoDisco enclosing type of the {@code IType}
	 * @return the {@link AbstractTypeDeclaration} object corresponding to the
	 *         {@code IType}, {@code null} if type does not exist.
	 * @throws JavaModelException
	 */
	protected AbstractTypeDeclaration parse2(final IType type,
			final AbstractTypeDeclaration enclosingType) throws JavaModelException {

		AbstractTypeDeclaration typeDeclaration = visitType(type);

		if (enclosingType == null) {
			// the class file object registers the top level type
			this.cuNode.setType(typeDeclaration);
		} else {
			// type is an member type
			enclosingType.getBodyDeclarations().add(typeDeclaration);
		}

		// fields
		for (IField f : type.getFields()) {
			if (type.isEnum() && f.isEnumConstant()) {
				EnumConstantDeclaration constant = visitEnumConstantDeclaration(f);
				if (constant != null) {
					((EnumDeclaration) typeDeclaration).getEnumConstants().add(constant);
				}
			} else {
				// declaring type is an annotation, interface or type
				FieldDeclaration field = visitField(f);
				if (field != null) {
					typeDeclaration.getBodyDeclarations().add(field);
				}
			}
		}

		// methods
		for (IMethod m : type.getMethods()) {
			BodyDeclaration method = null;
			if (type.isAnnotation()) {
				method = visitAnnotationTypeMemberDeclaration(m);
			} else {
				method = visitMethod(m);
			}
			if (method != null) {
				typeDeclaration.getBodyDeclarations().add(method);
			}
		}

		// member types
		for (IType subType : type.getTypes()) {
			if (subType.exists()) {
				parse2(subType, typeDeclaration);
			}
		}

		return typeDeclaration;
	}

	/**
	 * Visit the package of the class file.
	 *
	 * @param packageFragment
	 *            the {@code IPackageFragment}
	 */
	protected void visitPackage(final IPackageFragment packageFragment) {

		Package element = null;

		// the empty package
		if (!packageFragment.exists() || packageFragment.getElementName().length() == 0) {
			element = (Package) getGlobalBindings().getTarget(JDTVisitor.DEFAULT_PKG_ID);
			if (element == null) {
				element = getFactory().createPackage();
				element.setName(JDTVisitor.DEFAULT_PKG_ID);
				element.setModel(this.model);
				getGlobalBindings().addTarget(JDTVisitor.DEFAULT_PKG_ID, element);
			}
		} else {
			// named package
			Binding id = JavaModelDelegateBindingFactory.getInstance().getBindingForElement(
					packageFragment, this);
			if (!getGlobalBindings().containsTarget(id.toString())) {
				element = createPackageHierarchy(packageFragment);
				ClassFileParserUtils.manageBindingDeclaration(element, packageFragment, this);
			} else {
				element = (Package) getGlobalBindings().getTarget(id.toString());
			}
		}

		this.currentPackage = element;
	}

	// create iterately a hierarchy of packages
	protected Package createPackageHierarchy(final IPackageFragment packageFragment) {
		Package result = getFactory().createPackage();
		Binding id = JavaModelDelegateBindingFactory.getInstance().getBindingForElement(
				packageFragment, this);
		String currentPackageName = id.getName();
		Package localCurrentPackage = result;
		int lastDotIndex = currentPackageName.lastIndexOf('.');
		if (lastDotIndex == -1) {
			this.model.getOwnedElements().add(result);
			localCurrentPackage.setName(currentPackageName);
		} else {
			// iterate on parents packages to create them if needed
			localCurrentPackage.setName(currentPackageName.substring(lastDotIndex + 1));
			while (lastDotIndex > 0) {
				// add qualified name for curent Package
				currentPackageName = currentPackageName.substring(0, lastDotIndex);
				Package aParentPackage = null;
				if (!getGlobalBindings().containsTarget(currentPackageName)) {
					aParentPackage = getFactory().createPackage();

					getGlobalBindings().addTarget(currentPackageName, aParentPackage);
					lastDotIndex = currentPackageName.lastIndexOf('.');
					if (lastDotIndex < 0) { // top level package
						this.model.getOwnedElements().add(aParentPackage);
						aParentPackage.setName(currentPackageName);
					} else {
						aParentPackage.setName(currentPackageName.substring(lastDotIndex + 1));
					}
					aParentPackage.getOwnedPackages().add(localCurrentPackage);
				} else {
					aParentPackage = (Package) getGlobalBindings().getTarget(currentPackageName); // (PackageDeclaration)binding.get(node);
					aParentPackage.getOwnedPackages().add(localCurrentPackage);
					break; // if this package is registered, parents packages
							// also are
				}
				localCurrentPackage = aParentPackage;
			}
		}
		return result;
	}

	/**
	 * Visit the properties of an {@code IType}.
	 *
	 * @param type
	 *            the {@code IType}
	 * @return the {@link AbstractTypeDeclaration} object corresponding to the
	 *         {@code IType}
	 * @throws JavaModelException
	 */
	protected AbstractTypeDeclaration visitType(final IType type) throws JavaModelException {

		AbstractTypeDeclaration element = null;
		if (type.isEnum()) {
			element = getFactory().createEnumDeclaration();
		} else if (type.isAnnotation()) {
			element = getFactory().createAnnotationTypeDeclaration();
		} else if (type.isInterface()) {
			element = getFactory().createInterfaceDeclaration();
		} else {
			element = getFactory().createClassDeclaration();
		}

		this.currentlyVisitedJavaElement = type;
		initializeNode(element);

		element.setName(type.getElementName());
		element.setPackage(this.currentPackage);
		this.currentPackage.getOwnedElements().add(element);

		// superClass
		// enums are classes but can't have explicit superclass
		String superClass = type.getSuperclassTypeSignature();
		if (type.isClass() && superClass != null
				&& !ClassFileParserUtils.isJavaLangObject(superClass)) {
			((ClassDeclaration) element).setSuperClass(getRefOnType(superClass));
		}

		// superInterfaces
		// annotations can't have explicit annotations
		if (!type.isAnnotation()) {
			for (String superInterface : type.getSuperInterfaceTypeSignatures()) {
				if (!ClassFileParserUtils.isJavaLangObject(superInterface)) {
					element.getSuperInterfaces().add(getRefOnType(superInterface));
				}
			}
		}

		// type parameters
		ITypeParameter[] parameters = type.getTypeParameters();
		for (ITypeParameter parameter : parameters) {
			TypeParameter t = getFactory().createTypeParameter();
			((TypeDeclaration) element).getTypeParameters().add(t);
			visitTypeParameter(parameter, t);
		}

		// annotations
		for (IAnnotation annotation : type.getAnnotations()) {
			Annotation anno = getFactory().createAnnotation();
			element.getAnnotations().add(anno);
			visitAnnotation(annotation, anno);
		}

		// visibility modifier
		Modifier m = getFactory().createModifier();
		element.setModifier(m);
		m.setBodyDeclaration(element);
		manageModifier(m, type.getFlags(), type);

		ClassFileParserUtils.manageBindingDeclaration(element, type, this);

		return element;
	}

	/**
	 * Visit a {@code IField}.
	 *
	 * @param field
	 *            the {@code IField}
	 * @return the {@link FieldDeclaration} object corresponding to the
	 *         {@code IField}, or {@code null} if the field does not exist or is
	 *         {@link org.eclipse.jdt.core.Flags#isSynthetic(int) synthetic}
	 * @throws JavaModelException
	 */
	protected FieldDeclaration visitField(final IField field) throws JavaModelException {
		if (Flags.isSynthetic(field.getFlags())) {
			return null;
		}

		FieldDeclaration element = getFactory().createFieldDeclaration();
		initializeNode(element);

		// type
		String type = field.getTypeSignature();
		element.setType(getRefOnType(type));

		// visibility modifier
		Modifier m = getFactory().createModifier();
		element.setModifier(m);
		m.setBodyDeclaration(element);
		manageModifier(m, field.getFlags(), field);

		// the fragment of this field
		VariableDeclarationFragment fragment = getFactory().createVariableDeclarationFragment();
		initializeNode(fragment);
		fragment.setExtraArrayDimensions(0);
		fragment.setName(field.getElementName());
		fragment.setVariablesContainer(element);

		for (IAnnotation annotation : field.getAnnotations()) {
			Annotation anno = getFactory().createAnnotation();
			element.getAnnotations().add(anno);
			visitAnnotation(annotation, anno);
		}

		ClassFileParserUtils.manageBindingDeclaration(fragment, field, this);

		return element;
	}

	protected AnnotationTypeMemberDeclaration visitAnnotationTypeMemberDeclaration(
			final IMethod method) throws JavaModelException {
		AnnotationTypeMemberDeclaration element = getFactory()
				.createAnnotationTypeMemberDeclaration();
		initializeNode(element);

		element.setName(method.getElementName());
		element.setType(getRefOnType(method.getReturnType()));

		// the default value of this annotation member
		IMemberValuePair defaultValue = method.getDefaultValue();
		if (defaultValue != null) {
			Expression result = manageMemberValuePair(defaultValue);
			element.setDefault(result);
		}

		Modifier m = getFactory().createModifier();
		m.setBodyDeclaration(element);
		element.setModifier(m);
		manageModifier(m, method.getFlags(), method);

		ClassFileParserUtils.manageBindingDeclaration(element, method, this);

		return element;
	}

	protected EnumConstantDeclaration visitEnumConstantDeclaration(final IField field)
			throws JavaModelException {
		EnumConstantDeclaration element = getFactory().createEnumConstantDeclaration();
		initializeNode(element);

		element.setName(field.getElementName());
		element.setModifier(getFactory().createModifier());

		// annotations
		for (IAnnotation annotation : field.getAnnotations()) {
			Annotation anno = getFactory().createAnnotation();
			element.getAnnotations().add(anno);
			visitAnnotation(annotation, anno);
		}

		ClassFileParserUtils.manageBindingDeclaration(element, field, this);

		return element;
	}

	/**
	 * Visit a {@code IMethod}.
	 *
	 * @param method
	 *            the {@code IMethod}
	 * @return the {@link AbstractMethodDeclaration} object corresponding to the
	 *         {@code IMethod}, or {@code null} if the method does not exist or
	 *         is {@link org.eclipse.jdt.core.Flags#isSynthetic(int) synthetic}
	 *         or is {@link org.eclipse.jdt.core.Flags#isBridge(int) bridge} or
	 *         its name equals the special name <code>"&lt;clinit&gt;"</code>
	 * @throws JavaModelException
	 * @see org.eclipse.jdt.core.IMethod#getElementName()
	 */
	protected AbstractMethodDeclaration visitMethod(final IMethod method) throws JavaModelException {
		if (Flags.isSynthetic(method.getFlags()) || Flags.isBridge(method.getFlags())
				|| method.getElementName().equals("<clinit>")) { //$NON-NLS-1$
			return null;
		}

		this.currentlyVisitedJavaElement = method;
		AbstractMethodDeclaration element = null;
		if (method.isConstructor()) {
			element = getFactory().createConstructorDeclaration();
		} else {
			element = getFactory().createMethodDeclaration();
		}
		initializeNode(element);

		element.setName(method.getElementName());

		// throwns exceptions
		for (String exc : method.getExceptionTypes()) {
			element.getThrownExceptions().add(getRefOnType(exc));
		}

		// return type
		if (!method.isConstructor()) {
			String returnType = method.getReturnType();
			((MethodDeclaration) element).setReturnType(getRefOnType(returnType));
		}

		// type parameters
		ITypeParameter[] parameters = method.getTypeParameters();
		for (ITypeParameter parameter : parameters) {
			TypeParameter t = getFactory().createTypeParameter();
			element.getTypeParameters().add(t);
			visitTypeParameter(parameter, t);
		}

		// parameters
		for (int i = 0; i < method.getNumberOfParameters(); i++) {
			String parameterType = method.getParameterTypes()[i];
			String parameterName = method.getRawParameterNames()[i];

			SingleVariableDeclaration var = getFactory().createSingleVariableDeclaration();
			initializeNode(var);
			element.getParameters().add(var);
			var.setMethodDeclaration(element);
			var.setName(parameterName);
			var.setExtraArrayDimensions(0);
			// varargs option for the last argument
			if (i == method.getNumberOfParameters() - 1) {
				boolean isMethodVarargs = Flags.isVarargs(method.getFlags());
				var.setVarargs(isMethodVarargs);
			}

			var.setType(getRefOnType(parameterType));
		}

		// annotations
		for (IAnnotation annotation : method.getAnnotations()) {
			Annotation anno = getFactory().createAnnotation();
			element.getAnnotations().add(anno);
			visitAnnotation(annotation, anno);
		}

		// visibility modifier
		Modifier m = getFactory().createModifier();
		element.setModifier(m);
		m.setBodyDeclaration(element);
		manageModifier(m, method.getFlags(), method);

		ClassFileParserUtils.manageBindingDeclaration(element, method, this);

		return element;
	}

	protected void visitAnnotation(final IAnnotation annotation, final Annotation anno)
			throws JavaModelException {
		initializeNode(anno);

		String typeName = annotation.getElementName();
		// typeName is not a signature : java.lang.Deprecated
		String typeSignature = Signature.createTypeSignature(typeName, true);
		anno.setType(getRefOnType(typeSignature));

		for (IMemberValuePair valuePair : annotation.getMemberValuePairs()) {
			AnnotationMemberValuePair element = getFactory().createAnnotationMemberValuePair();
			initializeNode(element);
			anno.getValues().add(element);

			Expression value = manageMemberValuePair(valuePair);
			element.setValue(value);

			// member is a method declared in an annotation
			PendingElement pending = new PendingElement(getFactory());
			pending.setClientNode(element);
			pending.setLinkName("member"); //$NON-NLS-1$
			Binding id = null;
			if (this.typeFinder.isTypeExists(typeName)) {
				ClassBinding parent = JavaModelDelegateBindingFactory.getInstance()
						.getBindingForName(typeSignature, this, true);
				id = new MethodBinding();
				((MethodBinding) id).setDeclaringClass(parent);
				id.setName(valuePair.getMemberName());
			} else {
				id = new Binding();
				id.setName(typeName + "." + valuePair.getMemberName() + "()"); //$NON-NLS-1$ //$NON-NLS-2$
			}
			getGlobalBindings().addPending(pending, id);
		}
	}

	private Expression manageMemberValuePair(final IMemberValuePair defaultValue) {

		Expression result = null;

		switch (defaultValue.getValueKind()) {
		case IMemberValuePair.K_CLASS:
			result = manageValuePairClassKind(defaultValue);
			break;

		case IMemberValuePair.K_ANNOTATION:
			result = manageValuePairAnnotationKind(defaultValue);
			break;

		case IMemberValuePair.K_QUALIFIED_NAME:
			result = manageValuePairQualifiedNameKind(defaultValue);
			break;

		case IMemberValuePair.K_BOOLEAN:
			if (defaultValue.getValue().getClass().isArray()) {
				Object[] tab = (Object[]) defaultValue.getValue();
				ArrayInitializer array = getFactory().createArrayInitializer();
				initializeNode(array);
				for (Object element : tab) {
					BooleanLiteral bool = getFactory().createBooleanLiteral();
					bool.setValue(((Boolean) element).booleanValue());
					array.getExpressions().add(bool);
				}
				result = array;
			} else {
				BooleanLiteral bool = getFactory().createBooleanLiteral();
				bool.setValue(((Boolean) defaultValue.getValue()).booleanValue());
				result = bool;
			}
			break;

		case IMemberValuePair.K_CHAR:
			if (defaultValue.getValue().getClass().isArray()) {
				Object[] tab = (Object[]) defaultValue.getValue();
				ArrayInitializer array = getFactory().createArrayInitializer();
				initializeNode(array);
				for (Object element : tab) {
					CharacterLiteral ch = getFactory().createCharacterLiteral();
					char value = ((Character) element).charValue();
					ch.setEscapedValue(ClassFileParserUtils.escapeCharacter(value));
					array.getExpressions().add(ch);
				}
				result = array;
			} else {
				CharacterLiteral ch = getFactory().createCharacterLiteral();
				char value = ((Character) defaultValue.getValue()).charValue();
				ch.setEscapedValue(ClassFileParserUtils.escapeCharacter(value));
				result = ch;
			}
			break;

		case IMemberValuePair.K_DOUBLE:
		case IMemberValuePair.K_BYTE:
		case IMemberValuePair.K_FLOAT:
		case IMemberValuePair.K_INT:
		case IMemberValuePair.K_LONG:
			if (defaultValue.getValue().getClass().isArray()) {
				Object[] tab = (Object[]) defaultValue.getValue();
				ArrayInitializer array = getFactory().createArrayInitializer();
				initializeNode(array);
				for (Object element : tab) {
					NumberLiteral number = getFactory().createNumberLiteral();
					number.setTokenValue(element.toString());
					array.getExpressions().add(number);
				}
				result = array;
			} else {
				NumberLiteral number = getFactory().createNumberLiteral();
				number.setTokenValue(defaultValue.getValue().toString());
				result = number;
			}
			break;

		case IMemberValuePair.K_STRING:
			if (defaultValue.getValue().getClass().isArray()) {
				Object[] tab = (Object[]) defaultValue.getValue();
				ArrayInitializer array = getFactory().createArrayInitializer();
				initializeNode(array);
				for (Object element : tab) {
					StringLiteral string = getFactory().createStringLiteral();
					String value = String.valueOf(element);
					string.setEscapedValue(ClassFileParserUtils.escapeString(value));
					array.getExpressions().add(string);
				}
				result = array;
			} else {
				StringLiteral string = getFactory().createStringLiteral();
				String value = String.valueOf(defaultValue.getValue());
				string.setEscapedValue(ClassFileParserUtils.escapeString(value));
				result = string;
			}
			break;

		case IMemberValuePair.K_SIMPLE_NAME: // there should be no K_SIMPLE_NAME
												// in .class files
		case IMemberValuePair.K_UNKNOWN:
		default:
			if (defaultValue.getValue().getClass().isArray()) {
				Object[] tab = (Object[]) defaultValue.getValue();
				ArrayInitializer array = getFactory().createArrayInitializer();
				initializeNode(array);
				for (Object element : tab) {
					UnresolvedItemAccess unrAcc = getFactory().createUnresolvedItemAccess();
					UnresolvedItem item = getFactory().createUnresolvedItem();
					unrAcc.setElement(item);
					item.setName(String.valueOf(element));
					array.getExpressions().add(unrAcc);
				}
				result = array;
			} else {
				UnresolvedItemAccess unrAcc = getFactory().createUnresolvedItemAccess();
				UnresolvedItem item = getFactory().createUnresolvedItem();
				unrAcc.setElement(item);
				item.setName(String.valueOf(defaultValue.getValue()));
				result = unrAcc;
			}
			break;
		}
		return result;
	}

	private Expression manageValuePairQualifiedNameKind(final IMemberValuePair defaultValue) {
		Expression result;
		if (defaultValue.getValue().getClass().isArray()) {
			Object[] tab = (Object[]) defaultValue.getValue();
			ArrayInitializer array = getFactory().createArrayInitializer();
			initializeNode(array);
			for (Object element : tab) {
				SingleVariableAccess varAcc = getFactory().createSingleVariableAccess();
				PendingElement pending = new PendingElement(getFactory());
				pending.setClientNode(varAcc);
				pending.setLinkName("variable"); //$NON-NLS-1$
				String name = String.valueOf(element.toString());
				String memberName = name.substring(name.lastIndexOf('.') + 1);
				String typeName = name.substring(0, name.lastIndexOf('.'));

				Binding id = null;
				if (this.typeFinder.isTypeExists(typeName)) {
					ClassBinding parent = JavaModelDelegateBindingFactory.getInstance()
							.getBindingForName(Signature.createTypeSignature(typeName, true), this,
									true);
					id = new FieldBinding();
					((FieldBinding) id).setDeclaringClass(parent);
					id.setName(memberName);
				} else {
					id = new Binding();
					id.setName(typeName + "." + memberName); //$NON-NLS-1$
				}
				getGlobalBindings().addPending(pending, id);
				array.getExpressions().add(varAcc);
			}
			result = array;
		} else {
			// reference on a field or an enum constant
			// can't use
			// JavaModelDelegateBindingFactory.getBindingForName(String,
			// ClassFileParser)
			// since it is dedicated to types references
			SingleVariableAccess varAcc = getFactory().createSingleVariableAccess();
			PendingElement pending = new PendingElement(getFactory());
			pending.setClientNode(varAcc);
			pending.setLinkName("variable"); //$NON-NLS-1$
			String name = String.valueOf(defaultValue.getValue());
			String memberName = name.substring(name.lastIndexOf('.') + 1);
			String typeName = name.substring(0, name.lastIndexOf('.'));

			Binding id = null;
			if (this.typeFinder.isTypeExists(typeName)) {
				ClassBinding parent = JavaModelDelegateBindingFactory.getInstance()
						.getBindingForName(Signature.createTypeSignature(typeName, true), this,
								true);
				id = new FieldBinding();
				((FieldBinding) id).setDeclaringClass(parent);
				id.setName(memberName);
			} else {
				id = new Binding();
				id.setName(typeName + "." + memberName); //$NON-NLS-1$
			}
			getGlobalBindings().addPending(pending, id);
			result = varAcc;
		}
		return result;
	}

	private Expression manageValuePairAnnotationKind(final IMemberValuePair defaultValue) {
		Expression result;
		if (defaultValue.getValue().getClass().isArray()) {
			Object[] tab = (Object[]) defaultValue.getValue();
			ArrayInitializer array = getFactory().createArrayInitializer();
			initializeNode(array);
			for (Object element : tab) {
				IAnnotation annotation = (IAnnotation) element;
				Annotation anno = getFactory().createAnnotation();
				try {
					visitAnnotation(annotation, anno);
				} catch (JavaModelException e) {
					// nothing
					assert (true); // Dummy code for "EmptyBlock" rule
				}
				array.getExpressions().add(anno);
			}
			result = array;
		} else {
			IAnnotation annotation = (IAnnotation) defaultValue.getValue();
			Annotation anno = getFactory().createAnnotation();
			try {
				visitAnnotation(annotation, anno);
			} catch (JavaModelException e) {
				// nothing
				assert (true); // Dummy code for "EmptyBlock" rule
			}
			result = anno;
		}
		return result;
	}

	private Expression manageValuePairClassKind(final IMemberValuePair defaultValue) {
		Expression result;
		if (defaultValue.getValue().getClass().isArray()) {
			Object[] tab = (Object[]) defaultValue.getValue();
			ArrayInitializer array = getFactory().createArrayInitializer();
			initializeNode(array);
			for (Object element : tab) {
				// the type is not a signature, we have to create one
				String typeName = element.toString();
				String typeSignature = Signature.createTypeSignature(typeName, true);
				TypeLiteral literal = getFactory().createTypeLiteral();
				literal.setType(getRefOnType(typeSignature));
				array.getExpressions().add(literal);
			}
			result = array;
		} else {
			// the type is not a signature, we have to create one
			String typeName = defaultValue.getValue().toString();
			String typeSignature = Signature.createTypeSignature(typeName, true);
			TypeLiteral literal = getFactory().createTypeLiteral();
			literal.setType(getRefOnType(typeSignature));
			result = literal;
		}
		return result;
	}

	protected void visitTypeParameter(final ITypeParameter typeParameter,
			final TypeParameter element) throws JavaModelException {
		initializeNode(element);
		element.setName(typeParameter.getElementName());

		String[] boundsNames = typeParameter.getBounds();

		for (String bound : boundsNames) {
			// bound names are not signatures
			String boundSignature = Signature.createTypeSignature(bound, true);
			if (!ClassFileParserUtils.isJavaLangObject(boundSignature)) {
				element.getBounds().add(getRefOnType(boundSignature));
			}
		}

		ClassFileParserUtils.manageBindingDeclaration(element, typeParameter, this);
	}

	/**
	 * Handle a reference on a type.
	 * <p>
	 * Decodes the signature and tries to resolve immediately the reference. If
	 * unresolvable, a pending reference is created.
	 * </p>
	 * So, the returned {@code TypeAccess} may or may not have a resolved
	 * {@link TypeAccess#getType() type}.
	 *
	 * @param qualifiedName
	 *            the signature of the referenced type (eg : [I,
	 *            Ljava.lang.Object;)
	 * @return a {@code TypeAccess}
	 */
	private TypeAccess getRefOnType(final String qualifiedName) {

		TypeAccess typAcc = getFactory().createTypeAccess();

		switch (Signature.getTypeSignatureKind(qualifiedName)) {
		case Signature.ARRAY_TYPE_SIGNATURE:
			visitArrayType(typAcc, qualifiedName, this);
			break;

		case Signature.BASE_TYPE_SIGNATURE:
			visitPrimitiveType(typAcc, qualifiedName);
			break;

		case Signature.CLASS_TYPE_SIGNATURE:
			// a class type signature can be simple or parameterized
			if (Signature.getTypeArguments(qualifiedName).length > 0) {
				visitParameterizedType(typAcc, qualifiedName); // Ljava.util.List<Ljava.lang.String;>;
			} else {
				ClassFileParserUtils.manageBindingRef(typAcc, qualifiedName, this); // Ljava.util.List;
			}
			break;

		case Signature.WILDCARD_TYPE_SIGNATURE:
			visitWildCardType(typAcc, qualifiedName);
			break;

		case Signature.TYPE_VARIABLE_SIGNATURE:
			ClassFileParserUtils.manageBindingRef(typAcc, qualifiedName, this);
			break;

		case Signature.CAPTURE_TYPE_SIGNATURE:
			ClassFileParserUtils.manageBindingRef(typAcc,
					JavaModelDelegateBindingFactory.JAVA_LANG_OBJECT_SIGNATURE, this);
			break;

		default:
			// nothing
		}
		return typAcc;
	}

	protected void visitParameterizedType(final TypeAccess type, final String qualifiedName) {
		Binding id = JavaModelDelegateBindingFactory.getInstance().getBindingForParameterizedType(
				qualifiedName, this, false);
		ParameterizedType parameterizedType = (ParameterizedType) getGlobalBindings().getTarget(id);
		if (parameterizedType == null) {
			parameterizedType = getFactory().createParameterizedType();
			parameterizedType.setName(id.toString());

			parameterizedType.setType(getRefOnType(Signature.getTypeErasure(qualifiedName)));

			String[] typeArgumentsSignatures = Signature.getTypeArguments(qualifiedName);
			for (String typeArgumentsSignature : typeArgumentsSignatures) {
				parameterizedType.getTypeArguments().add(getRefOnType(typeArgumentsSignature));
			}
			this.model.getOrphanTypes().add(parameterizedType);
			getGlobalBindings().addTarget(id, parameterizedType);
		}
		type.setType(parameterizedType);
	}

	protected void visitWildCardType(final TypeAccess type, final String qualifiedName) {
		Binding id = JavaModelDelegateBindingFactory.getInstance().getBindingForWildCardType(
				qualifiedName, this);
		WildCardType wildCardType = (WildCardType) getGlobalBindings().getTarget(id);
		if (wildCardType == null) {
			wildCardType = getFactory().createWildCardType();

			boolean isUpperBound = false;
			String boundSignature = null;

			switch (qualifiedName.charAt(0)) {
			case Signature.C_EXTENDS:
				isUpperBound = true;
				break;
			case Signature.C_SUPER:
				boundSignature = qualifiedName.substring(1); // remove the first
																// character
				break;
			case Signature.C_STAR:
				break;
			default:
				break;
			}
			if (boundSignature != null) {
				wildCardType.setBound(getRefOnType(boundSignature));
			}
			wildCardType.setUpperBound(isUpperBound);
			wildCardType.setName(id.toString());

			this.model.getOrphanTypes().add(wildCardType);
			getGlobalBindings().addTarget(id, wildCardType);
		}
		type.setType(wildCardType);
	}

	/**
	 * @see JDTVisitorUtils#manageBindingRef(org.eclipse.jdt.core.dom.PrimitiveType,
	 *      JDTVisitor)
	 */
	protected void visitPrimitiveType(final TypeAccess type, final String qualifiedName) {
		Binding id = JavaModelDelegateBindingFactory
				.getBindingForPrimitiveType(qualifiedName, this);
		PrimitiveType primitiveType = (PrimitiveType) getGlobalBindings().getTarget(id.toString());
		if (primitiveType == null) {
			ClassFileParserUtils.initializePrimitiveTypes(getFactory(), this.model,
					getGlobalBindings());
			primitiveType = (PrimitiveType) getGlobalBindings().getTarget(id.toString());
		}
		if (primitiveType == null) { // should never happen
			primitiveType = getFactory().createPrimitiveType();
			primitiveType.setName(id.toString());
			this.model.getOrphanTypes().add(primitiveType);
			getGlobalBindings().addTarget(id, primitiveType);

		}
		type.setType(primitiveType);
	}

	/**
	 * @see JDTVisitorUtils#manageBindingRef(org.eclipse.jdt.core.dom.ArrayType,
	 *      JDTVisitor)
	 */
	protected void visitArrayType(final TypeAccess typAcc, final String qualifiedName,
			final ClassFileParser visitor) {
		Binding id = JavaModelDelegateBindingFactory.getInstance().getBindingForArrayType(
				qualifiedName, visitor, false);
		ArrayType arrayType = (ArrayType) getGlobalBindings().getTarget(id.toString());
		if (arrayType == null) {
			arrayType = getFactory().createArrayType();
			arrayType.setDimensions(Signature.getArrayCount(qualifiedName));
			arrayType.setName(id.toString());

			arrayType.setElementType(getRefOnType(Signature.getElementType(qualifiedName)));

			this.model.getOrphanTypes().add(arrayType);
			getGlobalBindings().addTarget(id, arrayType);
		}
		typAcc.setType(arrayType);
	}

	/**
	 * Complete the MoDisco modifier with the informations of the flags.
	 *
	 * @param flags
	 *            the flags
	 * @param modiscoModifier
	 *            the MoDisco Modifier
	 * @see Flags
	 */
	private static void manageModifier(final Modifier modiscoModifier, final int flags,
			final IJavaElement element) {
		int kind = element.getElementType();
		// static is applicable on types, methods, fields, and initializers.
		if (!modiscoModifier.isStatic()) {
			if (kind == IJavaElement.TYPE || kind == IJavaElement.METHOD
					|| kind == IJavaElement.FIELD) {
				modiscoModifier.setStatic(Flags.isStatic(flags));
			}
		}
		// native is applicable to methods
		if (!modiscoModifier.isNative()) {
			if (kind == IJavaElement.METHOD) {
				modiscoModifier.setNative(Flags.isNative(flags));
			}
		}
		// strictfp is applicable to types and methods
		if (!modiscoModifier.isStrictfp()) {
			if (kind == IJavaElement.TYPE || kind == IJavaElement.METHOD) {
				modiscoModifier.setStrictfp(Flags.isStrictfp(flags));
			}
		}
		// synchronized is applicable only to methods
		if (!modiscoModifier.isSynchronized()) {
			if (kind == IJavaElement.METHOD) {
				modiscoModifier.setSynchronized(Flags.isSynchronized(flags));
			}
		}
		// transient is applicable only to fields
		if (!modiscoModifier.isTransient()) {
			if (kind == IJavaElement.FIELD) {
				modiscoModifier.setTransient(Flags.isTransient(flags));
			}
		}
		// volatile is applicable only to fields
		if (!modiscoModifier.isVolatile()) {
			if (kind == IJavaElement.FIELD) {
				modiscoModifier.setVolatile(Flags.isVolatile(flags));
			}
		}

		// visibility modifiers are applicable to types, methods, constructors,
		// and fields.
		if (kind == IJavaElement.TYPE || kind == IJavaElement.METHOD || kind == IJavaElement.FIELD) {
			if (Flags.isPrivate(flags)) {
				modiscoModifier.setVisibility(VisibilityKind.PRIVATE);
			} else if (Flags.isProtected(flags)) {
				modiscoModifier.setVisibility(VisibilityKind.PROTECTED);
			} else if (Flags.isPublic(flags)) {
				modiscoModifier.setVisibility(VisibilityKind.PUBLIC);
			}
		}

		// abstract is applicable to types and methods
		// final is applicable to types, methods and variables
		if (kind == IJavaElement.TYPE || kind == IJavaElement.METHOD) {
			if (Flags.isAbstract(flags)) {
				modiscoModifier.setInheritance(InheritanceKind.ABSTRACT);
			} else if (Flags.isFinal(flags)) {
				modiscoModifier.setInheritance(InheritanceKind.FINAL);
			}
		}
	}

	public void setFactory(final JavaFactory factory) {
		this.factory = factory;
	}

	public JavaFactory getFactory() {
		return this.factory;
	}

	public void setGlobalBindings(final BindingManager globalBindings) {
		this.globalBindings = globalBindings;
	}

	public BindingManager getGlobalBindings() {
		return this.globalBindings;
	}

}
