/*******************************************************************************
 * Copyright (c) 2000, 2015 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
 *     Stephan Herrmann - Contribution for
 *								Bug 365992 - [builder] [null] Change of nullness for a parameter doesn't trigger a build for the files that call the method
 *								Bug 440477 - [null] Infrastructure for feeding external annotations into compilation
 *								Bug 440687 - [compiler][batch][null] improve command line option for external annotations
 *     Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for
 *         						bug 407191 - [1.8] Binary access support for type annotations
 *******************************************************************************/
package org.eclipse.jdt.internal.compiler.classfmt;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.internal.compiler.codegen.AttributeNamesConstants;
import org.eclipse.jdt.internal.compiler.env.*;
import org.eclipse.jdt.internal.compiler.impl.Constant;
import org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment;
import org.eclipse.jdt.internal.compiler.lookup.TagBits;
import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
import org.eclipse.jdt.internal.compiler.util.Util;

public class ClassFileReader extends ClassFileStruct implements IBinaryType {

	private int accessFlags;
	private char[] classFileName;
	private char[] className;
	private int classNameIndex;
	private int constantPoolCount;
	private AnnotationInfo[] annotations;
	private TypeAnnotationInfo[] typeAnnotations;
	private FieldInfo[] fields;
	private int fieldsCount;

