/*******************************************************************************
 * Copyright (c) 2000, 2010 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.jdt.internal.compiler.ast;

import java.util.Stack;

import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.internal.compiler.ASTVisitor;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
import org.eclipse.jdt.internal.compiler.impl.Constant;
import org.eclipse.jdt.internal.compiler.impl.IrritantSet;
import org.eclipse.jdt.internal.compiler.lookup.*;

/**
 * Annotation
 */
public abstract class Annotation extends Expression {

	/**
	 * Return the location for the corresponding annotation inside the type reference, <code>null</code> if none.
	 */
	public static int[] getLocations(
			final TypeReference reference,
			final Annotation[] primaryAnnotation,
			final Annotation annotation,
			final Annotation[][] annotationsOnDimensionsOnExpression) {
		class LocationCollector extends ASTVisitor {
			Stack currentIndexes;
			Annotation currentAnnotation;
			boolean search = true;
			
			public LocationCollector(Annotation currentAnnotation) {
				this.currentIndexes = new Stack();
				this.currentAnnotation = currentAnnotation;
			}
			public boolean visit(ArrayTypeReference typeReference, BlockScope scope) {
				if (!this.search) return false;
				Annotation[][] annotationsOnDimensions = typeReference.annotationsOnDimensions;
				if (annotationsOnDimensions != null) {
					// check if the annotation is located on the first dimension
					Annotation[] annotations = annotationsOnDimensions[0];
					if (annotations != null) {
						for (int j = 0, max2 = annotations.length; j < max2; j++) {
							Annotation current = annotations[j];
							if (current == this.currentAnnotation) {
								this.search = false;
								return false;
							}
						}
					}

					this.currentIndexes.push(new Integer(0));
					for (int i = 1, max = annotationsOnDimensions.length; i < max; i++) {
						annotations = annotationsOnDimensions[i];
						if (annotations != null) {
							for (int j = 0, max2 = annotations.length; j < max2; j++) {
								Annotation current = annotations[j];
								if (current == this.currentAnnotation) {
									this.search = false;
									return false;
								}
							}
						}
						this.currentIndexes.push(new Integer(((Integer) this.currentIndexes.pop()).intValue() + 1));
					}
				}
				Annotation[] annotations = typeReference.annotations;
				if (annotations == null) {
					annotations = primaryAnnotation;
				}
				if (annotations != null) {
					for (int i = 0; i < annotations.length; i++) {
						Annotation current = annotations[i];
						if (current == this.currentAnnotation) {
							this.search = false;
							return false;
						}
					}
				}
				this.currentIndexes.pop();
				return true;
			}
			public boolean visit(ArrayQualifiedTypeReference typeReference, BlockScope scope) {
				if (!this.search) return false;
				Annotation[][] annotationsOnDimensions = typeReference.annotationsOnDimensions;
				if (annotationsOnDimensions != null) {
					// check if the annotation is located on the first dimension
					Annotation[] annotations = annotationsOnDimensions[0];
					if (annotations != null) {
						for (int j = 0, max2 = annotations.length; j < max2; j++) {
							Annotation current = annotations[j];
							if (current == this.currentAnnotation) {
								this.search = false;
								return false;
							}
						}
					}

					this.currentIndexes.push(new Integer(0));
					for (int i = 1, max = annotationsOnDimensions.length; i < max; i++) {
						annotations = annotationsOnDimensions[i];
						if (annotations != null) {
							for (int j = 0, max2 = annotations.length; j < max2; j++) {
								Annotation current = annotations[j];
								if (current == this.currentAnnotation) {
									this.search = false;
									return false;
								}
							}
						}
						this.currentIndexes.push(new Integer(((Integer) this.currentIndexes.pop()).intValue() + 1));
					}
				}
				Annotation[] annotations = typeReference.annotations;
				if (annotations == null) {
					annotations = primaryAnnotation;
				}
				if (annotations != null) {
					for (int i = 0; i < annotations.length; i++) {
						Annotation current = annotations[i];
						if (current == this.currentAnnotation) {
							this.search = false;
							return false;
						}
					}
				}
				this.currentIndexes.pop();
				return true;
			}
			public boolean visit(ParameterizedSingleTypeReference typeReference, BlockScope scope) {
				if (!this.search) return false;
				Annotation[][] annotationsOnDimensions = typeReference.annotationsOnDimensions;
				if (annotationsOnDimensions != null) {
					// check if the annotation is located on the first dimension
					Annotation[] annotations = annotationsOnDimensions[0];
					if (annotations != null) {
						for (int j = 0, max2 = annotations.length; j < max2; j++) {
							Annotation current = annotations[j];
							if (current == this.currentAnnotation) {
								this.search = false;
								return false;
							}
						}
					}

					this.currentIndexes.push(new Integer(0));
					for (int i = 1, max = annotationsOnDimensions.length; i < max; i++) {
						annotations = annotationsOnDimensions[i];
						if (annotations != null) {
							for (int j = 0, max2 = annotations.length; j < max2; j++) {
								Annotation current = annotations[j];
								if (current == this.currentAnnotation) {
									this.search = false;
									return false;
								}
							}
						}
						this.currentIndexes.push(new Integer(((Integer) this.currentIndexes.pop()).intValue() + 1));
					}
				}
				Annotation[] annotations = typeReference.annotations;
				if (annotations == null) {
					annotations = primaryAnnotation;
				}
				if (annotations != null) {
					for (int i = 0; i < annotations.length; i++) {
						Annotation current = annotations[i];
						if (current == this.currentAnnotation) {
							this.search = false;
							return false;
						}
					}
				}
				TypeReference[] typeReferences = typeReference.typeArguments;
				this.currentIndexes.push(new Integer(0));
				for (int i = 0, max = typeReferences.length; i < max; i++) {
					typeReferences[i].traverse(this, scope);
					if (!this.search) return false;
					this.currentIndexes.push(new Integer(((Integer) this.currentIndexes.pop()).intValue() + 1));
				}
				this.currentIndexes.pop();
				return true;
			}
			public boolean visit(ParameterizedQualifiedTypeReference typeReference, BlockScope scope) {
				if (!this.search) return false;
				Annotation[][] annotationsOnDimensions = typeReference.annotationsOnDimensions;
				if (annotationsOnDimensions != null) {
					// check if the annotation is located on the first dimension
					Annotation[] annotations = annotationsOnDimensions[0];
					if (annotations != null) {
						for (int j = 0, max2 = annotations.length; j < max2; j++) {
							Annotation current = annotations[j];
							if (current == this.currentAnnotation) {
								this.search = false;
								return false;
							}
						}
					}

					this.currentIndexes.push(new Integer(0));
					for (int i = 1, max = annotationsOnDimensions.length; i < max; i++) {
						annotations = annotationsOnDimensions[i];
						if (annotations != null) {
							for (int j = 0, max2 = annotations.length; j < max2; j++) {
								Annotation current = annotations[j];
								if (current == this.currentAnnotation) {
									this.search = false;
									return false;
								}
							}
						}
						this.currentIndexes.push(new Integer(((Integer) this.currentIndexes.pop()).intValue() + 1));
					}
				}
				Annotation[] annotations = typeReference.annotations;
				if (annotations == null) {
					annotations = primaryAnnotation;
				}
				if (annotations != null) {
					for (int i = 0; i < annotations.length; i++) {
						Annotation current = annotations[i];
						if (current == this.currentAnnotation) {
							this.search = false;
							return false;
						}
					}
				}
				//TODO it is unclear how to manage annotations located in the first type arguments
				TypeReference[] typeReferences = typeReference.typeArguments[typeReference.typeArguments.length - 1];
				this.currentIndexes.push(new Integer(0));
				for (int i = 0, max = typeReferences.length; i < max; i++) {
					typeReferences[i].traverse(this, scope);
					if (!this.search) return false;
					this.currentIndexes.push(new Integer(((Integer) this.currentIndexes.pop()).intValue() + 1));
				}
				this.currentIndexes.pop();
				return true;
			}
			public boolean visit(SingleTypeReference typeReference, BlockScope scope) {
				if (!this.search) return false;
				Annotation[][] annotationsOnDimensions = annotationsOnDimensionsOnExpression;
				if (annotationsOnDimensions != null) {
					// check if the annotation is located on the first dimension
					Annotation[] annotations = annotationsOnDimensions[0];
					if (annotations != null) {
						for (int j = 0, max2 = annotations.length; j < max2; j++) {
							Annotation current = annotations[j];
							if (current == this.currentAnnotation) {
								this.search = false;
								return false;
							}
						}
					}

					this.currentIndexes.push(new Integer(0));
					for (int i = 1, max = annotationsOnDimensions.length; i < max; i++) {
						annotations = annotationsOnDimensions[i];
						if (annotations != null) {
							for (int j = 0, max2 = annotations.length; j < max2; j++) {
								Annotation current = annotations[j];
								if (current == this.currentAnnotation) {
									this.search = false;
									return false;
								}
							}
						}
						this.currentIndexes.push(new Integer(((Integer) this.currentIndexes.pop()).intValue() + 1));
					}
				}
				Annotation[] annotations = typeReference.annotations;
				if (annotations != null) {
					for (int i = 0; i < annotations.length; i++) {
						Annotation current = annotations[i];
						if (current == this.currentAnnotation) {
							this.search = false;
							return false;
						}
					}
				}
				return false;
			}
			public boolean visit(Wildcard typeReference, BlockScope scope) {
				if (!this.search) return false;
				TypeReference bound = typeReference.bound;
				bound.traverse(this, scope);
				return true;
			}
			public boolean visit(QualifiedTypeReference typeReference, BlockScope scope) {
				if (!this.search) return false;
				Annotation[] annotations = typeReference.annotations;
				if (annotations != null) {
					for (int i = 0; i < annotations.length; i++) {
						Annotation current = annotations[i];
						if (current == this.currentAnnotation) {
							this.search = false;
							return false;
						}
					}
				}
				return true;
			}
			public String toString() {
				StringBuffer buffer = new StringBuffer();
				buffer
					.append("search location for ") //$NON-NLS-1$
					.append(this.currentAnnotation)
					.append("\ncurrent indexes : ") //$NON-NLS-1$
					.append(this.currentIndexes);
				return String.valueOf(buffer);
			}
		}
		if (reference == null) return null;
		LocationCollector collector = new LocationCollector(annotation);
		reference.traverse(collector, (BlockScope) null);
		if (collector.currentIndexes.isEmpty()) {
			return null;
		}
		int size = collector.currentIndexes.size();
		int[] result = new int[size];
		for (int i = 0; i < size; i++) {
			result[size - i - 1] = ((Integer) collector.currentIndexes.pop()).intValue();
		}
		return result;
	}
	// jsr 308
	public static class TypeUseBinding extends ReferenceBinding {
		private int kind;
		public TypeUseBinding(int kind) {
			this.tagBits = 0L;
			this.kind = kind;
		}
		public int kind() {
			return this.kind;
		}
	}

