/*******************************************************************************
 * Copyright (c) 2013, 2019 GoPivotal, Inc.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *		Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for
 *			Bug 407191 - [1.8] Binary access support for type annotations
 *******************************************************************************/
package org.eclipse.jdt.core.tests.compiler.regression;

import junit.framework.Test;

import java.io.File;

import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
import org.eclipse.jdt.internal.compiler.codegen.AnnotationTargetTypeConstants;
import org.eclipse.jdt.internal.compiler.env.IBinaryAnnotation;
import org.eclipse.jdt.internal.compiler.env.IBinaryElementValuePair;
import org.eclipse.jdt.internal.compiler.env.IBinaryField;
import org.eclipse.jdt.internal.compiler.env.IBinaryMethod;
import org.eclipse.jdt.internal.compiler.env.IBinaryTypeAnnotation;

@SuppressWarnings({ "rawtypes" })
public class ClassFileReaderTest_1_8 extends AbstractRegressionTest {
	static {
	}

	public static Test suite() {
		return buildMinimalComplianceTestSuite(testClass(), F_1_8);
	}
	public static Class testClass() {
		return ClassFileReaderTest_1_8.class;
	}

	public ClassFileReaderTest_1_8(String name) {
		super(name);
	}
	
	// Needed to run tests individually from JUnit
	protected void setUp() throws Exception {
		super.setUp();
		this.complianceLevel = ClassFileConstants.JDK1_8;
	}
	
	public void test001_classTypeParameter() throws Exception {
		String source =
			"import java.lang.annotation.*;\n" +
			"public class X<@Foo T1,@Bar(iii=99) T2> {}\n" +
			"@Retention(RetentionPolicy.CLASS)\n" +
			"@Target(ElementType.TYPE_USE)\n" +
			"@interface Foo {\n" +
			"}\n" +
			"@Retention(RetentionPolicy.CLASS)\n" +
			"@Target(ElementType.TYPE_USE)\n" +
			"@interface Bar {\n" +
			"        int iii() default -1;\n" +
			"}";

		org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader classFileReader = getInternalClassFile("", "X", "X", source);
		
		IBinaryTypeAnnotation[] typeAnnotations = classFileReader.getTypeAnnotations();
		assertEquals(2,typeAnnotations.length);
		
		assertEquals("@LFoo; CLASS_TYPE_PARAMETER(type_parameter_index=0)", printTypeAnnotation(typeAnnotations[0]));
		assertEquals("@LBar;(iii=(int)99) CLASS_TYPE_PARAMETER(type_parameter_index=1)", printTypeAnnotation(typeAnnotations[1]));
	}
	
	public void test001a_classTypeParameterDifferingRetentions() throws Exception {
		String source =
			"import java.lang.annotation.*;\n" +
			"public class X<@Foo T1,@Bar(iii=99) T2> {}\n" +
			"@Retention(RetentionPolicy.RUNTIME)\n" +
			"@Target(ElementType.TYPE_USE)\n" +
			"@interface Foo {\n" +
			"}\n" +
			"@Retention(RetentionPolicy.CLASS)\n" +
			"@Target(ElementType.TYPE_USE)\n" +
			"@interface Bar {\n" +
			"        int iii() default -1;\n" +
			"}";

		org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader classFileReader = getInternalClassFile("", "X", "X", source);
		
		IBinaryTypeAnnotation[] typeAnnotations = classFileReader.getTypeAnnotations();
		assertEquals(2,typeAnnotations.length);
		
		assertEquals("@LBar;(iii=(int)99) CLASS_TYPE_PARAMETER(type_parameter_index=1)", printTypeAnnotation(typeAnnotations[0]));
		assertEquals("@LFoo; CLASS_TYPE_PARAMETER(type_parameter_index=0)", printTypeAnnotation(typeAnnotations[1]));
	}
	