	// initialized in case the .class file is a nested type
	private InnerClassInfo innerInfo;
	private int innerInfoIndex;
	private InnerClassInfo[] innerInfos;
	private char[][] interfaceNames;
	private int interfacesCount;
	private MethodInfo[] methods;
	private int methodsCount;
	private char[] signature;
	private char[] sourceName;
	private char[] sourceFileName;
	private char[] superclassName;
	private long tagBits;
	private long version;
	private char[] enclosingTypeName;
	private char[][][] missingTypeNames;
	private int enclosingNameAndTypeIndex;
	private char[] enclosingMethod;
	private ExternalAnnotationProvider annotationProvider;

private static String printTypeModifiers(int modifiers) {
	java.io.ByteArrayOutputStream out = new java.io.ByteArrayOutputStream();
	java.io.PrintWriter print = new java.io.PrintWriter(out);

	if ((modifiers & ClassFileConstants.AccPublic) != 0) print.print("public "); //$NON-NLS-1$
	if ((modifiers & ClassFileConstants.AccPrivate) != 0) print.print("private "); //$NON-NLS-1$
	if ((modifiers & ClassFileConstants.AccFinal) != 0) print.print("final "); //$NON-NLS-1$
	if ((modifiers & ClassFileConstants.AccSuper) != 0) print.print("super "); //$NON-NLS-1$
	if ((modifiers & ClassFileConstants.AccInterface) != 0) print.print("interface "); //$NON-NLS-1$
	if ((modifiers & ClassFileConstants.AccAbstract) != 0) print.print("abstract "); //$NON-NLS-1$
	print.flush();
	return out.toString();
}

public static ClassFileReader read(File file) throws ClassFormatException, IOException {
	return read(file, false);
}

public static ClassFileReader read(File file, boolean fullyInitialize) throws ClassFormatException, IOException {
	byte classFileBytes[] = Util.getFileByteContent(file);
	ClassFileReader classFileReader = new ClassFileReader(classFileBytes, file.getAbsolutePath().toCharArray());
	if (fullyInitialize) {
		classFileReader.initialize();
	}
	return classFileReader;
}

public static ClassFileReader read(InputStream stream, String fileName) throws ClassFormatException, IOException {
	return read(stream, fileName, false);
}

public static ClassFileReader read(InputStream stream, String fileName, boolean fullyInitialize) throws ClassFormatException, IOException {
	byte classFileBytes[] = Util.getInputStreamAsByteArray(stream, -1);
	ClassFileReader classFileReader = new ClassFileReader(classFileBytes, fileName.toCharArray());
	if (fullyInitialize) {
		classFileReader.initialize();
	}
	return classFileReader;
}

public static ClassFileReader read(
	java.util.zip.ZipFile zip,
	String filename)
	throws ClassFormatException, java.io.IOException {
		return read(zip, filename, false);
}

public static ClassFileReader read(
	java.util.zip.ZipFile zip,
	String filename,
	boolean fullyInitialize)
	throws ClassFormatException, java.io.IOException {
	java.util.zip.ZipEntry ze = zip.getEntry(filename);
	if (ze == null)
		return null;
	byte classFileBytes[] = Util.getZipEntryByteContent(ze, zip);
	ClassFileReader classFileReader = new ClassFileReader(classFileBytes, filename.toCharArray());
	if (fullyInitialize) {
		classFileReader.initialize();
	}
	return classFileReader;
}

public static ClassFileReader read(String fileName) throws ClassFormatException, java.io.IOException {
	return read(fileName, false);
}

public static ClassFileReader read(String fileName, boolean fullyInitialize) throws ClassFormatException, java.io.IOException {
	return read(new File(fileName), fullyInitialize);
}

/**
 * @param classFileBytes Actual bytes of a .class file
 * @param fileName	Actual name of the file that contains the bytes, can be null
 *
 * @exception ClassFormatException
 */
public ClassFileReader(byte classFileBytes[], char[] fileName) throws ClassFormatException {
	this(classFileBytes, fileName, false);
}

/**
 * @param classFileBytes byte[]
 * 		Actual bytes of a .class file
 *
 * @param fileName char[]
 * 		Actual name of the file that contains the bytes, can be null
 *
 * @param fullyInitialize boolean
 * 		Flag to fully initialize the new object
 * @exception ClassFormatException
 */
public ClassFileReader(byte[] classFileBytes, char[] fileName, boolean fullyInitialize) throws ClassFormatException {
	// This method looks ugly but is actually quite simple, the constantPool is constructed
	// in 3 passes.  All non-primitive constant pool members that usually refer to other members
	// by index are tweaked to have their value in inst vars, this minor cost at read-time makes
	// all subsequent uses of the constant pool element faster.
	super(classFileBytes, null, 0);
	this.classFileName = fileName;
	int readOffset = 10;
	try {
		this.version = ((long)u2At(6) << 16) + u2At(4); // major<<16 + minor
		this.constantPoolCount = u2At(8);
		// Pass #1 - Fill in all primitive constants
		this.constantPoolOffsets = new int[this.constantPoolCount];
		for (int i = 1; i < this.constantPoolCount; i++) {
			int tag = u1At(readOffset);
			switch (tag) {
				case ClassFileConstants.Utf8Tag :
					this.constantPoolOffsets[i] = readOffset;
					readOffset += u2At(readOffset + 1);
					readOffset += ClassFileConstants.ConstantUtf8FixedSize;
					break;
				case ClassFileConstants.IntegerTag :
					this.constantPoolOffsets[i] = readOffset;
					readOffset += ClassFileConstants.ConstantIntegerFixedSize;
					break;
				case ClassFileConstants.FloatTag :
					this.constantPoolOffsets[i] = readOffset;
					readOffset += ClassFileConstants.ConstantFloatFixedSize;
					break;
				case ClassFileConstants.LongTag :
					this.constantPoolOffsets[i] = readOffset;
					readOffset += ClassFileConstants.ConstantLongFixedSize;
					i++;
					break;
				case ClassFileConstants.DoubleTag :
					this.constantPoolOffsets[i] = readOffset;
					readOffset += ClassFileConstants.ConstantDoubleFixedSize;
					i++;
					break;
				case ClassFileConstants.ClassTag :
					this.constantPoolOffsets[i] = readOffset;
					readOffset += ClassFileConstants.ConstantClassFixedSize;
					break;
				case ClassFileConstants.StringTag :
					this.constantPoolOffsets[i] = readOffset;
					readOffset += ClassFileConstants.ConstantStringFixedSize;
					break;
				case ClassFileConstants.FieldRefTag :
					this.constantPoolOffsets[i] = readOffset;
					readOffset += ClassFileConstants.ConstantFieldRefFixedSize;
					break;
				case ClassFileConstants.MethodRefTag :
					this.constantPoolOffsets[i] = readOffset;
					readOffset += ClassFileConstants.ConstantMethodRefFixedSize;
					break;
				case ClassFileConstants.InterfaceMethodRefTag :
					this.constantPoolOffsets[i] = readOffset;
					readOffset += ClassFileConstants.ConstantInterfaceMethodRefFixedSize;
					break;
				case ClassFileConstants.NameAndTypeTag :
					this.constantPoolOffsets[i] = readOffset;
					readOffset += ClassFileConstants.ConstantNameAndTypeFixedSize;
					break;
				case ClassFileConstants.MethodHandleTag :
					this.constantPoolOffsets[i] = readOffset;
					readOffset += ClassFileConstants.ConstantMethodHandleFixedSize;
					break;
				case ClassFileConstants.MethodTypeTag :
					this.constantPoolOffsets[i] = readOffset;
					readOffset += ClassFileConstants.ConstantMethodTypeFixedSize;
					break;
				case ClassFileConstants.InvokeDynamicTag :
					this.constantPoolOffsets[i] = readOffset;
					readOffset += ClassFileConstants.ConstantInvokeDynamicFixedSize;
					break;
			}
		}
		// Read and validate access flags
		this.accessFlags = u2At(readOffset);
		readOffset += 2;

		// Read the classname, use exception handlers to catch bad format
		this.classNameIndex = u2At(readOffset);
		this.className = getConstantClassNameAt(this.classNameIndex);
		readOffset += 2;

		// Read the superclass name, can be null for java.lang.Object
		int superclassNameIndex = u2At(readOffset);
		readOffset += 2;
		// if superclassNameIndex is equals to 0 there is no need to set a value for the
		// field this.superclassName. null is fine.
		if (superclassNameIndex != 0) {
			this.superclassName = getConstantClassNameAt(superclassNameIndex);
		}

		// Read the interfaces, use exception handlers to catch bad format
		this.interfacesCount = u2At(readOffset);
		readOffset += 2;
		if (this.interfacesCount != 0) {
			this.interfaceNames = new char[this.interfacesCount][];
			for (int i = 0; i < this.interfacesCount; i++) {
				this.interfaceNames[i] = getConstantClassNameAt(u2At(readOffset));
				readOffset += 2;
			}
		}
		// Read the fields, use exception handlers to catch bad format
		this.fieldsCount = u2At(readOffset);
		readOffset += 2;
		if (this.fieldsCount != 0) {
			FieldInfo field;
			this.fields = new FieldInfo[this.fieldsCount];
			for (int i = 0; i < this.fieldsCount; i++) {
				field = FieldInfo.createField(this.reference, this.constantPoolOffsets, readOffset);
				this.fields[i] = field;
				readOffset += field.sizeInBytes();
			}
		}
		// Read the methods
		this.methodsCount = u2At(readOffset);
		readOffset += 2;
		if (this.methodsCount != 0) {
			this.methods = new MethodInfo[this.methodsCount];
			boolean isAnnotationType = (this.accessFlags & ClassFileConstants.AccAnnotation) != 0;
			for (int i = 0; i < this.methodsCount; i++) {
				this.methods[i] = isAnnotationType
					? AnnotationMethodInfo.createAnnotationMethod(this.reference, this.constantPoolOffsets, readOffset)
					: MethodInfo.createMethod(this.reference, this.constantPoolOffsets, readOffset);
				readOffset += this.methods[i].sizeInBytes();
			}
		}

		// Read the attributes
		int attributesCount = u2At(readOffset);
		readOffset += 2;

		for (int i = 0; i < attributesCount; i++) {
			int utf8Offset = this.constantPoolOffsets[u2At(readOffset)];
			char[] attributeName = utf8At(utf8Offset + 3, u2At(utf8Offset + 1));
			if (attributeName.length == 0) {
				readOffset += (6 + u4At(readOffset + 2));
				continue;
			}
			switch(attributeName[0] ) {
				case 'E' :
					if (CharOperation.equals(attributeName, AttributeNamesConstants.EnclosingMethodName)) {
						utf8Offset =
							this.constantPoolOffsets[u2At(this.constantPoolOffsets[u2At(readOffset + 6)] + 1)];
 						this.enclosingTypeName = utf8At(utf8Offset + 3, u2At(utf8Offset + 1));
						this.enclosingNameAndTypeIndex = u2At(readOffset + 8);
					}
					break;
				case 'D' :
					if (CharOperation.equals(attributeName, AttributeNamesConstants.DeprecatedName)) {
						this.accessFlags |= ClassFileConstants.AccDeprecated;
					}
					break;
				case 'I' :
					if (CharOperation.equals(attributeName, AttributeNamesConstants.InnerClassName)) {
						int innerOffset = readOffset + 6;
						int number_of_classes = u2At(innerOffset);
						if (number_of_classes != 0) {
							innerOffset+= 2;
							this.innerInfos = new InnerClassInfo[number_of_classes];
							for (int j = 0; j < number_of_classes; j++) {
								this.innerInfos[j] =
									new InnerClassInfo(this.reference, this.constantPoolOffsets, innerOffset);
								if (this.classNameIndex == this.innerInfos[j].innerClassNameIndex) {
									this.innerInfo = this.innerInfos[j];
									this.innerInfoIndex = j;
								}
								innerOffset += 8;
							}
							if (this.innerInfo != null) {
								char[] enclosingType = this.innerInfo.getEnclosingTypeName();
								if (enclosingType != null) {
									this.enclosingTypeName = enclosingType;
								}
							}
						}
					} else if (CharOperation.equals(attributeName, AttributeNamesConstants.InconsistentHierarchy)) {
						this.tagBits |= TagBits.HierarchyHasProblems;
					}
					break;
				case 'S' :
					if (attributeName.length > 2) {
						switch(attributeName[1]) {
							case 'o' :
								if (CharOperation.equals(attributeName, AttributeNamesConstants.SourceName)) {
									utf8Offset = this.constantPoolOffsets[u2At(readOffset + 6)];
									this.sourceFileName = utf8At(utf8Offset + 3, u2At(utf8Offset + 1));
								}
								break;
							case 'y' :
								if (CharOperation.equals(attributeName, AttributeNamesConstants.SyntheticName)) {
									this.accessFlags |= ClassFileConstants.AccSynthetic;
								}
								break;
							case 'i' :
								if (CharOperation.equals(attributeName, AttributeNamesConstants.SignatureName)) {
									utf8Offset = this.constantPoolOffsets[u2At(readOffset + 6)];
									this.signature = utf8At(utf8Offset + 3, u2At(utf8Offset + 1));
								}
						}
					}
					break;
				case 'R' :
					if (CharOperation.equals(attributeName, AttributeNamesConstants.RuntimeVisibleAnnotationsName)) {
						decodeAnnotations(readOffset, true);
					} else if (CharOperation.equals(attributeName, AttributeNamesConstants.RuntimeInvisibleAnnotationsName)) {
						decodeAnnotations(readOffset, false);
					} else if (CharOperation.equals(attributeName, AttributeNamesConstants.RuntimeVisibleTypeAnnotationsName)) {
						decodeTypeAnnotations(readOffset, true);
					} else if (CharOperation.equals(attributeName, AttributeNamesConstants.RuntimeInvisibleTypeAnnotationsName)) {
						decodeTypeAnnotations(readOffset, false);
					}
					break;
				case 'M' :
					if (CharOperation.equals(attributeName, AttributeNamesConstants.MissingTypesName)) {
						// decode the missing types
						int missingTypeOffset = readOffset + 6;
						int numberOfMissingTypes = u2At(missingTypeOffset);
						if (numberOfMissingTypes != 0) {
							this.missingTypeNames = new char[numberOfMissingTypes][][];
							missingTypeOffset += 2;
							for (int j = 0; j < numberOfMissingTypes; j++) {
								utf8Offset = this.constantPoolOffsets[u2At(this.constantPoolOffsets[u2At(missingTypeOffset)] + 1)];
								char[] missingTypeConstantPoolName = utf8At(utf8Offset + 3, u2At(utf8Offset + 1));
								this.missingTypeNames[j] = CharOperation.splitOn('/', missingTypeConstantPoolName);
								missingTypeOffset += 2;
							}
						}
					}
			}
			readOffset += (6 + u4At(readOffset + 2));
		}
		if (fullyInitialize) {
			initialize();
		}
	} catch(ClassFormatException e) {
		throw e;
	} catch (Exception e) {
		throw new ClassFormatException(
			ClassFormatException.ErrTruncatedInput,
			readOffset);
	}
}

/** Auxiliary interface for {@link #setExternalAnnotationProvider(String,String,ZipFile,ZipFileProducer)}. */
public interface ZipFileProducer { ZipFile produce() throws IOException; }

/**
 * Create and remember a provider for external annotations using the given basePath,
 * which is either a directory holding .eea text files, or a zip file of entries of the same format.
 * @param basePath resolved filesystem path of either directory or zip file
 * @param qualifiedBinaryTypeName slash-separated type name
 * @param zipFile an existing zip file for the same basePath, or null. 
 * 		Output: wl be filled with 
 * @param producer an optional helper to produce the zipFile when needed.
 * @return the client provided zip file; 
 * 		or else a fresh new zip file, to let clients cache it, if desired; 
 * 		or null to signal that basePath is not a zip file, but a directory.
 * @throws IOException any unexpected errors during file access. File not found while
 *		accessing an individual file if basePath is a directory <em>is</em> expected,
 *		and simply answered with null. If basePath is neither a directory nor a zip file,
 *		this is unexpected.
 */
public ZipFile setExternalAnnotationProvider(String basePath, String qualifiedBinaryTypeName, ZipFile zipFile, ZipFileProducer producer) throws IOException {
	String qualifiedBinaryFileName = qualifiedBinaryTypeName + ExternalAnnotationProvider.ANNOTATION_FILE_SUFFIX;
	if (zipFile == null) {
		File annotationBase = new File(basePath);
		if (annotationBase.isDirectory()) {
			try {
				String filePath = annotationBase.getAbsolutePath()+'/'+qualifiedBinaryFileName;
				this.annotationProvider = new ExternalAnnotationProvider(new FileInputStream(filePath), String.valueOf(getName()));
			} catch (FileNotFoundException e) {
				// expected, no need to report an error here
			}
			return null; // no zipFile
		}
		if (!annotationBase.exists())
			return null; // no zipFile, treat as not-yet-created directory
		zipFile = (producer != null ? producer.produce() : new ZipFile(annotationBase));
	}
	ZipEntry entry = zipFile.getEntry(qualifiedBinaryFileName);
	if (entry != null)
		this.annotationProvider = new ExternalAnnotationProvider(zipFile.getInputStream(entry), String.valueOf(getName()));
	return zipFile;
}
public boolean hasAnnotationProvider() {
	return this.annotationProvider != null;
}

/**
 * Conditionally add external annotations to the mix.
 * If 'member' is given it must be either of IBinaryField or IBinaryMethod, in which case we're seeking annotations for that member.
 * Otherwise we're seeking annotations for top-level elements of a type (type parameters & super types).
 */
@Override
public ITypeAnnotationWalker enrichWithExternalAnnotationsFor(ITypeAnnotationWalker walker, Object member, LookupEnvironment environment) {
	if (walker == ITypeAnnotationWalker.EMPTY_ANNOTATION_WALKER && this.annotationProvider != null) {
		if (member == null) {
			return this.annotationProvider.forTypeHeader(environment);
		} else if (member instanceof IBinaryField) {
			IBinaryField field = (IBinaryField) member;
			char[] fieldSignature = field.getGenericSignature();
			if (fieldSignature == null)
				fieldSignature = field.getTypeName();
			return this.annotationProvider.forField(field.getName(), fieldSignature, environment);
		} else if (member instanceof IBinaryMethod) {
			IBinaryMethod method = (IBinaryMethod) member;
			char[] methodSignature = method.getGenericSignature();
			if (methodSignature == null)
				methodSignature = method.getMethodDescriptor();
			return this.annotationProvider.forMethod(method.isConstructor() ? TypeConstants.INIT : method.getSelector(), methodSignature, environment);
		}
	}
	return walker;
}

/**
 * Answer the receiver's access flags.  The value of the access_flags
 *	item is a mask of modifiers used with class and interface declarations.
 *  @return int
 */
public int accessFlags() {
	return this.accessFlags;
}

private void decodeAnnotations(int offset, boolean runtimeVisible) {
	int numberOfAnnotations = u2At(offset + 6);
	if (numberOfAnnotations > 0) {
		int readOffset = offset + 8;
		AnnotationInfo[] newInfos = null;
		int newInfoCount = 0;
		for (int i = 0; i < numberOfAnnotations; i++) {
			// With the last parameter being 'false', the data structure will not be flushed out
			AnnotationInfo newInfo = new AnnotationInfo(this.reference, this.constantPoolOffsets, readOffset, runtimeVisible, false);
			readOffset += newInfo.readOffset;
			long standardTagBits = newInfo.standardAnnotationTagBits;
			if (standardTagBits != 0) {
				this.tagBits |= standardTagBits;
			} else {
				if (newInfos == null)
					newInfos = new AnnotationInfo[numberOfAnnotations - i];
				newInfos[newInfoCount++] = newInfo;
			}
		}
		if (newInfos == null)
			return; // nothing to record in this.annotations

		if (this.annotations == null) {
			if (newInfoCount != newInfos.length)
				System.arraycopy(newInfos, 0, newInfos = new AnnotationInfo[newInfoCount], 0, newInfoCount);
			this.annotations = newInfos;
		} else {
			int length = this.annotations.length;
			AnnotationInfo[] temp = new AnnotationInfo[length + newInfoCount];
			System.arraycopy(this.annotations, 0, temp, 0, length);
			System.arraycopy(newInfos, 0, temp, length, newInfoCount);
			this.annotations = temp;
		}
	}
}

private void decodeTypeAnnotations(int offset, boolean runtimeVisible) {
	int numberOfAnnotations = u2At(offset + 6);
	if (numberOfAnnotations > 0) {
		int readOffset = offset + 8;
		TypeAnnotationInfo[] newInfos = null;
		newInfos = new TypeAnnotationInfo[numberOfAnnotations];
		for (int i = 0; i < numberOfAnnotations; i++) {
			// With the last parameter being 'false', the data structure will not be flushed out
			TypeAnnotationInfo newInfo = new TypeAnnotationInfo(this.reference, this.constantPoolOffsets, readOffset, runtimeVisible, false);
			readOffset += newInfo.readOffset;
			newInfos[i] = newInfo;
		}
		if (this.typeAnnotations == null) {
			this.typeAnnotations = newInfos;
		} else {
			int length = this.typeAnnotations.length;
			TypeAnnotationInfo[] temp = new TypeAnnotationInfo[length + numberOfAnnotations];
			System.arraycopy(this.typeAnnotations, 0, temp, 0, length);
			System.arraycopy(newInfos, 0, temp, length, numberOfAnnotations);
			this.typeAnnotations = temp;
		}
	}
}

/**
 * @return the annotations or null if there is none.
 */
public IBinaryAnnotation[] getAnnotations() {
	return this.annotations;
}

/**
 * @return the type annotations or null if there is none.
 */
public IBinaryTypeAnnotation[] getTypeAnnotations() {
	return this.typeAnnotations;
}

/**
 * Answer the char array that corresponds to the class name of the constant class.
 * constantPoolIndex is the index in the constant pool that is a constant class entry.
 *
 * @param constantPoolIndex int
 * @return char[]
 */
private char[] getConstantClassNameAt(int constantPoolIndex) {
	int utf8Offset = this.constantPoolOffsets[u2At(this.constantPoolOffsets[constantPoolIndex] + 1)];
	return utf8At(utf8Offset + 3, u2At(utf8Offset + 1));
}

/**
 * Answer the int array that corresponds to all the offsets of each entry in the constant pool
 *
 * @return int[]
 */
public int[] getConstantPoolOffsets() {
	return this.constantPoolOffsets;
}

public char[] getEnclosingMethod() {
	if (this.enclosingNameAndTypeIndex <= 0) {
		return null;
	}
	if (this.enclosingMethod == null) {
		// read the name
		StringBuffer buffer = new StringBuffer();
		
		int nameAndTypeOffset = this.constantPoolOffsets[this.enclosingNameAndTypeIndex];
		int utf8Offset = this.constantPoolOffsets[u2At(nameAndTypeOffset + 1)];
		buffer.append(utf8At(utf8Offset + 3, u2At(utf8Offset + 1)));

		utf8Offset = this.constantPoolOffsets[u2At(nameAndTypeOffset + 3)];
		buffer.append(utf8At(utf8Offset + 3, u2At(utf8Offset + 1)));

		this.enclosingMethod = String.valueOf(buffer).toCharArray();
	}
	return this.enclosingMethod;
}

/*
 * Answer the resolved compoundName of the enclosing type
 * or null if the receiver is a top level type.
 */
public char[] getEnclosingTypeName() {
	return this.enclosingTypeName;
}

/**
 * Answer the receiver's this.fields or null if the array is empty.
 * @return org.eclipse.jdt.internal.compiler.api.IBinaryField[]
 */
public IBinaryField[] getFields() {
	return this.fields;
}

/**
 * @see org.eclipse.jdt.internal.compiler.env.IDependent#getFileName()
 */
public char[] getFileName() {
	return this.classFileName;
}

public char[] getGenericSignature() {
	return this.signature;
}

/**
 * Answer the source name if the receiver is a inner type. Return null if it is an anonymous class or if the receiver is a top-level class.
 * e.g.
 * public class A {
 *	public class B {
 *	}
 *	public void foo() {
 *		class C {}
 *	}
 *	public Runnable bar() {
 *		return new Runnable() {
 *			public void run() {}
 *		};
 *	}
 * }
 * It returns {'B'} for the member A$B
 * It returns null for A
 * It returns {'C'} for the local class A$1$C
 * It returns null for the anonymous A$1
 * @return char[]
 */
public char[] getInnerSourceName() {
	if (this.innerInfo != null)
		return this.innerInfo.getSourceName();
	return null;
}

/**
 * Answer the resolved names of the receiver's interfaces in the
 * class file format as specified in section 4.2 of the Java 2 VM spec
 * or null if the array is empty.
 *
 * For example, java.lang.String is java/lang/String.
 * @return char[][]
 */
public char[][] getInterfaceNames() {
	return this.interfaceNames;
}

/**
 * Answer the receiver's nested types or null if the array is empty.
 *
 * This nested type info is extracted from the inner class attributes. Ask the
 * name environment to find a member type using its compound name
 *
 * @return org.eclipse.jdt.internal.compiler.api.IBinaryNestedType[]
 */
public IBinaryNestedType[] getMemberTypes() {
	// we might have some member types of the current type
	if (this.innerInfos == null) return null;

	int length = this.innerInfos.length;
	int startingIndex = this.innerInfo != null ? this.innerInfoIndex + 1 : 0;
	if (length != startingIndex) {
		IBinaryNestedType[] memberTypes =
			new IBinaryNestedType[length - this.innerInfoIndex];
		int memberTypeIndex = 0;
		for (int i = startingIndex; i < length; i++) {
			InnerClassInfo currentInnerInfo = this.innerInfos[i];
			int outerClassNameIdx = currentInnerInfo.outerClassNameIndex;
			int innerNameIndex = currentInnerInfo.innerNameIndex;
			/*
			 * Checking that outerClassNameIDx is different from 0 should be enough to determine if an inner class
			 * attribute entry is a member class, but due to the bug:
			 * http://dev.eclipse.org/bugs/show_bug.cgi?id=14592
			 * we needed to add an extra check. So we check that innerNameIndex is different from 0 as well.
			 *
			 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=49879
			 * From JavaMail 1.2, the class javax.mail.Folder contains an anonymous class in the
			 * terminateQueue() method for which the inner attribute is boggus.
			 * outerClassNameIdx is not 0, innerNameIndex is not 0, but the sourceName length is 0.
			 * So I added this extra check to filter out this anonymous class from the
			 * member types.
			 */
			if (outerClassNameIdx != 0
				&& innerNameIndex != 0
				&& outerClassNameIdx == this.classNameIndex
				&& currentInnerInfo.getSourceName().length != 0) {
				memberTypes[memberTypeIndex++] = currentInnerInfo;
			}
		}
		if (memberTypeIndex == 0) return null;
		if (memberTypeIndex != memberTypes.length) {
			// we need to resize the memberTypes array. Some local or anonymous classes
			// are present in the current class.
			System.arraycopy(
				memberTypes,
				0,
				(memberTypes = new IBinaryNestedType[memberTypeIndex]),
				0,
				memberTypeIndex);
		}
		return memberTypes;
	}
	return null;
}

/**
 * Answer the receiver's this.methods or null if the array is empty.
 * @return org.eclipse.jdt.internal.compiler.api.env.IBinaryMethod[]
 */
public IBinaryMethod[] getMethods() {
	return this.methods;
}

/*
public static void main(String[] args) throws ClassFormatException, IOException {
	if (args == null || args.length != 1) {
		System.err.println("ClassFileReader <filename>"); //$NON-NLS-1$
		System.exit(1);
	}
	File file = new File(args[0]);
	ClassFileReader reader = read(file, true);
	if (reader.annotations != null) {
		System.err.println();
		for (int i = 0; i < reader.annotations.length; i++)
			System.err.println(reader.annotations[i]);
	}
	System.err.print("class "); //$NON-NLS-1$
	System.err.print(reader.getName());
	char[] superclass = reader.getSuperclassName();
	if (superclass != null) {
		System.err.print(" extends "); //$NON-NLS-1$
		System.err.print(superclass);
	}
	System.err.println();
	char[][] interfaces = reader.getInterfaceNames();
	if (interfaces != null && interfaces.length > 0) {
		System.err.print(" implements "); //$NON-NLS-1$
		for (int i = 0; i < interfaces.length; i++) {
			if (i != 0) System.err.print(", "); //$NON-NLS-1$
			System.err.println(interfaces[i]);
		}
	}
	System.err.println();
	System.err.println('{');
	if (reader.fields != null) {
		for (int i = 0; i < reader.fields.length; i++) {
			System.err.println(reader.fields[i]);
			System.err.println();
		}
	}
	if (reader.methods != null) {
		for (int i = 0; i < reader.methods.length; i++) {
			System.err.println(reader.methods[i]);
			System.err.println();
		}
	}
	System.err.println();
	System.err.println('}');
}
*/
public char[][][] getMissingTypeNames() {
	return this.missingTypeNames;
}

/**
 * Answer an int whose bits are set according the access constants
 * defined by the VM spec.
 * Set the AccDeprecated and AccSynthetic bits if necessary
 * @return int
 */
public int getModifiers() {
	int modifiers;
	if (this.innerInfo != null) {
		modifiers = this.innerInfo.getModifiers()
			| (this.accessFlags & ClassFileConstants.AccDeprecated)
			| (this.accessFlags & ClassFileConstants.AccSynthetic);
	} else {
		modifiers = this.accessFlags;
	}
	return modifiers;
}

/**
 * Answer the resolved name of the type in the
 * class file format as specified in section 4.2 of the Java 2 VM spec.
 *
 * For example, java.lang.String is java/lang/String.
 * @return char[]
 */
public char[] getName() {
	return this.className;
}

public char[] getSourceName() {
	if (this.sourceName != null)
		return this.sourceName;

	char[] name = getInnerSourceName(); // member or local scenario
	if (name == null) {
		name = getName(); // extract from full name
		int start;
		if (isAnonymous()) {
			start = CharOperation.indexOf('$', name, CharOperation.lastIndexOf('/', name) + 1) + 1;
		} else {
			start = CharOperation.lastIndexOf('/', name) + 1;
		}
		if (start > 0) {
			char[] newName = new char[name.length - start];
			System.arraycopy(name, start, newName, 0, newName.length);
			name = newName;
		}
	}
	return this.sourceName = name;
}

/**
 * Answer the resolved name of the receiver's superclass in the
 * class file format as specified in section 4.2 of the Java 2 VM spec
 * or null if it does not have one.
 *
 * For example, java.lang.String is java/lang/String.
 * @return char[]
 */
public char[] getSuperclassName() {
	return this.superclassName;
}

public long getTagBits() {
	return this.tagBits;
}

/**
 * Answer the major/minor version defined in this class file according to the VM spec.
 * as a long: (major<<16)+minor
 * @return the major/minor version found
 */
public long getVersion() {
	return this.version;
}

private boolean hasNonSyntheticFieldChanges(FieldInfo[] currentFieldInfos, FieldInfo[] otherFieldInfos) {
	int length1 = currentFieldInfos == null ? 0 : currentFieldInfos.length;
	int length2 = otherFieldInfos == null ? 0 : otherFieldInfos.length;
	int index1 = 0;
	int index2 = 0;

	end : while (index1 < length1 && index2 < length2) {
		while (currentFieldInfos[index1].isSynthetic()) {
			if (++index1 >= length1) break end;
		}
		while (otherFieldInfos[index2].isSynthetic()) {
			if (++index2 >= length2) break end;
		}
		if (hasStructuralFieldChanges(currentFieldInfos[index1++], otherFieldInfos[index2++]))
			return true;
	}

	while (index1 < length1) {
		if (!currentFieldInfos[index1++].isSynthetic()) return true;
	}
	while (index2 < length2) {
		if (!otherFieldInfos[index2++].isSynthetic()) return true;
	}
	return false;
}

private boolean hasNonSyntheticMethodChanges(MethodInfo[] currentMethodInfos, MethodInfo[] otherMethodInfos) {
	int length1 = currentMethodInfos == null ? 0 : currentMethodInfos.length;
	int length2 = otherMethodInfos == null ? 0 : otherMethodInfos.length;
	int index1 = 0;
	int index2 = 0;

	MethodInfo m;
	end : while (index1 < length1 && index2 < length2) {
		while ((m = currentMethodInfos[index1]).isSynthetic() || m.isClinit()) {
			if (++index1 >= length1) break end;
		}
		while ((m = otherMethodInfos[index2]).isSynthetic() || m.isClinit()) {
			if (++index2 >= length2) break end;
		}
		if (hasStructuralMethodChanges(currentMethodInfos[index1++], otherMethodInfos[index2++]))
			return true;
	}

	while (index1 < length1) {
		if (!((m = currentMethodInfos[index1++]).isSynthetic() || m.isClinit())) return true;
	}
	while (index2 < length2) {
		if (!((m = otherMethodInfos[index2++]).isSynthetic() || m.isClinit())) return true;
	}
	return false;
}

/**
 * Check if the receiver has structural changes compare to the byte array in argument.
 * Structural changes are:
 * - modifiers changes for the class, the this.fields or the this.methods
 * - signature changes for this.fields or this.methods.
 * - changes in the number of this.fields or this.methods
 * - changes for field constants
 * - changes for thrown exceptions
 * - change for the super class or any super interfaces.
 * - changes for member types name or modifiers
 * If any of these changes occurs, the method returns true. false otherwise.
 * The synthetic fields are included and the members are not required to be sorted.
 * @param newBytes the bytes of the .class file we want to compare the receiver to
 * @return boolean Returns true is there is a structural change between the two .class files, false otherwise
 */
public boolean hasStructuralChanges(byte[] newBytes) {
	return hasStructuralChanges(newBytes, true, true);
}

/**
 * Check if the receiver has structural changes compare to the byte array in argument.
 * Structural changes are:
 * - modifiers changes for the class, the this.fields or the this.methods
 * - signature changes for this.fields or this.methods.
 * - changes in the number of this.fields or this.methods
 * - changes for field constants
 * - changes for thrown exceptions
 * - change for the super class or any super interfaces.
 * - changes for member types name or modifiers
 * If any of these changes occurs, the method returns true. false otherwise.
 * @param newBytes the bytes of the .class file we want to compare the receiver to
 * @param orderRequired a boolean indicating whether the members should be sorted or not
 * @param excludesSynthetic a boolean indicating whether the synthetic members should be used in the comparison
 * @return boolean Returns true is there is a structural change between the two .class files, false otherwise
 */
public boolean hasStructuralChanges(byte[] newBytes, boolean orderRequired, boolean excludesSynthetic) {
	try {
		ClassFileReader newClassFile =
			new ClassFileReader(newBytes, this.classFileName);
		// type level comparison
		// modifiers
		if (getModifiers() != newClassFile.getModifiers())
			return true;

		// only consider a portion of the tagbits which indicate a structural change for dependents
		// e.g. @Override change has no influence outside
		long OnlyStructuralTagBits = TagBits.AnnotationTargetMASK // different @Target status ?
			| TagBits.AnnotationDeprecated // different @Deprecated status ?
			| TagBits.AnnotationRetentionMASK // different @Retention status ?
			| TagBits.HierarchyHasProblems; // different hierarchy status ?

		// meta-annotations
		if ((getTagBits() & OnlyStructuralTagBits) != (newClassFile.getTagBits() & OnlyStructuralTagBits))
			return true;
		// annotations
		if (hasStructuralAnnotationChanges(getAnnotations(), newClassFile.getAnnotations()))
			return true;

		// generic signature
		if (!CharOperation.equals(getGenericSignature(), newClassFile.getGenericSignature()))
			return true;
		// superclass
		if (!CharOperation.equals(getSuperclassName(), newClassFile.getSuperclassName()))
			return true;
		// interfaces
		char[][] newInterfacesNames = newClassFile.getInterfaceNames();
		if (this.interfaceNames != newInterfacesNames) { // TypeConstants.NoSuperInterfaces
			int newInterfacesLength = newInterfacesNames == null ? 0 : newInterfacesNames.length;
			if (newInterfacesLength != this.interfacesCount)
				return true;
			for (int i = 0, max = this.interfacesCount; i < max; i++)
				if (!CharOperation.equals(this.interfaceNames[i], newInterfacesNames[i]))
					return true;
		}

		// member types
		IBinaryNestedType[] currentMemberTypes = getMemberTypes();
		IBinaryNestedType[] otherMemberTypes = newClassFile.getMemberTypes();
		if (currentMemberTypes != otherMemberTypes) { // TypeConstants.NoMemberTypes
			int currentMemberTypeLength = currentMemberTypes == null ? 0 : currentMemberTypes.length;
			int otherMemberTypeLength = otherMemberTypes == null ? 0 : otherMemberTypes.length;
			if (currentMemberTypeLength != otherMemberTypeLength)
				return true;
			for (int i = 0; i < currentMemberTypeLength; i++)
				if (!CharOperation.equals(currentMemberTypes[i].getName(), otherMemberTypes[i].getName())
					|| currentMemberTypes[i].getModifiers() != otherMemberTypes[i].getModifiers())
						return true;
		}

		// fields
		FieldInfo[] otherFieldInfos = (FieldInfo[]) newClassFile.getFields();
		int otherFieldInfosLength = otherFieldInfos == null ? 0 : otherFieldInfos.length;
		boolean compareFields = true;
		if (this.fieldsCount == otherFieldInfosLength) {
			int i = 0;
			for (; i < this.fieldsCount; i++)
				if (hasStructuralFieldChanges(this.fields[i], otherFieldInfos[i])) break;
			if ((compareFields = i != this.fieldsCount) && !orderRequired && !excludesSynthetic)
				return true;
		}
		if (compareFields) {
			if (this.fieldsCount != otherFieldInfosLength && !excludesSynthetic)
				return true;
			if (orderRequired) {
				if (this.fieldsCount != 0)
					Arrays.sort(this.fields);
				if (otherFieldInfosLength != 0)
					Arrays.sort(otherFieldInfos);
			}
			if (excludesSynthetic) {
				if (hasNonSyntheticFieldChanges(this.fields, otherFieldInfos))
					return true;
			} else {
				for (int i = 0; i < this.fieldsCount; i++)
					if (hasStructuralFieldChanges(this.fields[i], otherFieldInfos[i]))
						return true;
			}
		}

		// methods
		MethodInfo[] otherMethodInfos = (MethodInfo[]) newClassFile.getMethods();
		int otherMethodInfosLength = otherMethodInfos == null ? 0 : otherMethodInfos.length;
		boolean compareMethods = true;
		if (this.methodsCount == otherMethodInfosLength) {
			int i = 0;
			for (; i < this.methodsCount; i++)
				if (hasStructuralMethodChanges(this.methods[i], otherMethodInfos[i])) break;
			if ((compareMethods = i != this.methodsCount) && !orderRequired && !excludesSynthetic)
				return true;
		}
		if (compareMethods) {
			if (this.methodsCount != otherMethodInfosLength && !excludesSynthetic)
				return true;
			if (orderRequired) {
				if (this.methodsCount != 0)
					Arrays.sort(this.methods);
				if (otherMethodInfosLength != 0)
					Arrays.sort(otherMethodInfos);
			}
			if (excludesSynthetic) {
				if (hasNonSyntheticMethodChanges(this.methods, otherMethodInfos))
					return true;
			} else {
				for (int i = 0; i < this.methodsCount; i++)
					if (hasStructuralMethodChanges(this.methods[i], otherMethodInfos[i]))
						return true;
			}
		}

		// missing types
		char[][][] missingTypes = getMissingTypeNames();
		char[][][] newMissingTypes = newClassFile.getMissingTypeNames();
		if (missingTypes != null) {
			if (newMissingTypes == null) {
				return true;
			}
			int length = missingTypes.length;
			if (length != newMissingTypes.length) {
				return true;
			}
			for (int i = 0; i < length; i++) {
				if (!CharOperation.equals(missingTypes[i], newMissingTypes[i])) {
					return true;
				}
			}
		} else if (newMissingTypes != null) {
			return true;
		}
		return false;
	} catch (ClassFormatException e) {
		return true;
	}
}

private boolean hasStructuralAnnotationChanges(IBinaryAnnotation[] currentAnnotations, IBinaryAnnotation[] otherAnnotations) {
	if (currentAnnotations == otherAnnotations)
		return false;

	int currentAnnotationsLength = currentAnnotations == null ? 0 : currentAnnotations.length;
	int otherAnnotationsLength = otherAnnotations == null ? 0 : otherAnnotations.length;
	if (currentAnnotationsLength != otherAnnotationsLength)
		return true;
	for (int i = 0; i < currentAnnotationsLength; i++) {
		if (!CharOperation.equals(currentAnnotations[i].getTypeName(), otherAnnotations[i].getTypeName()))
			return true;
		IBinaryElementValuePair[] currentPairs = currentAnnotations[i].getElementValuePairs();
		IBinaryElementValuePair[] otherPairs = otherAnnotations[i].getElementValuePairs();
		int currentPairsLength = currentPairs == null ? 0 : currentPairs.length;
		int otherPairsLength = otherPairs == null ? 0 : otherPairs.length;
		if (currentPairsLength != otherPairsLength)
			return true;
		for (int j = 0; j < currentPairsLength; j++) {
			if (!CharOperation.equals(currentPairs[j].getName(), otherPairs[j].getName()))
				return true;
			final Object value = currentPairs[j].getValue();
			final Object value2 = otherPairs[j].getValue();
			if (value instanceof Object[]) {
				Object[] currentValues = (Object[]) value;
				if (value2 instanceof Object[]) {
					Object[] currentValues2 = (Object[]) value2;
					final int length = currentValues.length;
					if (length != currentValues2.length) {
						return true;
					}
					for (int n = 0; n < length; n++) {
						if (!currentValues[n].equals(currentValues2[n])) {
							return true;
						}
					}
					return false;
				}
				return true;
			} else if (!value.equals(value2)) {
				return true;
			}
		}
	}
	return false;
}

private boolean hasStructuralFieldChanges(FieldInfo currentFieldInfo, FieldInfo otherFieldInfo) {
	// generic signature
	if (!CharOperation.equals(currentFieldInfo.getGenericSignature(), otherFieldInfo.getGenericSignature()))
		return true;
	if (currentFieldInfo.getModifiers() != otherFieldInfo.getModifiers())
		return true;
	if ((currentFieldInfo.getTagBits() & TagBits.AnnotationDeprecated) != (otherFieldInfo.getTagBits() & TagBits.AnnotationDeprecated))
		return true;
	if (hasStructuralAnnotationChanges(currentFieldInfo.getAnnotations(), otherFieldInfo.getAnnotations()))
		return true;
	if (!CharOperation.equals(currentFieldInfo.getName(), otherFieldInfo.getName()))
		return true;
	if (!CharOperation.equals(currentFieldInfo.getTypeName(), otherFieldInfo.getTypeName()))
		return true;
	if (currentFieldInfo.hasConstant() != otherFieldInfo.hasConstant())
		return true;
	if (currentFieldInfo.hasConstant()) {
		Constant currentConstant = currentFieldInfo.getConstant();
		Constant otherConstant = otherFieldInfo.getConstant();
		if (currentConstant.typeID() != otherConstant.typeID())
			return true;
		if (!currentConstant.getClass().equals(otherConstant.getClass()))
			return true;
		switch (currentConstant.typeID()) {
			case TypeIds.T_int :
				return currentConstant.intValue() != otherConstant.intValue();
			case TypeIds.T_byte :
				return currentConstant.byteValue() != otherConstant.byteValue();
			case TypeIds.T_short :
				return currentConstant.shortValue() != otherConstant.shortValue();
			case TypeIds.T_char :
				return currentConstant.charValue() != otherConstant.charValue();
			case TypeIds.T_long :
				return currentConstant.longValue() != otherConstant.longValue();
			case TypeIds.T_float :
				return currentConstant.floatValue() != otherConstant.floatValue();
			case TypeIds.T_double :
				return currentConstant.doubleValue() != otherConstant.doubleValue();
			case TypeIds.T_boolean :
				return currentConstant.booleanValue() != otherConstant.booleanValue();
			case TypeIds.T_JavaLangString :
				return !currentConstant.stringValue().equals(otherConstant.stringValue());
		}
	}
	return false;
}

private boolean hasStructuralMethodChanges(MethodInfo currentMethodInfo, MethodInfo otherMethodInfo) {
	// generic signature
	if (!CharOperation.equals(currentMethodInfo.getGenericSignature(), otherMethodInfo.getGenericSignature()))
		return true;
	if (currentMethodInfo.getModifiers() != otherMethodInfo.getModifiers())
		return true;
	if ((currentMethodInfo.getTagBits() & TagBits.AnnotationDeprecated) != (otherMethodInfo.getTagBits() & TagBits.AnnotationDeprecated))
		return true;
	if (hasStructuralAnnotationChanges(currentMethodInfo.getAnnotations(), otherMethodInfo.getAnnotations()))
		return true;
	// parameter annotations:
	int currentAnnotatedParamsCount = currentMethodInfo.getAnnotatedParametersCount();
	int otherAnnotatedParamsCount = otherMethodInfo.getAnnotatedParametersCount();
	if (currentAnnotatedParamsCount != otherAnnotatedParamsCount)
		return true;
	for (int i=0; i<currentAnnotatedParamsCount; i++) {
		if (hasStructuralAnnotationChanges(currentMethodInfo.getParameterAnnotations(i), otherMethodInfo.getParameterAnnotations(i)))
			return true;
	}

	if (!CharOperation.equals(currentMethodInfo.getSelector(), otherMethodInfo.getSelector()))
		return true;
	if (!CharOperation.equals(currentMethodInfo.getMethodDescriptor(), otherMethodInfo.getMethodDescriptor()))
		return true;
	if (!CharOperation.equals(currentMethodInfo.getGenericSignature(), otherMethodInfo.getGenericSignature()))
		return true;

	char[][] currentThrownExceptions = currentMethodInfo.getExceptionTypeNames();
	char[][] otherThrownExceptions = otherMethodInfo.getExceptionTypeNames();
	if (currentThrownExceptions != otherThrownExceptions) { // TypeConstants.NoExceptions
		int currentThrownExceptionsLength = currentThrownExceptions == null ? 0 : currentThrownExceptions.length;
		int otherThrownExceptionsLength = otherThrownExceptions == null ? 0 : otherThrownExceptions.length;
		if (currentThrownExceptionsLength != otherThrownExceptionsLength)
			return true;
		for (int k = 0; k < currentThrownExceptionsLength; k++)
			if (!CharOperation.equals(currentThrownExceptions[k], otherThrownExceptions[k]))
				return true;
	}
	return false;
}

/**
 * This method is used to fully initialize the contents of the receiver. All methodinfos, fields infos
 * will be therefore fully initialized and we can get rid of the bytes.
 */
private void initialize() throws ClassFormatException {
	try {
		for (int i = 0, max = this.fieldsCount; i < max; i++) {
			this.fields[i].initialize();
		}
		for (int i = 0, max = this.methodsCount; i < max; i++) {
			this.methods[i].initialize();
		}
		if (this.innerInfos != null) {
			for (int i = 0, max = this.innerInfos.length; i < max; i++) {
				this.innerInfos[i].initialize();
			}
		}
		if (this.annotations != null) {
			for (int i = 0, max = this.annotations.length; i < max; i++) {
				this.annotations[i].initialize();
			}
		}
		this.getEnclosingMethod();
		reset();
	} catch(RuntimeException e) {
		ClassFormatException exception = new ClassFormatException(e, this.classFileName);
		throw exception;
	}
}

/**
 * Answer true if the receiver is an anonymous type, false otherwise
 *
 * @return <CODE>boolean</CODE>
 */
public boolean isAnonymous() {
	if (this.innerInfo == null) return false;
	char[] innerSourceName = this.innerInfo.getSourceName();
	return (innerSourceName == null || innerSourceName.length == 0);
}

/**
 * Answer whether the receiver contains the resolved binary form
 * or the unresolved source form of the type.
 * @return boolean
 */
public boolean isBinaryType() {
	return true;
}

/**
 * Answer true if the receiver is a local type, false otherwise
 *
 * @return <CODE>boolean</CODE>
 */
public boolean isLocal() {
	if (this.innerInfo == null) return false;
	if (this.innerInfo.getEnclosingTypeName() != null) return false;
	char[] innerSourceName = this.innerInfo.getSourceName();
	return (innerSourceName != null && innerSourceName.length > 0);
}

/**
 * Answer true if the receiver is a member type, false otherwise
 *
 * @return <CODE>boolean</CODE>
 */
public boolean isMember() {
	if (this.innerInfo == null) return false;
	if (this.innerInfo.getEnclosingTypeName() == null) return false;
	char[] innerSourceName = this.innerInfo.getSourceName();
	return (innerSourceName != null && innerSourceName.length > 0);	 // protection against ill-formed attributes (67600)
}

/**
 * Answer true if the receiver is a nested type, false otherwise
 *
 * @return <CODE>boolean</CODE>
 */
public boolean isNestedType() {
	return this.innerInfo != null;
}

/**
 * Answer the source file name attribute. Return null if there is no source file attribute for the receiver.
 *
 * @return char[]
 */
public char[] sourceFileName() {
	return this.sourceFileName;
}

public String toString() {
	java.io.ByteArrayOutputStream out = new java.io.ByteArrayOutputStream();
	java.io.PrintWriter print = new java.io.PrintWriter(out);
	print.println(getClass().getName() + "{"); //$NON-NLS-1$
	print.println(" this.className: " + new String(getName())); //$NON-NLS-1$
	print.println(" this.superclassName: " + (getSuperclassName() == null ? "null" : new String(getSuperclassName()))); //$NON-NLS-2$ //$NON-NLS-1$
	print.println(" access_flags: " + printTypeModifiers(accessFlags()) + "(" + accessFlags() + ")"); //$NON-NLS-1$ //$NON-NLS-3$ //$NON-NLS-2$
	print.flush();
	return out.toString();
}
}