	final static MemberValuePair[] NoValuePairs = new MemberValuePair[0];
	public int declarationSourceEnd;
	public Binding recipient;

	public TypeReference type;
	/**
	 *  The representation of this annotation in the type system.
	 */
	private AnnotationBinding compilerAnnotation = null;

	public static long getRetentionPolicy(char[] policyName) {
		if (policyName == null || policyName.length == 0)
			return 0;
		switch(policyName[0]) {
			case 'C' :
				if (CharOperation.equals(policyName, TypeConstants.UPPER_CLASS))
					return TagBits.AnnotationClassRetention;
				break;
			case 'S' :
				if (CharOperation.equals(policyName, TypeConstants.UPPER_SOURCE))
					return TagBits.AnnotationSourceRetention;
				break;
			case 'R' :
				if (CharOperation.equals(policyName, TypeConstants.UPPER_RUNTIME))
					return TagBits.AnnotationRuntimeRetention;
				break;
		}
		return 0; // unknown
	}

	public static long getTargetElementType(char[] elementName) {
		if (elementName == null || elementName.length == 0)
			return 0;
		switch(elementName[0]) {
			case 'A' :
				if (CharOperation.equals(elementName, TypeConstants.UPPER_ANNOTATION_TYPE))
					return TagBits.AnnotationForAnnotationType;
				break;
			case 'C' :
				if (CharOperation.equals(elementName, TypeConstants.UPPER_CONSTRUCTOR))
					return TagBits.AnnotationForConstructor;
				break;
			case 'F' :
				if (CharOperation.equals(elementName, TypeConstants.UPPER_FIELD))
					return TagBits.AnnotationForField;
				break;
			case 'L' :
				if (CharOperation.equals(elementName, TypeConstants.UPPER_LOCAL_VARIABLE))
					return TagBits.AnnotationForLocalVariable;
				break;
			case 'M' :
				if (CharOperation.equals(elementName, TypeConstants.UPPER_METHOD))
					return TagBits.AnnotationForMethod;
				break;
			case 'P' :
				if (CharOperation.equals(elementName, TypeConstants.UPPER_PARAMETER))
					return TagBits.AnnotationForParameter;
				else if (CharOperation.equals(elementName, TypeConstants.UPPER_PACKAGE))
					return TagBits.AnnotationForPackage;
				break;
			case 'T' :
				if (CharOperation.equals(elementName, TypeConstants.TYPE))
					return TagBits.AnnotationForType;
				if (CharOperation.equals(elementName, TypeConstants.TYPE_USE_TARGET))
					return TagBits.AnnotationForTypeUse;
				if (CharOperation.equals(elementName, TypeConstants.TYPE_PARAMETER_TARGET))
					return TagBits.AnnotationForTypeParameter;
				break;
		}
		return 0; // unknown
	}