	public void test002_methodTypeParameter() throws Exception {
		String source =
			"import java.lang.annotation.*;\n" +
			"public class X {\n" +
			"	<@Foo T1, @Bar(3) T2> void foo(T1 t1,T2 t2) {}\n" + 
			"}\n" +
			"@Retention(RetentionPolicy.CLASS)\n" +
			"@Target(ElementType.TYPE_USE)\n" +
			"@interface Foo {\n" +
			"}\n" +
			"@Retention(RetentionPolicy.CLASS)\n" +
			"@Target(ElementType.TYPE_USE)\n" +
			"@interface Bar {\n" +
			"        int value() default -1;\n" +
			"}";

		org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader cfr = getInternalClassFile("", "X", "X", source);
		
		IBinaryMethod method = getMethod(cfr,"foo");
		assertNotNull(method);
		IBinaryTypeAnnotation[] typeAnnotations = method.getTypeAnnotations();
		assertNotNull(typeAnnotations);
		assertEquals(2,typeAnnotations.length);
		assertEquals("@LFoo; METHOD_TYPE_PARAMETER(type_parameter_index=0)",printTypeAnnotation(typeAnnotations[0]));
		assertEquals("@LBar;(value=(int)3) METHOD_TYPE_PARAMETER(type_parameter_index=1)",printTypeAnnotation(typeAnnotations[1]));
	}
	
	public void test003_classExtends() throws Exception {
		this.complianceLevel = ClassFileConstants.JDK1_8;
		String source =
			"import java.lang.annotation.*;\n" +
			"public class X extends @Foo @Bar(iii=34) Object implements java.io.@Bar(iii=1) Serializable {\n" +
			"}\n" +
			"@Retention(RetentionPolicy.CLASS)\n" +
			"@Target(ElementType.TYPE_USE)\n" +
			"@interface Foo {\n" +
			"}\n" +
			"@Retention(RetentionPolicy.CLASS)\n" +
			"@Target(ElementType.TYPE_USE)\n" +
			"@interface Bar {\n" +
			"        int iii() default -1;\n" +
			"}";

		org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader classFileReader = getInternalClassFile("", "X", "X", source);
		
		IBinaryTypeAnnotation[] typeAnnotations = classFileReader.getTypeAnnotations();
		assertEquals(3,typeAnnotations.length);
		assertEquals("@LFoo; CLASS_EXTENDS(type_index=-1)", printTypeAnnotation(typeAnnotations[0]));
		assertEquals("@LBar;(iii=(int)34) CLASS_EXTENDS(type_index=-1)", printTypeAnnotation(typeAnnotations[1]));
		assertEquals("@LBar;(iii=(int)1) CLASS_EXTENDS(type_index=0)", printTypeAnnotation(typeAnnotations[2]));
	}

	public void test004_classExtends() throws Exception {
		String source =
			"import java.lang.annotation.*;\n" +
			"public class X extends Y<@Foo String,@Bar Integer> implements I<@Foo String> {\n" +
			"}\n" +
			"class Y<T1, T2> {}\n" +
			"interface I<T1> {}\n" +
			"@Retention(RetentionPolicy.CLASS)\n" +
			"@Target(ElementType.TYPE_USE)\n" +
			"@interface Foo {\n" +
			"}\n" +
			"@Retention(RetentionPolicy.CLASS)\n" +
			"@Target(ElementType.TYPE_USE)\n" +
			"@interface Bar {\n" +
			"        int iii() default -1;\n" +
			"}";

		org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader classFileReader = getInternalClassFile("", "X", "X", source);
		
		IBinaryTypeAnnotation[] typeAnnotations = classFileReader.getTypeAnnotations();
		assertEquals(3,typeAnnotations.length);
		assertEquals("@LFoo; CLASS_EXTENDS(type_index=-1), location=[TYPE_ARGUMENT(0)]", printTypeAnnotation(typeAnnotations[0]));
		assertEquals("@LBar; CLASS_EXTENDS(type_index=-1), location=[TYPE_ARGUMENT(1)]", printTypeAnnotation(typeAnnotations[1]));
		assertEquals("@LFoo; CLASS_EXTENDS(type_index=0), location=[TYPE_ARGUMENT(0)]", printTypeAnnotation(typeAnnotations[2]));
	}
	