	public ElementValuePair[] computeElementValuePairs() {
		return Binding.NO_ELEMENT_VALUE_PAIRS;
	}

	/**
	 * Compute the bit pattern for recognized standard annotations the compiler may need to act upon
	 */
	private long detectStandardAnnotation(Scope scope, ReferenceBinding annotationType, MemberValuePair valueAttribute) {
		long tagBits = 0;
		switch (annotationType.id) {
			// retention annotation
			case TypeIds.T_JavaLangAnnotationRetention :
				if (valueAttribute != null) {
					Expression expr = valueAttribute.value;
					if ((expr.bits & Binding.VARIABLE) == Binding.FIELD) {
						FieldBinding field = ((Reference)expr).fieldBinding();
						if (field != null && field.declaringClass.id == T_JavaLangAnnotationRetentionPolicy) {
							tagBits |= getRetentionPolicy(field.name);
						}
					}
				}
				break;
			// target annotation
			case TypeIds.T_JavaLangAnnotationTarget :
				tagBits |= TagBits.AnnotationTarget; // target specified (could be empty)
				if (valueAttribute != null) {
					Expression expr = valueAttribute.value;
					if (expr instanceof ArrayInitializer) {
						ArrayInitializer initializer = (ArrayInitializer) expr;
						final Expression[] expressions = initializer.expressions;
						if (expressions != null) {
							for (int i = 0, length = expressions.length; i < length; i++) {
								Expression initExpr = expressions[i];
								if ((initExpr.bits & Binding.VARIABLE) == Binding.FIELD) {
									FieldBinding field = ((Reference) initExpr).fieldBinding();
									if (field != null && field.declaringClass.id == T_JavaLangAnnotationElementType) {
										long element = getTargetElementType(field.name);
										if ((tagBits & element) != 0) {
											scope.problemReporter().duplicateTargetInTargetAnnotation(annotationType, (NameReference)initExpr);
										} else {
											tagBits |= element;
										}
									}
								}
							}
						}
					} else if ((expr.bits & Binding.VARIABLE) == Binding.FIELD) {
						FieldBinding field = ((Reference) expr).fieldBinding();
						if (field != null && field.declaringClass.id == T_JavaLangAnnotationElementType) {
							tagBits |= getTargetElementType(field.name);
						}
					}
				}
				break;
			// marker annotations
			case TypeIds.T_JavaLangDeprecated :
				tagBits |= TagBits.AnnotationDeprecated;
				break;
			case TypeIds.T_JavaLangAnnotationDocumented :
				tagBits |= TagBits.AnnotationDocumented;
				break;
			case TypeIds.T_JavaLangAnnotationInherited :
				tagBits |= TagBits.AnnotationInherited;
				break;
			case TypeIds.T_JavaLangOverride :
				tagBits |= TagBits.AnnotationOverride;
				break;
			case TypeIds.T_JavaLangSuppressWarnings :
				tagBits |= TagBits.AnnotationSuppressWarnings;
				break;
		}
		return tagBits;
	}

	public AnnotationBinding getCompilerAnnotation() {
		return this.compilerAnnotation;
	}

	public boolean isRuntimeInvisible() {
		final TypeBinding annotationBinding = this.resolvedType;
		if (annotationBinding == null) {
			return false;
		}
		long metaTagBits = annotationBinding.getAnnotationTagBits(); // could be forward reference
		// jsr 308
		// we need to filter out type use and type parameter annotations
		if ((metaTagBits & (TagBits.AnnotationForTypeParameter | TagBits.AnnotationForTypeUse)) != 0) {
			return false;
		}

		if ((metaTagBits & TagBits.AnnotationRetentionMASK) == 0)
			return true; // by default the retention is CLASS

		return (metaTagBits & TagBits.AnnotationRetentionMASK) == TagBits.AnnotationClassRetention;
	}

	public boolean isRuntimeTypeInvisible() {
		final TypeBinding annotationBinding = this.resolvedType;
		if (annotationBinding == null) {
			return false;
		}
		long metaTagBits = annotationBinding.getAnnotationTagBits(); // could be forward reference
		// jsr 308
		// we need to filter out type use and type parameter annotations
		if ((metaTagBits & (TagBits.AnnotationTargetMASK)) != 0
				&& ((metaTagBits & (TagBits.AnnotationForTypeParameter | TagBits.AnnotationForTypeUse)) == 0)) {
			return false;
		}

		if ((metaTagBits & TagBits.AnnotationRetentionMASK) == 0)
			return true; // by default the retention is CLASS

		return (metaTagBits & TagBits.AnnotationRetentionMASK) == TagBits.AnnotationClassRetention;
	}