	public void test005_classTypeParameterBound() throws Exception {
		String source =
			"import java.lang.annotation.*;\n" +
			"public class X<U, T extends Y<@Foo String @Bar(1)[][]@Bar(2)[]> & @Bar(3) Cloneable> {}\n" +
			"class Y<T> {}\n" +
			"@Retention(RetentionPolicy.CLASS)\n" +
			"@Target(ElementType.TYPE_USE)\n" +
			"@interface Foo {\n" +
			"}\n" +
			"@Retention(RetentionPolicy.CLASS)\n" +
			"@Target(ElementType.TYPE_USE)\n" +
			"@interface Bar {\n" +
			"        int value() default -1;\n" +
			"}";

		org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader classFileReader = getInternalClassFile("", "X", "X", source);
		
		IBinaryTypeAnnotation[] typeAnnotations = classFileReader.getTypeAnnotations();
		assertEquals(4,typeAnnotations.length);
		assertEquals("@LFoo; CLASS_TYPE_PARAMETER_BOUND(type_parameter_index=1, bound_index=0), location=[TYPE_ARGUMENT(0), ARRAY, ARRAY, ARRAY]", printTypeAnnotation(typeAnnotations[0]));
		assertEquals("@LBar;(value=(int)1) CLASS_TYPE_PARAMETER_BOUND(type_parameter_index=1, bound_index=0), location=[TYPE_ARGUMENT(0)]", printTypeAnnotation(typeAnnotations[1]));
		assertEquals("@LBar;(value=(int)2) CLASS_TYPE_PARAMETER_BOUND(type_parameter_index=1, bound_index=0), location=[TYPE_ARGUMENT(0), ARRAY, ARRAY]", printTypeAnnotation(typeAnnotations[2]));
		assertEquals("@LBar;(value=(int)3) CLASS_TYPE_PARAMETER_BOUND(type_parameter_index=1, bound_index=1)", printTypeAnnotation(typeAnnotations[3]));
	}
	
	public void test006_methodTypeParameterBound() throws Exception {
		String source =
			"import java.lang.annotation.*;\n" +
			"public class X{\n" +
			"	<T extends Y<@Foo Z @Bar(1)[][]@Bar(2)[]> & @Bar(3) Cloneable> void foo(T t) {}\n" +
			"}\n" +
			"class Y<T> {}\n" +
			"class Z {}\n" +
			"@Retention(RetentionPolicy.CLASS)\n" +
			"@Target(ElementType.TYPE_USE)\n" +
			"@interface Foo {\n" +
			"}\n" +
			"@Retention(RetentionPolicy.CLASS)\n" +
			"@Target(ElementType.TYPE_USE)\n" +
			"@interface Bar {\n" +
			"        int value() default -1;\n" +
			"}";

		org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader cfr = getInternalClassFile("", "X", "X", source);

		IBinaryMethod method = getMethod(cfr,"foo");
		assertNotNull(method);
		IBinaryTypeAnnotation[] typeAnnotations = method.getTypeAnnotations();
		assertNotNull(typeAnnotations);
		assertEquals(4,typeAnnotations.length);
		assertEquals("@LFoo; METHOD_TYPE_PARAMETER_BOUND(type_parameter_index=0, bound_index=0), location=[TYPE_ARGUMENT(0), ARRAY, ARRAY, ARRAY]",printTypeAnnotation(typeAnnotations[0]));
		assertEquals("@LBar;(value=(int)1) METHOD_TYPE_PARAMETER_BOUND(type_parameter_index=0, bound_index=0), location=[TYPE_ARGUMENT(0)]", printTypeAnnotation(typeAnnotations[1]));
		assertEquals("@LBar;(value=(int)2) METHOD_TYPE_PARAMETER_BOUND(type_parameter_index=0, bound_index=0), location=[TYPE_ARGUMENT(0), ARRAY, ARRAY]", printTypeAnnotation(typeAnnotations[2]));
		assertEquals("@LBar;(value=(int)3) METHOD_TYPE_PARAMETER_BOUND(type_parameter_index=0, bound_index=1)", printTypeAnnotation(typeAnnotations[3]));
	}
	