	public boolean isRuntimeTypeVisible() {
		final TypeBinding annotationBinding = this.resolvedType;
		if (annotationBinding == null) {
			return false;
		}
		long metaTagBits = annotationBinding.getAnnotationTagBits();
		if ((metaTagBits & (TagBits.AnnotationTargetMASK)) != 0
				&& ((metaTagBits & (TagBits.AnnotationForTypeParameter | TagBits.AnnotationForTypeUse)) == 0)) {
			return false;
		}
		if ((metaTagBits & TagBits.AnnotationRetentionMASK) == 0)
			return false; // by default the retention is CLASS

		return (metaTagBits & TagBits.AnnotationRetentionMASK) == TagBits.AnnotationRuntimeRetention;
	}

	public boolean isRuntimeVisible() {
		final TypeBinding annotationBinding = this.resolvedType;
		if (annotationBinding == null) {
			return false;
		}
		long metaTagBits = annotationBinding.getAnnotationTagBits();
		if ((metaTagBits & (TagBits.AnnotationForTypeParameter | TagBits.AnnotationForTypeUse)) != 0) {
			return false;
		}
		if ((metaTagBits & TagBits.AnnotationRetentionMASK) == 0)
			return false; // by default the retention is CLASS

		return (metaTagBits & TagBits.AnnotationRetentionMASK) == TagBits.AnnotationRuntimeRetention;
	}

	public abstract MemberValuePair[] memberValuePairs();

	public StringBuffer printExpression(int indent, StringBuffer output) {
		output.append('@');
		this.type.printExpression(0, output);
		return output;
	}