	public void test007_field() throws Exception {
		String source =
			"import java.lang.annotation.*;\n" +
			"import java.util.Map;\n" +
			"public class X{\n" +
			"	@Foo Map<@Bar(1) String, @Bar(2) String @Bar(3)[] @Bar(4)[] @Bar(5)[]> field3;\n" +
			"}\n" +
			"class Y<T> {}\n" +
			"class Z {}\n" +
			"@Retention(RetentionPolicy.CLASS)\n" +
			"@Target(ElementType.TYPE_USE)\n" +
			"@interface Foo {\n" +
			"}\n" +
			"@Retention(RetentionPolicy.CLASS)\n" +
			"@Target(ElementType.TYPE_USE)\n" +
			"@interface Bar {\n" +
			"        int value() default -1;\n" +
			"}";

		org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader cfr = getInternalClassFile("", "X", "X", source);

		IBinaryField field = getField(cfr,"field3");
		assertNotNull(field);
		IBinaryTypeAnnotation[] typeAnnotations = field.getTypeAnnotations();
		assertNotNull(typeAnnotations);
		assertEquals(6,typeAnnotations.length);
		assertEquals("@LFoo; FIELD",printTypeAnnotation(typeAnnotations[0]));
		assertEquals("@LBar;(value=(int)1) FIELD, location=[TYPE_ARGUMENT(0)]", printTypeAnnotation(typeAnnotations[1]));
		assertEquals("@LBar;(value=(int)2) FIELD, location=[TYPE_ARGUMENT(1), ARRAY, ARRAY, ARRAY]", printTypeAnnotation(typeAnnotations[2]));
		assertEquals("@LBar;(value=(int)3) FIELD, location=[TYPE_ARGUMENT(1)]", printTypeAnnotation(typeAnnotations[3]));
		assertEquals("@LBar;(value=(int)4) FIELD, location=[TYPE_ARGUMENT(1), ARRAY]", printTypeAnnotation(typeAnnotations[4]));
		assertEquals("@LBar;(value=(int)5) FIELD, location=[TYPE_ARGUMENT(1), ARRAY, ARRAY]", printTypeAnnotation(typeAnnotations[5]));
	}
	
	public void test008_methodReturn() throws Exception {
		String source =
			"import java.lang.annotation.*;\n" +
			"import java.util.Map;\n" +
			"public class X{\n" +
			"	@Bar(3) @Foo int foo() {\n" +
			"		return 1;\n" +
			"	}\n" + 
			"	@Bar(3) int @Foo [] foo2() {\n" +
			"		return null;\n" +
			"	}\n" + 
			"}\n" +
			"@Retention(RetentionPolicy.CLASS)\n" +
			"@Target(ElementType.TYPE_USE)\n" +
			"@interface Foo {\n" +
			"}\n" +
			"@Retention(RetentionPolicy.CLASS)\n" +
			"@Target(ElementType.TYPE_USE)\n" +
			"@interface Bar {\n" +
			"        int value() default -1;\n" +
			"}";

		org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader cfr = getInternalClassFile("", "X", "X", source);

		IBinaryMethod method = getMethod(cfr,"foo");
		assertNotNull(method);
		IBinaryTypeAnnotation[] typeAnnotations = method.getTypeAnnotations();
		assertNotNull(typeAnnotations);
		assertEquals(2,typeAnnotations.length);
		assertEquals("@LBar;(value=(int)3) METHOD_RETURN",printTypeAnnotation(typeAnnotations[0]));
		assertEquals("@LFoo; METHOD_RETURN", printTypeAnnotation(typeAnnotations[1]));
		
		method = getMethod(cfr,"foo2");
		assertNotNull(method);
		typeAnnotations = method.getTypeAnnotations();
		assertNotNull(typeAnnotations);
		assertEquals(2,typeAnnotations.length);
		assertEquals("@LBar;(value=(int)3) METHOD_RETURN, location=[ARRAY]",printTypeAnnotation(typeAnnotations[0]));
		assertEquals("@LFoo; METHOD_RETURN", printTypeAnnotation(typeAnnotations[1]));
	}
	