	public void recordSuppressWarnings(Scope scope, int startSuppresss, int endSuppress, boolean isSuppressingWarnings) {
		IrritantSet suppressWarningIrritants = null;
		MemberValuePair[] pairs = memberValuePairs();
		pairLoop: for (int i = 0, length = pairs.length; i < length; i++) {
			MemberValuePair pair = pairs[i];
			if (CharOperation.equals(pair.name, TypeConstants.VALUE)) {
				Expression value = pair.value;
				if (value instanceof ArrayInitializer) {
					ArrayInitializer initializer = (ArrayInitializer) value;
					Expression[] inits = initializer.expressions;
					if (inits != null) {
						for (int j = 0, initsLength = inits.length; j < initsLength; j++) {
							Constant cst = inits[j].constant;
							if (cst != Constant.NotAConstant && cst.typeID() == T_JavaLangString) {
								IrritantSet irritants = CompilerOptions.warningTokenToIrritants(cst.stringValue());
								if (irritants != null) {
									if (suppressWarningIrritants == null) {
										suppressWarningIrritants = new IrritantSet(irritants);
									} else if (suppressWarningIrritants.set(irritants) == null) {
											scope.problemReporter().unusedWarningToken(inits[j]);
									}
								} else {
									scope.problemReporter().unhandledWarningToken(inits[j]);
								}
							}
						}
					}
				} else {
					Constant cst = value.constant;
					if (cst != Constant.NotAConstant && cst.typeID() == T_JavaLangString) {
						IrritantSet irritants = CompilerOptions.warningTokenToIrritants(cst.stringValue());
						if (irritants != null) {
							suppressWarningIrritants = new IrritantSet(irritants);
							// TODO: should check for unused warning token against enclosing annotation as well ?
						} else {
							scope.problemReporter().unhandledWarningToken(value);
						}
					}
				}
				break pairLoop;
			}
		}
		if (isSuppressingWarnings && suppressWarningIrritants != null) {
			scope.referenceCompilationUnit().recordSuppressWarnings(suppressWarningIrritants, this, startSuppresss, endSuppress);
		}
	}