	public void test009_methodReceiver() throws Exception {
		String source =
			"import java.lang.annotation.*;\n" +
			"import java.util.Map;\n" +
			"public class X{\n" +
			"	void foo(@Bar(3) X this) {}\n" + 
			"}\n" +
			"@Retention(RetentionPolicy.CLASS)\n" +
			"@Target(ElementType.TYPE_USE)\n" +
			"@interface Foo {\n" +
			"}\n" +
			"@Retention(RetentionPolicy.CLASS)\n" +
			"@Target(ElementType.TYPE_USE)\n" +
			"@interface Bar {\n" +
			"        int value() default -1;\n" +
			"}";

		org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader cfr = getInternalClassFile("", "X", "X", source);

		IBinaryMethod method = getMethod(cfr,"foo");
		assertNotNull(method);
		IBinaryTypeAnnotation[] typeAnnotations = method.getTypeAnnotations();
		assertNotNull(typeAnnotations);
		assertEquals(1,typeAnnotations.length);
		assertEquals("@LBar;(value=(int)3) METHOD_RECEIVER", printTypeAnnotation(typeAnnotations[0]));
	}
	
	public void test010_methodFormalParameter() throws Exception {
		String source =
			"import java.lang.annotation.*;\n" +
			"import java.util.Map;\n" +
			"public class X{\n" +
			"	void foo(@Bar(3) String s, @Foo int i) {}\n" + 
			"}\n" +
			"@Retention(RetentionPolicy.CLASS)\n" +
			"@Target(ElementType.TYPE_USE)\n" +
			"@interface Foo {\n" +
			"}\n" +
			"@Retention(RetentionPolicy.CLASS)\n" +
			"@Target(ElementType.TYPE_USE)\n" +
			"@interface Bar {\n" +
			"        int value() default -1;\n" +
			"}";

		org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader cfr = getInternalClassFile("", "X", "X", source);

		IBinaryMethod method = getMethod(cfr,"foo");
		assertNotNull(method);
		IBinaryTypeAnnotation[] typeAnnotations = method.getTypeAnnotations();
		assertNotNull(typeAnnotations);
		assertEquals(2,typeAnnotations.length);
		assertEquals("@LBar;(value=(int)3) METHOD_FORMAL_PARAMETER(method_formal_parameter_index=0)",printTypeAnnotation(typeAnnotations[0]));
		assertEquals("@LFoo; METHOD_FORMAL_PARAMETER(method_formal_parameter_index=1)",printTypeAnnotation(typeAnnotations[1]));
	}
	
	public void test011_throws() throws Exception {
		String source =
			"import java.lang.annotation.*;\n" +
			"import java.util.Map;\n" +
			"public class X{\n" +
			"	void foo() throws @Foo Exception, @Bar(1) Throwable {}\n" + 
			"}\n" +
			"@Retention(RetentionPolicy.CLASS)\n" +
			"@Target(ElementType.TYPE_USE)\n" +
			"@interface Foo {\n" +
			"}\n" +
			"@Retention(RetentionPolicy.CLASS)\n" +
			"@Target(ElementType.TYPE_USE)\n" +
			"@interface Bar {\n" +
			"        int value() default -1;\n" +
			"}";

		org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader cfr = getInternalClassFile("", "X", "X", source);

		IBinaryMethod method = getMethod(cfr,"foo");
		assertNotNull(method);
		IBinaryTypeAnnotation[] typeAnnotations = method.getTypeAnnotations();
		assertNotNull(typeAnnotations);
		assertEquals(2,typeAnnotations.length);
		assertEquals("@LFoo; THROWS(throws_type_index=0)",printTypeAnnotation(typeAnnotations[0]));
		assertEquals("@LBar;(value=(int)1) THROWS(throws_type_index=1)",printTypeAnnotation(typeAnnotations[1]));
	}
	public void test012_annotationMethodReturn() throws Exception {
		String source =
			"import java.lang.annotation.*;\n" +
			"import java.util.Map;\n" +
			"public @interface X{\n" +
			"	@Bar(3) @Foo int foo();\n" + 
			"	@Bar(3) int @Foo [] foo2();\n" + 
			"	@Bar(7) @Foo String value() default \"aaa\";\n" + 
			"}\n" +
			"@Retention(RetentionPolicy.CLASS)\n" +
			"@Target(ElementType.TYPE_USE)\n" +
			"@interface Foo {\n" +
			"}\n" +
			"@Retention(RetentionPolicy.CLASS)\n" +
			"@Target(ElementType.TYPE_USE)\n" +
			"@interface Bar {\n" +
			"        int value() default -1;\n" +
			"}";

		org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader cfr = getInternalClassFile("", "X", "X", source);

		IBinaryMethod method = getMethod(cfr,"foo");
		assertNotNull(method);
		IBinaryTypeAnnotation[] typeAnnotations = method.getTypeAnnotations();
		assertNotNull(typeAnnotations);
		assertEquals(2,typeAnnotations.length);
		assertEquals("@LBar;(value=(int)3) METHOD_RETURN",printTypeAnnotation(typeAnnotations[0]));
		assertEquals("@LFoo; METHOD_RETURN", printTypeAnnotation(typeAnnotations[1]));
		
		method = getMethod(cfr,"foo2");
		assertNotNull(method);
		typeAnnotations = method.getTypeAnnotations();
		assertNotNull(typeAnnotations);
		assertEquals(2,typeAnnotations.length);
		assertEquals("@LBar;(value=(int)3) METHOD_RETURN, location=[ARRAY]",printTypeAnnotation(typeAnnotations[0]));
		assertEquals("@LFoo; METHOD_RETURN", printTypeAnnotation(typeAnnotations[1]));
		
		method = getMethod(cfr,"value");
		assertNotNull(method);
		typeAnnotations = method.getTypeAnnotations();
		assertNotNull(typeAnnotations);
		assertEquals(2,typeAnnotations.length);
		assertEquals("@LBar;(value=(int)7) METHOD_RETURN",printTypeAnnotation(typeAnnotations[0]));
		assertEquals("@LFoo; METHOD_RETURN", printTypeAnnotation(typeAnnotations[1]));
		assertEquals(((org.eclipse.jdt.internal.compiler.impl.Constant)method.getDefaultValue()).stringValue(), "aaa");
	}

	public void testBug548596() {
		/*-
		 * Test548596.jar contains classes for the following kotlin code (compiled with kotlin 1.3.21):
		 * package k;
		 *	class A {
		 *	    class B {
		 *	        class C {
		 *	            //
		 *	        }
		 *	    }
		 *	}
		 */
		String[] libs = getDefaultClassPaths();
		int len = libs.length;
		System.arraycopy(libs, 0, libs = new String[len+1], 0, len);
		libs[libs.length-1] = this.getCompilerTestsPluginDirectoryPath() + File.separator + "workspace" + File.separator + "Test548596.jar";

		runConformTest(
			new String[] {
				"j/Usage.java",
				"package j;\n" + 
				"\n" + 
				"import k.A.B.C;\n" + 
				"\n" + 
				"public class Usage {\n" + 
				"    C c;\n" + 
				"}"
			},
			"",
			libs,
			false,
			null
		);
	}