	public TypeBinding resolveType(BlockScope scope) {

		if (this.compilerAnnotation != null)
			return this.resolvedType;
		this.constant = Constant.NotAConstant;

		TypeBinding typeBinding = this.type.resolveType(scope);
		if (typeBinding == null) {
			return null;
		}
		this.resolvedType = typeBinding;
		// ensure type refers to an annotation type
		if (!typeBinding.isAnnotationType() && typeBinding.isValidBinding()) {
			scope.problemReporter().typeMismatchError(typeBinding, scope.getJavaLangAnnotationAnnotation(), this.type, null);
			return null;
		}
		ReferenceBinding annotationType = (ReferenceBinding) this.resolvedType;
		MethodBinding[] methods = annotationType.methods();
		// clone valuePairs to keep track of unused ones
		MemberValuePair[] originalValuePairs = memberValuePairs();
		MemberValuePair valueAttribute = null; // remember the first 'value' pair
		MemberValuePair[] pairs;
		int pairsLength = originalValuePairs.length;
		if (pairsLength > 0) {
			System.arraycopy(originalValuePairs, 0, pairs = new MemberValuePair[pairsLength], 0, pairsLength);
		} else {
			pairs = originalValuePairs;
		}

		nextMember: for (int i = 0, requiredLength = methods.length; i < requiredLength; i++) {
			MethodBinding method = methods[i];
			char[] selector = method.selector;
			boolean foundValue = false;
			nextPair: for (int j = 0; j < pairsLength; j++) {
				MemberValuePair pair = pairs[j];
				if (pair == null) continue nextPair;
				char[] name = pair.name;
				if (CharOperation.equals(name, selector)) {
					if (valueAttribute == null && CharOperation.equals(name, TypeConstants.VALUE)) {
						valueAttribute = pair;
					}
					pair.binding = method;
					pair.resolveTypeExpecting(scope, method.returnType);
					pairs[j] = null; // consumed
					foundValue = true;

					// check duplicates
					boolean foundDuplicate = false;
					for (int k = j+1; k < pairsLength; k++) {
						MemberValuePair otherPair = pairs[k];
						if (otherPair == null) continue;
						if (CharOperation.equals(otherPair.name, selector)) {
							foundDuplicate = true;
							scope.problemReporter().duplicateAnnotationValue(annotationType, otherPair);
							otherPair.binding = method;
							otherPair.resolveTypeExpecting(scope, method.returnType);
							pairs[k] = null;
						}
					}
					if (foundDuplicate) {
						scope.problemReporter().duplicateAnnotationValue(annotationType, pair);
						continue nextMember;
					}
				}
			}
			if (!foundValue
					&& (method.modifiers & ClassFileConstants.AccAnnotationDefault) == 0
					&& (this.bits & IsRecovered) == 0
					&& annotationType.isValidBinding()) {
				scope.problemReporter().missingValueForAnnotationMember(this, selector);
			}
		}
		// check unused pairs
		for (int i = 0; i < pairsLength; i++) {
			if (pairs[i] != null) {
				if (annotationType.isValidBinding()) {
					scope.problemReporter().undefinedAnnotationValue(annotationType, pairs[i]);
				}
				pairs[i].resolveTypeExpecting(scope, null); // resilient
			}
		}
//		if (scope.compilerOptions().storeAnnotations)
		this.compilerAnnotation = scope.environment().createAnnotation((ReferenceBinding) this.resolvedType, computeElementValuePairs());
		// recognize standard annotations ?
		long tagBits = detectStandardAnnotation(scope, annotationType, valueAttribute);

		// record annotation positions in the compilation result
		scope.referenceCompilationUnit().recordSuppressWarnings(IrritantSet.NLS, null, this.sourceStart, this.declarationSourceEnd);
		if (this.recipient != null) {
			if (tagBits != 0) {
				// tag bits onto recipient
				switch (this.recipient.kind()) {
					case Binding.PACKAGE :
						((PackageBinding)this.recipient).tagBits |= tagBits;
						break;
					case Binding.TYPE :
					case Binding.GENERIC_TYPE :
						SourceTypeBinding sourceType = (SourceTypeBinding) this.recipient;
						sourceType.tagBits |= tagBits;
						if ((tagBits & TagBits.AnnotationSuppressWarnings) != 0) {
							TypeDeclaration typeDeclaration =  sourceType.scope.referenceContext;
							int start;
							if (scope.referenceCompilationUnit().types[0] == typeDeclaration) {
								start = 0;
							} else {
								start = typeDeclaration.declarationSourceStart;
							}
							recordSuppressWarnings(scope, start, typeDeclaration.declarationSourceEnd, scope.compilerOptions().suppressWarnings);
						}
						break;
					case Binding.METHOD :
						MethodBinding sourceMethod = (MethodBinding) this.recipient;
						sourceMethod.tagBits |= tagBits;
						if ((tagBits & TagBits.AnnotationSuppressWarnings) != 0) {
							sourceType = (SourceTypeBinding) sourceMethod.declaringClass;
							AbstractMethodDeclaration methodDeclaration = sourceType.scope.referenceContext.declarationOf(sourceMethod);
							recordSuppressWarnings(scope, methodDeclaration.declarationSourceStart, methodDeclaration.declarationSourceEnd, scope.compilerOptions().suppressWarnings);
						}
						break;
					case Binding.FIELD :
						FieldBinding sourceField = (FieldBinding) this.recipient;
						sourceField.tagBits |= tagBits;
						if ((tagBits & TagBits.AnnotationSuppressWarnings) != 0) {
							sourceType = (SourceTypeBinding) sourceField.declaringClass;
							FieldDeclaration fieldDeclaration = sourceType.scope.referenceContext.declarationOf(sourceField);
							recordSuppressWarnings(scope, fieldDeclaration.declarationSourceStart, fieldDeclaration.declarationSourceEnd, scope.compilerOptions().suppressWarnings);
						}
						break;
					case Binding.LOCAL :
						LocalVariableBinding variable = (LocalVariableBinding) this.recipient;
						variable.tagBits |= tagBits;
						if ((tagBits & TagBits.AnnotationSuppressWarnings) != 0) {
							 LocalDeclaration localDeclaration = variable.declaration;
							recordSuppressWarnings(scope, localDeclaration.declarationSourceStart, localDeclaration.declarationSourceEnd, scope.compilerOptions().suppressWarnings);
						}
						break;
				}
			}
			// check (meta)target compatibility
			checkTargetCompatibility: {
				if (!annotationType.isValidBinding()) {
					// no need to check annotation usage if missing
					break checkTargetCompatibility;
				}

				long metaTagBits = annotationType.getAnnotationTagBits(); // could be forward reference
				if ((metaTagBits & TagBits.AnnotationTargetMASK) == 0) {
					// does not specify any target restriction - all locations are possible including type annotations
					break checkTargetCompatibility;
				}

				switch (this.recipient.kind()) {
					case Binding.PACKAGE :
						if ((metaTagBits & TagBits.AnnotationForPackage) != 0)
							break checkTargetCompatibility;
						break;
					case Binding.TYPE_USE :
						if ((metaTagBits & TagBits.AnnotationForTypeUse) != 0) {
							// jsr 308
							break checkTargetCompatibility;
						}
						break;
					case Binding.TYPE :
					case Binding.GENERIC_TYPE :
						if (((ReferenceBinding)this.recipient).isAnnotationType()) {
							if ((metaTagBits & (TagBits.AnnotationForAnnotationType | TagBits.AnnotationForType)) != 0)
							break checkTargetCompatibility;
						} else if ((metaTagBits & TagBits.AnnotationForType) != 0) {
							break checkTargetCompatibility;
						} else if ((metaTagBits & TagBits.AnnotationForPackage) != 0) {
							if (CharOperation.equals(((ReferenceBinding)this.recipient).sourceName, TypeConstants.PACKAGE_INFO_NAME))
								break checkTargetCompatibility;
						}
						break;
					case Binding.METHOD :
						MethodBinding methodBinding = (MethodBinding) this.recipient;
						if (methodBinding.isConstructor()) {
							if ((metaTagBits & TagBits.AnnotationForConstructor) != 0)
								break checkTargetCompatibility;
						} else if ((metaTagBits & TagBits.AnnotationForMethod) != 0) {
							break checkTargetCompatibility;
						} else if ((metaTagBits & TagBits.AnnotationForTypeUse) != 0) {
							// jsr 308 - annotation on method return type
							if (methodBinding.returnType != null && methodBinding.returnType.id == T_void) {
								scope.problemReporter().illegalUsageOfTypeAnnotations(this);
							}
							break checkTargetCompatibility;
						}
						break;
					case Binding.FIELD :
						if ((metaTagBits & TagBits.AnnotationForField) != 0) {
							break checkTargetCompatibility;
						} else if ((metaTagBits & TagBits.AnnotationForTypeUse) != 0) {
							// jsr 308 - annotation on field type
							break checkTargetCompatibility;
						}
						break;
					case Binding.LOCAL :
						if ((((LocalVariableBinding)this.recipient).tagBits & TagBits.IsArgument) != 0) {
							if ((metaTagBits & TagBits.AnnotationForParameter) != 0) {
								break checkTargetCompatibility;
							} else if ((metaTagBits & TagBits.AnnotationForTypeUse) != 0) {
								// jsr 308 - annotation on method parameter type
								break checkTargetCompatibility;
							}
						} else if ((annotationType.tagBits & TagBits.AnnotationForLocalVariable) != 0) {
							break checkTargetCompatibility;
						} else if ((metaTagBits & TagBits.AnnotationForTypeUse) != 0) {
							// jsr 308 - annotation on local type
							break checkTargetCompatibility;
						}
						break;
					case Binding.TYPE_PARAMETER : // jsr308
						if ((metaTagBits & TagBits.AnnotationForTypeParameter) != 0) {
							break checkTargetCompatibility;
						}
					}
				scope.problemReporter().disallowedTargetForAnnotation(this);
			}
		}
		return this.resolvedType;
	}

	public abstract void traverse(ASTVisitor visitor, BlockScope scope);

	public abstract void traverse(ASTVisitor visitor, ClassScope scope);
}