	/**
	 * Produce a nicely formatted type annotation for testing. Exercises the API for type annotations.
	 * Output examples:<br>
	 * <tt>@Foo(id=34) CLASS_EXTENDS, type_index=-1, location=[ARRAY, INNER_TYPE, TYPE_ARGUMENT(0)]</tt><br>
	 */
	private String printTypeAnnotation(IBinaryTypeAnnotation typeAnnotation) {
		StringBuffer sb = new StringBuffer();
		// The annotation:
		IBinaryAnnotation annotation = typeAnnotation.getAnnotation();
		sb.append('@').append(annotation.getTypeName());
		IBinaryElementValuePair[] pairs = annotation.getElementValuePairs();
		if (pairs.length != 0) {
			sb.append('(');
			for (int i = 0; i < pairs.length; i++) {
				if (i > 0) {
					sb.append(',');
				}
				sb.append(pairs[i].getName()).append('=').append(pairs[i].getValue());
			}
			sb.append(')');
		}
		sb.append(' ');
		
		// target type
		int targetType = typeAnnotation.getTargetType();
		switch (targetType) {
			case AnnotationTargetTypeConstants.CLASS_TYPE_PARAMETER:
				sb.append("CLASS_TYPE_PARAMETER(type_parameter_index=").append(typeAnnotation.getTypeParameterIndex()).append(')');
				break;
			case AnnotationTargetTypeConstants.METHOD_TYPE_PARAMETER:
				sb.append("METHOD_TYPE_PARAMETER(type_parameter_index=").append(typeAnnotation.getTypeParameterIndex()).append(')');
				break;
			case AnnotationTargetTypeConstants.CLASS_EXTENDS:
				sb.append("CLASS_EXTENDS(type_index=").append((short)typeAnnotation.getSupertypeIndex()).append(')');
				break;
			case AnnotationTargetTypeConstants.CLASS_TYPE_PARAMETER_BOUND:
				sb.append("CLASS_TYPE_PARAMETER_BOUND(type_parameter_index=").
					append(typeAnnotation.getTypeParameterIndex()).
					append(", bound_index=").append(typeAnnotation.getBoundIndex()).
					append(')');
				break;
			case AnnotationTargetTypeConstants.METHOD_TYPE_PARAMETER_BOUND:
				sb.append("METHOD_TYPE_PARAMETER_BOUND(type_parameter_index=").
					append(typeAnnotation.getTypeParameterIndex()).
					append(", bound_index=").append(typeAnnotation.getBoundIndex()).
					append(')');
				break;
			case AnnotationTargetTypeConstants.FIELD:
				sb.append("FIELD");
				break;
			case AnnotationTargetTypeConstants.METHOD_RETURN:
				sb.append("METHOD_RETURN");
				break;
			case AnnotationTargetTypeConstants.METHOD_RECEIVER:
				sb.append("METHOD_RECEIVER");
				break;
			case AnnotationTargetTypeConstants.METHOD_FORMAL_PARAMETER :
				sb.append("METHOD_FORMAL_PARAMETER(method_formal_parameter_index=").
					append(typeAnnotation.getMethodFormalParameterIndex()).append(')');
				break;
			case AnnotationTargetTypeConstants.THROWS :
				sb.append("THROWS(throws_type_index=").
					append(typeAnnotation.getThrowsTypeIndex()).append(')');
				break;
			default: throw new IllegalStateException("nyi "+targetType);
		}
		
		// location
		int[] typepath = typeAnnotation.getTypePath();
		
		if (typepath != IBinaryTypeAnnotation.NO_TYPE_PATH) {
			sb.append(", location=["); //$NON-NLS-1$
			for (int i = 0, max = typepath.length; i < max; i += 2) {
				if (i > 0) {
					sb.append(", "); //$NON-NLS-1$
				}
				switch (typepath[i]) {
					case 0:
						sb.append("ARRAY"); //$NON-NLS-1$
						break;
					case 1:
						sb.append("INNER_TYPE"); //$NON-NLS-1$
						break;
					case 2:
						sb.append("WILDCARD"); //$NON-NLS-1$
						break;
					case 3:
						sb.append("TYPE_ARGUMENT(").append(typepath[i+1]).append(')'); //$NON-NLS-1$
						break;
				}
			}
			sb.append(']');
		}
		return sb.toString();
	}

	private IBinaryMethod getMethod(ClassFileReader cfr,String methodname) {
		IBinaryMethod[] methods = cfr.getMethods();
		if (methods == null) {
			return null;
		}
		char[] methodnameAsCharArray = methodname.toCharArray();
		for (int i = 0, max = methods.length; i < max; i++) {
			if (CharOperation.equals(methods[i].getSelector(),methodnameAsCharArray)) {
				return methods[i];
			}
		}
		return null;
	}

	private IBinaryField getField(ClassFileReader cfr,String fieldname) {
		IBinaryField[] fields = cfr.getFields();
		if (fields == null) {
			return null;
		}
		char[] fieldnameAsCharArray = fieldname.toCharArray();
		for (int i = 0, max = fields.length; i < max; i++) {
			if (CharOperation.equals(fields[i].getName(),fieldnameAsCharArray)) {
				return fields[i];
			}
		}
		return null;
	}
	
}
