/*******************************************************************************
 * Copyright (c) 2009, 2017 IBM Corporation and others.
 *
 * 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:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.equinox.p2.internal.repository.comparator.java;

import java.util.Arrays;
import org.eclipse.osgi.util.NLS;

/**
 * Disassembler of .class files. It generates an output in the Writer that looks close to
 * the javap output.
 */
public class Disassembler {
	/**
	 * The mode is the detailed mode to disassemble ClassFileReader. It returns the magic
	 * numbers, the version numbers and field and method descriptors.
	 */
	public final static int DETAILED = 1;

	/**
	 * This mode is used to compact the class name to a simple name instead of a qualified name.
	 * @since 3.1
	 */
	public final static int COMPACT = 8;

	private static final char[] ANY_EXCEPTION = Messages.classfileformat_anyexceptionhandler.toCharArray();
	private static final String VERSION_UNKNOWN = Messages.classfileformat_versionUnknown;

	private boolean appendModifier(StringBuffer buffer, int accessFlags, int modifierConstant, String modifier, boolean firstModifier) {
		if ((accessFlags & modifierConstant) != 0) {
			if (!firstModifier) {
				buffer.append(Messages.disassembler_space);
			}
			if (firstModifier) {
				firstModifier = false;
			}
			buffer.append(modifier);
		}
		return firstModifier;
	}

	private void decodeModifiers(StringBuffer buffer, int accessFlags, int[] checkBits) {
		decodeModifiers(buffer, accessFlags, false, false, checkBits);
	}

	private void decodeModifiers(StringBuffer buffer, int accessFlags, boolean printDefault, boolean asBridge, int[] checkBits) {
		if (checkBits == null)
			return;
		boolean firstModifier = true;
		for (int checkBit : checkBits) {
			switch (checkBit) {
				case IModifierConstants.ACC_PUBLIC :
					firstModifier = appendModifier(buffer, accessFlags, IModifierConstants.ACC_PUBLIC, "public", firstModifier); //$NON-NLS-1$
					break;
				case IModifierConstants.ACC_PROTECTED :
					firstModifier = appendModifier(buffer, accessFlags, IModifierConstants.ACC_PROTECTED, "protected", firstModifier); //$NON-NLS-1$
					break;
				case IModifierConstants.ACC_PRIVATE :
					firstModifier = appendModifier(buffer, accessFlags, IModifierConstants.ACC_PRIVATE, "private", firstModifier); //$NON-NLS-1$
					break;
				case IModifierConstants.ACC_ABSTRACT :
					firstModifier = appendModifier(buffer, accessFlags, IModifierConstants.ACC_ABSTRACT, "abstract", firstModifier); //$NON-NLS-1$
					break;
				case IModifierConstants.ACC_STATIC :
					firstModifier = appendModifier(buffer, accessFlags, IModifierConstants.ACC_STATIC, "static", firstModifier); //$NON-NLS-1$
					break;
				case IModifierConstants.ACC_FINAL :
					firstModifier = appendModifier(buffer, accessFlags, IModifierConstants.ACC_FINAL, "final", firstModifier); //$NON-NLS-1$
					break;
				case IModifierConstants.ACC_SYNCHRONIZED :
					firstModifier = appendModifier(buffer, accessFlags, IModifierConstants.ACC_SYNCHRONIZED, "synchronized", firstModifier); //$NON-NLS-1$
					break;
				case IModifierConstants.ACC_NATIVE :
					firstModifier = appendModifier(buffer, accessFlags, IModifierConstants.ACC_NATIVE, "native", firstModifier); //$NON-NLS-1$
					break;
				case IModifierConstants.ACC_STRICT :
					firstModifier = appendModifier(buffer, accessFlags, IModifierConstants.ACC_STRICT, "strictfp", firstModifier); //$NON-NLS-1$
					break;
				case IModifierConstants.ACC_TRANSIENT :
					firstModifier = appendModifier(buffer, accessFlags, IModifierConstants.ACC_TRANSIENT, "transient", firstModifier); //$NON-NLS-1$
					break;
				case IModifierConstants.ACC_VOLATILE :
					// case IModifierConstants.ACC_BRIDGE :
					if (asBridge) {
						firstModifier = appendModifier(buffer, accessFlags, IModifierConstants.ACC_BRIDGE, "bridge", firstModifier); //$NON-NLS-1$
					} else {
						firstModifier = appendModifier(buffer, accessFlags, IModifierConstants.ACC_VOLATILE, "volatile", firstModifier); //$NON-NLS-1$
					}
					break;
				case IModifierConstants.ACC_ENUM :
					firstModifier = appendModifier(buffer, accessFlags, IModifierConstants.ACC_ENUM, "enum", firstModifier); //$NON-NLS-1$
					break;
			}
		}
		if (!firstModifier) {
			if (!printDefault)
				buffer.append(Messages.disassembler_space);
		} else if (printDefault) {
			// no modifier: package default visibility
			buffer.append("default"); //$NON-NLS-1$
		}
	}

	private void decodeModifiersForField(StringBuffer buffer, int accessFlags) {
		decodeModifiers(buffer, accessFlags, new int[] {IModifierConstants.ACC_PUBLIC, IModifierConstants.ACC_PROTECTED, IModifierConstants.ACC_PRIVATE, IModifierConstants.ACC_STATIC, IModifierConstants.ACC_FINAL, IModifierConstants.ACC_TRANSIENT, IModifierConstants.ACC_VOLATILE, IModifierConstants.ACC_ENUM});
	}

	private final void decodeModifiersForInnerClasses(StringBuffer buffer, int accessFlags, boolean printDefault) {
		decodeModifiers(buffer, accessFlags, printDefault, false, new int[] {IModifierConstants.ACC_PUBLIC, IModifierConstants.ACC_PROTECTED, IModifierConstants.ACC_PRIVATE, IModifierConstants.ACC_ABSTRACT, IModifierConstants.ACC_STATIC, IModifierConstants.ACC_FINAL,});
	}

	private final void decodeModifiersForMethod(StringBuffer buffer, int accessFlags) {
		decodeModifiers(buffer, accessFlags, false, true, new int[] {IModifierConstants.ACC_PUBLIC, IModifierConstants.ACC_PROTECTED, IModifierConstants.ACC_PRIVATE, IModifierConstants.ACC_ABSTRACT, IModifierConstants.ACC_STATIC, IModifierConstants.ACC_FINAL, IModifierConstants.ACC_SYNCHRONIZED, IModifierConstants.ACC_NATIVE, IModifierConstants.ACC_STRICT, IModifierConstants.ACC_BRIDGE,});
	}

	private final void decodeModifiersForType(StringBuffer buffer, int accessFlags) {
		decodeModifiers(buffer, accessFlags, new int[] {IModifierConstants.ACC_PUBLIC, IModifierConstants.ACC_ABSTRACT, IModifierConstants.ACC_FINAL,});
	}

	public static String escapeString(String s) {
		StringBuilder buffer = new StringBuilder();
		for (int i = 0, max = s.length(); i < max; i++) {
			char c = s.charAt(i);
			switch (c) {
				case '\b' :
					buffer.append("\\b"); //$NON-NLS-1$
					break;
				case '\t' :
					buffer.append("\\t"); //$NON-NLS-1$
					break;
				case '\n' :
					buffer.append("\\n"); //$NON-NLS-1$
					break;
				case '\f' :
					buffer.append("\\f"); //$NON-NLS-1$
					break;
				case '\r' :
					buffer.append("\\r"); //$NON-NLS-1$
					break;
				case '\0' :
					buffer.append("\\0"); //$NON-NLS-1$
					break;
				case '\1' :
					buffer.append("\\1"); //$NON-NLS-1$
					break;
				case '\2' :
					buffer.append("\\2"); //$NON-NLS-1$
					break;
				case '\3' :
					buffer.append("\\3"); //$NON-NLS-1$
					break;
				case '\4' :
					buffer.append("\\4"); //$NON-NLS-1$
					break;
				case '\5' :
					buffer.append("\\5"); //$NON-NLS-1$
					break;
				case '\6' :
					buffer.append("\\6"); //$NON-NLS-1$
					break;
				case '\7' :
					buffer.append("\\7"); //$NON-NLS-1$
					break;
				default :
					buffer.append(c);
			}
		}
		return buffer.toString();
	}

	static String decodeStringValue(char[] chars) {
		StringBuilder buffer = new StringBuilder();
		for (char c : chars) {
			switch (c) {
				case '\b' :
					buffer.append("\\b"); //$NON-NLS-1$
					break;
				case '\t' :
					buffer.append("\\t"); //$NON-NLS-1$
					break;
				case '\n' :
					buffer.append("\\n"); //$NON-NLS-1$
					break;
				case '\f' :
					buffer.append("\\f"); //$NON-NLS-1$
					break;
				case '\r' :
					buffer.append("\\r"); //$NON-NLS-1$
					break;
				case '\0' :
					buffer.append("\\0"); //$NON-NLS-1$
					break;
				case '\1' :
					buffer.append("\\1"); //$NON-NLS-1$
					break;
				case '\2' :
					buffer.append("\\2"); //$NON-NLS-1$
					break;
				case '\3' :
					buffer.append("\\3"); //$NON-NLS-1$
					break;
				case '\4' :
					buffer.append("\\4"); //$NON-NLS-1$
					break;
				case '\5' :
					buffer.append("\\5"); //$NON-NLS-1$
					break;
				case '\6' :
					buffer.append("\\6"); //$NON-NLS-1$
					break;
				case '\7' :
					buffer.append("\\7"); //$NON-NLS-1$
					break;
				default :
					buffer.append(c);
			}
		}
		return buffer.toString();
	}

	static String decodeStringValue(String s) {
		return decodeStringValue(s.toCharArray());
	}

	/*
	 * @see org.eclipse.jdt.core.util.ClassFileBytesDisassembler#disassemble(byte[], java.lang.String, int)
	 */
	public String disassemble(byte[] classFileBytes, String lineSeparator, int mode) throws ClassFormatException {
		try {
			return disassemble(new ClassFileReader(classFileBytes, ClassFileReader.ALL), lineSeparator, mode);
		} catch (ArrayIndexOutOfBoundsException e) {
			throw new ClassFormatException(e.getMessage(), e);
		}
	}

	private void disassemble(Annotation annotation, StringBuffer buffer, String lineSeparator, int tabNumber, int mode) {
		writeNewLine(buffer, lineSeparator, tabNumber + 1);
		final char[] typeName = CharOperation.replaceOnCopy(annotation.getTypeName(), '/', '.');
		buffer.append(NLS.bind(Messages.disassembler_annotationentrystart, new String[] {new String(returnClassName(Signature.toCharArray(typeName), '.', mode))}));
		for (AnnotationComponent component : annotation.getComponents()) {
			disassemble(component, buffer, lineSeparator, tabNumber + 1, mode);
		}
		writeNewLine(buffer, lineSeparator, tabNumber + 1);
		buffer.append(Messages.disassembler_annotationentryend);
	}

	private void disassemble(AnnotationComponent annotationComponent, StringBuffer buffer, String lineSeparator, int tabNumber, int mode) {
		writeNewLine(buffer, lineSeparator, tabNumber + 1);
		buffer.append(NLS.bind(Messages.disassembler_annotationcomponent, new String[] {new String(annotationComponent.getComponentName())}));
		disassemble(annotationComponent.getComponentValue(), buffer, lineSeparator, tabNumber + 1, mode);
	}

	private void disassemble(AnnotationComponentValue annotationComponentValue, StringBuffer buffer, String lineSeparator, int tabNumber, int mode) {
		switch (annotationComponentValue.getTag()) {
			case AnnotationComponentValue.BYTE_TAG :
			case AnnotationComponentValue.CHAR_TAG :
			case AnnotationComponentValue.DOUBLE_TAG :
			case AnnotationComponentValue.FLOAT_TAG :
			case AnnotationComponentValue.INTEGER_TAG :
			case AnnotationComponentValue.LONG_TAG :
			case AnnotationComponentValue.SHORT_TAG :
			case AnnotationComponentValue.BOOLEAN_TAG :
			case AnnotationComponentValue.STRING_TAG :
				ConstantPoolEntry constantPoolEntry = annotationComponentValue.getConstantValue();
				String value = null;
				switch (constantPoolEntry.getKind()) {
					case ConstantPoolConstant.CONSTANT_Long :
						value = constantPoolEntry.getLongValue() + "L"; //$NON-NLS-1$
						break;
					case ConstantPoolConstant.CONSTANT_Float :
						value = constantPoolEntry.getFloatValue() + "f"; //$NON-NLS-1$
						break;
					case ConstantPoolConstant.CONSTANT_Double :
						value = Double.toString(constantPoolEntry.getDoubleValue());
						break;
					case ConstantPoolConstant.CONSTANT_Integer :
						switch (annotationComponentValue.getTag()) {
							case AnnotationComponentValue.CHAR_TAG :
								value = "'" + (char) constantPoolEntry.getIntegerValue() + "'"; //$NON-NLS-1$//$NON-NLS-2$
								break;
							case AnnotationComponentValue.BOOLEAN_TAG :
								value = constantPoolEntry.getIntegerValue() == 1 ? "true" : "false";//$NON-NLS-1$//$NON-NLS-2$
								break;
							case AnnotationComponentValue.BYTE_TAG :
								value = "(byte) " + constantPoolEntry.getIntegerValue(); //$NON-NLS-1$
								break;
							case AnnotationComponentValue.SHORT_TAG :
								value = "(short) " + constantPoolEntry.getIntegerValue(); //$NON-NLS-1$
								break;
							case AnnotationComponentValue.INTEGER_TAG :
								value = "(int) " + constantPoolEntry.getIntegerValue(); //$NON-NLS-1$
						}
						break;
					case ConstantPoolConstant.CONSTANT_Utf8 :
						value = "\"" + decodeStringValue(constantPoolEntry.getUtf8Value()) + "\"";//$NON-NLS-1$//$NON-NLS-2$
				}
				buffer.append(NLS.bind(Messages.disassembler_annotationdefaultvalue, value));
				break;
			case AnnotationComponentValue.ENUM_TAG :
				final char[] typeName = CharOperation.replaceOnCopy(annotationComponentValue.getEnumConstantTypeName(), '/', '.');
				final char[] constantName = annotationComponentValue.getEnumConstantName();
				buffer.append(NLS.bind(Messages.disassembler_annotationenumvalue, new String[] {new String(returnClassName(Signature.toCharArray(typeName), '.', mode)), new String(constantName)}));
				break;
			case AnnotationComponentValue.CLASS_TAG :
				constantPoolEntry = annotationComponentValue.getClassInfo();
				final char[] className = CharOperation.replaceOnCopy(constantPoolEntry.getUtf8Value(), '/', '.');
				buffer.append(NLS.bind(Messages.disassembler_annotationclassvalue, new String[] {new String(returnClassName(Signature.toCharArray(className), '.', mode))}));
				break;
			case AnnotationComponentValue.ANNOTATION_TAG :
				buffer.append(Messages.disassembler_annotationannotationvalue);
				Annotation annotation = annotationComponentValue.getAnnotationValue();
				disassemble(annotation, buffer, lineSeparator, tabNumber + 1, mode);
				break;
			case AnnotationComponentValue.ARRAY_TAG:
				buffer.append(Messages.disassembler_annotationarrayvaluestart);
				final AnnotationComponentValue[] annotationComponentValues = annotationComponentValue
					.getAnnotationComponentValues();
				for (AnnotationComponentValue annotationComponentValue2 : annotationComponentValues) {
					writeNewLine(buffer, lineSeparator, tabNumber + 1);
					disassemble(annotationComponentValue2, buffer, lineSeparator, tabNumber + 1, mode);
				}
				writeNewLine(buffer, lineSeparator, tabNumber + 1);
				buffer.append(Messages.disassembler_annotationarrayvalueend);
		}
	}

	private void disassemble(AnnotationDefaultAttribute annotationDefaultAttribute, StringBuffer buffer, String lineSeparator, int tabNumber, int mode) {
		writeNewLine(buffer, lineSeparator, tabNumber + 1);
		buffer.append(Messages.disassembler_annotationdefaultheader);
		AnnotationComponentValue componentValue = annotationDefaultAttribute.getMemberValue();
		writeNewLine(buffer, lineSeparator, tabNumber + 2);
		disassemble(componentValue, buffer, lineSeparator, tabNumber + 1, mode);
	}

	/**
	 * Disassemble a method info header
	 */
	private void disassemble(ClassFileReader classFileReader, char[] className, MethodInfo methodInfo, StringBuffer buffer, String lineSeparator, int tabNumber, int mode) {
		writeNewLine(buffer, lineSeparator, tabNumber);
		final CodeAttribute codeAttribute = methodInfo.getCodeAttribute();
		final char[] methodDescriptor = methodInfo.getDescriptor();
		final SignatureAttribute signatureAttribute = (SignatureAttribute) Utility.getAttribute(methodInfo, AttributeNamesConstants.SIGNATURE);
		final ClassFileAttribute runtimeVisibleAnnotationsAttribute = Utility.getAttribute(methodInfo, AttributeNamesConstants.RUNTIME_VISIBLE_ANNOTATIONS);
		final ClassFileAttribute runtimeInvisibleAnnotationsAttribute = Utility.getAttribute(methodInfo, AttributeNamesConstants.RUNTIME_INVISIBLE_ANNOTATIONS);
		final ClassFileAttribute runtimeVisibleParameterAnnotationsAttribute = Utility.getAttribute(methodInfo, AttributeNamesConstants.RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS);
		final ClassFileAttribute runtimeInvisibleParameterAnnotationsAttribute = Utility.getAttribute(methodInfo, AttributeNamesConstants.RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS);
		final ClassFileAttribute annotationDefaultAttribute = Utility.getAttribute(methodInfo, AttributeNamesConstants.ANNOTATION_DEFAULT);
		if (checkMode(mode, DETAILED)) {
			buffer.append(NLS.bind(Messages.classfileformat_methoddescriptor, new String[] {new String(methodDescriptor)}));
			if (methodInfo.isDeprecated()) {
				buffer.append(Messages.disassembler_deprecated);
			}
			writeNewLine(buffer, lineSeparator, tabNumber);
			if (signatureAttribute != null) {
				buffer.append(NLS.bind(Messages.disassembler_signatureattributeheader, new String(signatureAttribute.getSignature())));
				writeNewLine(buffer, lineSeparator, tabNumber);
			}
			if (codeAttribute != null) {
				buffer.append(NLS.bind(Messages.classfileformat_stacksAndLocals, new String[] {Integer.toString(codeAttribute.getMaxStack()), Integer.toString(codeAttribute.getMaxLocals())}));
				writeNewLine(buffer, lineSeparator, tabNumber);
			}
			// disassemble compact version of annotations
			if (runtimeInvisibleAnnotationsAttribute != null) {
				disassembleAsModifier((RuntimeInvisibleAnnotationsAttribute) runtimeInvisibleAnnotationsAttribute, buffer, lineSeparator, tabNumber, mode);
				writeNewLine(buffer, lineSeparator, tabNumber);
			}
			if (runtimeVisibleAnnotationsAttribute != null) {
				disassembleAsModifier((RuntimeVisibleAnnotationsAttribute) runtimeVisibleAnnotationsAttribute, buffer, lineSeparator, tabNumber, mode);
				writeNewLine(buffer, lineSeparator, tabNumber);
			}
		}
		final int accessFlags = methodInfo.getAccessFlags();
		decodeModifiersForMethod(buffer, accessFlags);
		if (methodInfo.isSynthetic()) {
			buffer.append("synthetic"); //$NON-NLS-1$
			buffer.append(Messages.disassembler_space);
		}
		CharOperation.replace(methodDescriptor, '/', '.');
		final boolean isVarArgs = isVarArgs(methodInfo);
		char[] methodHeader = null;
		if (methodInfo.isConstructor()) {
			methodHeader = Signature.toCharArray(methodDescriptor, returnClassName(className, '.', COMPACT), null, !checkMode(mode, COMPACT), false, isVarArgs);
		} else if (methodInfo.isClinit()) {
			methodHeader = Messages.classfileformat_clinitname.toCharArray();
		} else {
			methodHeader = Signature.toCharArray(methodDescriptor, methodInfo.getName(), null, !checkMode(mode, COMPACT), true, isVarArgs);
		}
		if (checkMode(mode, DETAILED) && (runtimeInvisibleParameterAnnotationsAttribute != null || runtimeVisibleParameterAnnotationsAttribute != null)) {
			ParameterAnnotation[] invisibleParameterAnnotations = null;
			ParameterAnnotation[] visibleParameterAnnotations = null;
			int length = -1;
			if (runtimeInvisibleParameterAnnotationsAttribute != null) {
				RuntimeInvisibleParameterAnnotationsAttribute attribute = (RuntimeInvisibleParameterAnnotationsAttribute) runtimeInvisibleParameterAnnotationsAttribute;
				invisibleParameterAnnotations = attribute.getParameterAnnotations();
				length = invisibleParameterAnnotations.length;
			}
			if (runtimeVisibleParameterAnnotationsAttribute != null) {
				RuntimeVisibleParameterAnnotationsAttribute attribute = (RuntimeVisibleParameterAnnotationsAttribute) runtimeVisibleParameterAnnotationsAttribute;
				visibleParameterAnnotations = attribute.getParameterAnnotations();
				length = visibleParameterAnnotations.length;
			}
			int insertionPosition = CharOperation.indexOf('(', methodHeader) + 1;
			int start = 0;
			StringBuffer stringBuffer = new StringBuffer();
			stringBuffer.append(methodHeader, 0, insertionPosition);
			for (int i = 0; i < length; i++) {
				if (i > 0) {
					stringBuffer.append(' ');
				}
				int stringBufferSize = stringBuffer.length();
				if (runtimeVisibleParameterAnnotationsAttribute != null) {
					disassembleAsModifier((RuntimeVisibleParameterAnnotationsAttribute) runtimeVisibleParameterAnnotationsAttribute, stringBuffer, i, lineSeparator, tabNumber, mode);
				}
				if (runtimeInvisibleParameterAnnotationsAttribute != null) {
					if (stringBuffer.length() != stringBufferSize) {
						stringBuffer.append(' ');
						stringBufferSize = stringBuffer.length();
					}
					disassembleAsModifier((RuntimeInvisibleParameterAnnotationsAttribute) runtimeInvisibleParameterAnnotationsAttribute, stringBuffer, i, lineSeparator, tabNumber, mode);
				}
				if (i == 0 && stringBuffer.length() != stringBufferSize) {
					stringBuffer.append(' ');
				}
				start = insertionPosition;
				insertionPosition = CharOperation.indexOf(',', methodHeader, start + 1) + 1;
				if (insertionPosition == 0) {
					stringBuffer.append(methodHeader, start, methodHeader.length - start);
				} else {
					stringBuffer.append(methodHeader, start, insertionPosition - start);
				}
			}
			buffer.append(stringBuffer);
		} else {
			buffer.append(methodHeader);
		}
		ExceptionAttribute exceptionAttribute = methodInfo.getExceptionAttribute();
		if (exceptionAttribute != null) {
			buffer.append(" throws "); //$NON-NLS-1$
			char[][] exceptionNames = exceptionAttribute.getExceptionNames();
			int length = exceptionNames.length;
			for (int i = 0; i < length; i++) {
				if (i != 0) {
					buffer.append(Messages.disassembler_comma).append(Messages.disassembler_space);
				}
				char[] exceptionName = exceptionNames[i];
				CharOperation.replace(exceptionName, '/', '.');
				buffer.append(returnClassName(exceptionName, '.', mode));
			}
		}
		if (checkMode(mode, DETAILED)) {
			if (annotationDefaultAttribute != null) {
				buffer.append(" default "); //$NON-NLS-1$
				disassembleAsModifier((AnnotationDefaultAttribute) annotationDefaultAttribute, buffer, lineSeparator, tabNumber, mode);
			}
		}
		buffer.append(Messages.disassembler_endofmethodheader);

		if (checkMode(mode, DETAILED)) {
			if (codeAttribute != null) {
				disassemble(codeAttribute, methodDescriptor, (accessFlags & IModifierConstants.ACC_STATIC) != 0, buffer, lineSeparator, tabNumber, mode);
			}
			if (annotationDefaultAttribute != null) {
				disassemble((AnnotationDefaultAttribute) annotationDefaultAttribute, buffer, lineSeparator, tabNumber, mode);
			}
			if (runtimeVisibleAnnotationsAttribute != null) {
				disassemble((RuntimeVisibleAnnotationsAttribute) runtimeVisibleAnnotationsAttribute, buffer, lineSeparator, tabNumber, mode);
			}
			if (runtimeInvisibleAnnotationsAttribute != null) {
				disassemble((RuntimeInvisibleAnnotationsAttribute) runtimeInvisibleAnnotationsAttribute, buffer, lineSeparator, tabNumber, mode);
			}
			if (runtimeVisibleParameterAnnotationsAttribute != null) {
				disassemble((RuntimeVisibleParameterAnnotationsAttribute) runtimeVisibleParameterAnnotationsAttribute, buffer, lineSeparator, tabNumber, mode);
			}
			if (runtimeInvisibleParameterAnnotationsAttribute != null) {
				disassemble((RuntimeInvisibleParameterAnnotationsAttribute) runtimeInvisibleParameterAnnotationsAttribute, buffer, lineSeparator, tabNumber, mode);
			}
		}
	}

	/**
	 * Answers back the disassembled string of the ClassFileReader according to the
	 * mode.
	 * This is an output quite similar to the javap tool.
	 *
	 * @param classFileReader The classFileReader to be disassembled
	 * @param lineSeparator the line separator to use.
	 * @param mode the mode used to disassemble the ClassFileReader
	 *
	 * @return the disassembled string of the ClassFileReader according to the mode
	 */
	private String disassemble(ClassFileReader classFileReader, String lineSeparator, int mode) {
		if (classFileReader == null)
			return Utility.EMPTY_STRING;
		char[] className = classFileReader.getClassName();
		if (className == null) {
			// incomplete initialization. We cannot go further.
			return Utility.EMPTY_STRING;
		}
		className = CharOperation.replaceOnCopy(className, '/', '.');
		final int accessFlags = classFileReader.getAccessFlags();
		final boolean isEnum = (accessFlags & IModifierConstants.ACC_ENUM) != 0;

		StringBuffer buffer = new StringBuffer();
		SourceFileAttribute sourceAttribute = classFileReader.getSourceFileAttribute();
		ClassFileAttribute classFileAttribute = Utility.getAttribute(classFileReader, AttributeNamesConstants.SIGNATURE);
		SignatureAttribute signatureAttribute = (SignatureAttribute) classFileAttribute;
		if (checkMode(mode, DETAILED)) {
			int minorVersion = classFileReader.getMinorVersion();
			int majorVersion = classFileReader.getMajorVersion();
			buffer.append(Messages.disassembler_begincommentline);
			if (sourceAttribute != null) {
				buffer.append(Messages.disassembler_sourceattributeheader);
				buffer.append(sourceAttribute.getSourceFileName());
			}
			String versionNumber = VERSION_UNKNOWN;
			if (minorVersion == 3 && majorVersion == 45) {
				versionNumber = IModifierConstants.VERSION_1_1;
			} else if (minorVersion == 0 && majorVersion == 46) {
				versionNumber = IModifierConstants.VERSION_1_2;
			} else if (minorVersion == 0 && majorVersion == 47) {
				versionNumber = IModifierConstants.VERSION_1_3;
			} else if (minorVersion == 0 && majorVersion == 48) {
				versionNumber = IModifierConstants.VERSION_1_4;
			} else if (minorVersion == 0 && majorVersion == 49) {
				versionNumber = IModifierConstants.VERSION_1_5;
			} else if (minorVersion == 0 && majorVersion == 50) {
				versionNumber = IModifierConstants.VERSION_1_6;
			} else if (minorVersion == 0 && majorVersion == 51) {
				versionNumber = IModifierConstants.VERSION_1_7;
			}
			buffer.append(NLS.bind(Messages.classfileformat_versiondetails, new String[] {versionNumber, Integer.toString(majorVersion), Integer.toString(minorVersion), ((accessFlags & IModifierConstants.ACC_SUPER) != 0 ? Messages.classfileformat_superflagisset : Messages.classfileformat_superflagisnotset) + (isDeprecated(classFileReader) ? ", deprecated" : Utility.EMPTY_STRING)//$NON-NLS-1$
			}));
			writeNewLine(buffer, lineSeparator, 0);
			if (signatureAttribute != null) {
				buffer.append(NLS.bind(Messages.disassembler_signatureattributeheader, new String(signatureAttribute.getSignature())));
				writeNewLine(buffer, lineSeparator, 0);
			}
		}

		InnerClassesAttribute innerClassesAttribute = classFileReader.getInnerClassesAttribute();
		ClassFileAttribute runtimeVisibleAnnotationsAttribute = Utility.getAttribute(classFileReader, AttributeNamesConstants.RUNTIME_VISIBLE_ANNOTATIONS);
		ClassFileAttribute runtimeInvisibleAnnotationsAttribute = Utility.getAttribute(classFileReader, AttributeNamesConstants.RUNTIME_INVISIBLE_ANNOTATIONS);

		if (checkMode(mode, DETAILED)) {
			// disassemble compact version of annotations
			if (runtimeInvisibleAnnotationsAttribute != null) {
				disassembleAsModifier((RuntimeInvisibleAnnotationsAttribute) runtimeInvisibleAnnotationsAttribute, buffer, lineSeparator, 0, mode);
				writeNewLine(buffer, lineSeparator, 0);
			}
			if (runtimeVisibleAnnotationsAttribute != null) {
				disassembleAsModifier((RuntimeVisibleAnnotationsAttribute) runtimeVisibleAnnotationsAttribute, buffer, lineSeparator, 0, mode);
				writeNewLine(buffer, lineSeparator, 0);
			}
		}
		boolean decoded = false;
		if (innerClassesAttribute != null) {
			// search the right entry
			InnerClassesAttributeEntry[] entries = innerClassesAttribute.getInnerClassAttributesEntries();
			for (InnerClassesAttributeEntry entry : entries) {
				char[] innerClassName = entry.getInnerClassName();
				if (innerClassName != null) {
					if (Arrays.equals(classFileReader.getClassName(), innerClassName)) {
						decodeModifiersForInnerClasses(buffer, entry.getAccessFlags(), false);
						decoded = true;
					}
				}
			}
		}
		if (!decoded) {
			decodeModifiersForType(buffer, accessFlags);
			if (isSynthetic(classFileReader)) {
				buffer.append("synthetic"); //$NON-NLS-1$
				buffer.append(Messages.disassembler_space);
			}
		}

		final boolean isAnnotation = (accessFlags & IModifierConstants.ACC_ANNOTATION) != 0;
		boolean isInterface = false;
		if (isEnum) {
			buffer.append("enum "); //$NON-NLS-1$
		} else if (classFileReader.isClass()) {
			buffer.append("class "); //$NON-NLS-1$
		} else {
			if (isAnnotation) {
				buffer.append("@"); //$NON-NLS-1$
			}
			buffer.append("interface "); //$NON-NLS-1$
			isInterface = true;
		}

		buffer.append(className);

		char[] superclassName = classFileReader.getSuperclassName();
		if (superclassName != null) {
			CharOperation.replace(superclassName, '/', '.');
			if (!isJavaLangObject(superclassName) && !isEnum) {
				buffer.append(" extends "); //$NON-NLS-1$
				buffer.append(returnClassName(superclassName, '.', mode));
			}
		}
		if (!isAnnotation) {
			char[][] superclassInterfaces = classFileReader.getInterfaceNames();
			int length = superclassInterfaces.length;
			if (length != 0) {
				if (isInterface) {
					buffer.append(" extends "); //$NON-NLS-1$
				} else {
					buffer.append(" implements "); //$NON-NLS-1$
				}
				for (int i = 0; i < length; i++) {
					if (i != 0) {
						buffer.append(Messages.disassembler_comma).append(Messages.disassembler_space);
					}
					char[] superinterface = superclassInterfaces[i];
					CharOperation.replace(superinterface, '/', '.');
					buffer.append(returnClassName(superinterface, '.', mode));
				}
			}
		}
		buffer.append(Messages.disassembler_opentypedeclaration);
		disassembleTypeMembers(classFileReader, className, buffer, lineSeparator, 1, mode, isEnum);
		if (checkMode(mode, DETAILED)) {
			ClassFileAttribute[] attributes = classFileReader.getAttributes();
			int length = attributes.length;
			EnclosingMethodAttribute enclosingMethodAttribute = getEnclosingMethodAttribute(classFileReader);
			int remainingAttributesLength = length;
			if (innerClassesAttribute != null) {
				remainingAttributesLength--;
			}
			if (enclosingMethodAttribute != null) {
				remainingAttributesLength--;
			}
			if (sourceAttribute != null) {
				remainingAttributesLength--;
			}
			if (signatureAttribute != null) {
				remainingAttributesLength--;
			}
			if (innerClassesAttribute != null || enclosingMethodAttribute != null || remainingAttributesLength != 0) {
				writeNewLine(buffer, lineSeparator, 0);
			}
			if (innerClassesAttribute != null) {
				disassemble(innerClassesAttribute, buffer, lineSeparator, 1);
			}
			if (enclosingMethodAttribute != null) {
				disassemble(enclosingMethodAttribute, buffer, lineSeparator, 0);
			}
			if (runtimeVisibleAnnotationsAttribute != null) {
				disassemble((RuntimeVisibleAnnotationsAttribute) runtimeVisibleAnnotationsAttribute, buffer, lineSeparator, 0, mode);
			}
			if (runtimeInvisibleAnnotationsAttribute != null) {
				disassemble((RuntimeInvisibleAnnotationsAttribute) runtimeInvisibleAnnotationsAttribute, buffer, lineSeparator, 0, mode);
			}
		}
		writeNewLine(buffer, lineSeparator, 0);
		buffer.append(Messages.disassembler_closetypedeclaration);
		return buffer.toString();
	}

	private boolean isJavaLangObject(final char[] className) {
		return Arrays.equals(TypeConstants.JAVA_LANG_OBJECT, CharOperation.splitOn('.', className));
	}

	private boolean isVarArgs(MethodInfo methodInfo) {
		int accessFlags = methodInfo.getAccessFlags();
		if ((accessFlags & IModifierConstants.ACC_VARARGS) != 0)
			return true;
		// check the presence of the unspecified Varargs attribute
		return Utility.getAttribute(methodInfo, AttributeNamesConstants.VAR_ARGS) != null;
	}

	private void disassemble(CodeAttribute codeAttribute, char[] methodDescriptor, boolean isStatic, StringBuffer buffer, String lineSeparator, int tabNumber, int mode) {
		writeNewLine(buffer, lineSeparator, tabNumber - 1);
		DefaultBytecodeVisitor visitor = new DefaultBytecodeVisitor(codeAttribute, methodDescriptor, isStatic, buffer, lineSeparator, tabNumber, mode);
		try {
			codeAttribute.traverse(visitor);
		} catch (ClassFormatException e) {
			dumpTab(tabNumber + 2, buffer);
			buffer.append(Messages.classformat_classformatexception);
			writeNewLine(buffer, lineSeparator, tabNumber + 1);
		}
		final int exceptionTableLength = codeAttribute.getExceptionTableLength();
		if (exceptionTableLength != 0) {
			final int tabNumberForExceptionAttribute = tabNumber + 2;
			dumpTab(tabNumberForExceptionAttribute, buffer);
			final ExceptionTableEntry[] exceptionTableEntries = codeAttribute.getExceptionTable();
			buffer.append(Messages.disassembler_exceptiontableheader);
			writeNewLine(buffer, lineSeparator, tabNumberForExceptionAttribute + 1);
			for (int i = 0; i < exceptionTableLength; i++) {
				if (i != 0) {
					writeNewLine(buffer, lineSeparator, tabNumberForExceptionAttribute + 1);
				}
				ExceptionTableEntry exceptionTableEntry = exceptionTableEntries[i];
				char[] catchType;
				if (exceptionTableEntry.getCatchTypeIndex() != 0) {
					catchType = exceptionTableEntry.getCatchType();
					CharOperation.replace(catchType, '/', '.');
					catchType = returnClassName(catchType, '.', mode);
				} else {
					catchType = ANY_EXCEPTION;
				}
				buffer.append(NLS.bind(Messages.classfileformat_exceptiontableentry, new String[] {Integer.toString(exceptionTableEntry.getStartPC()), Integer.toString(exceptionTableEntry.getEndPC()), Integer.toString(exceptionTableEntry.getHandlerPC()), new String(catchType),}));
			}
		}
	}

	private void disassemble(EnclosingMethodAttribute enclosingMethodAttribute, StringBuffer buffer, String lineSeparator, int tabNumber) {
		writeNewLine(buffer, lineSeparator, tabNumber + 1);
		buffer.append(Messages.disassembler_enclosingmethodheader);
		buffer.append(" ")//$NON-NLS-1$
				.append(enclosingMethodAttribute.getEnclosingClass());
		if (enclosingMethodAttribute.getMethodNameAndTypeIndex() != 0) {
			buffer.append(".")//$NON-NLS-1$
					.append(enclosingMethodAttribute.getMethodName()).append(enclosingMethodAttribute.getMethodDescriptor());
		}
	}

	/**
	 * Disassemble a field info
	 */
	private void disassemble(FieldInfo fieldInfo, StringBuffer buffer, String lineSeparator, int tabNumber, int mode) {
		writeNewLine(buffer, lineSeparator, tabNumber);
		final char[] fieldDescriptor = fieldInfo.getDescriptor();
		final SignatureAttribute signatureAttribute = (SignatureAttribute) Utility.getAttribute(fieldInfo, AttributeNamesConstants.SIGNATURE);
		if (checkMode(mode, DETAILED)) {
			buffer.append(NLS.bind(Messages.classfileformat_fieldddescriptor, new String[] {new String(fieldDescriptor)}));
			if (fieldInfo.isDeprecated()) {
				buffer.append(Messages.disassembler_deprecated);
			}
			writeNewLine(buffer, lineSeparator, tabNumber);
			if (signatureAttribute != null) {
				buffer.append(NLS.bind(Messages.disassembler_signatureattributeheader, new String(signatureAttribute.getSignature())));
				writeNewLine(buffer, lineSeparator, tabNumber);
			}
		}
		final ClassFileAttribute runtimeVisibleAnnotationsAttribute = Utility.getAttribute(fieldInfo, AttributeNamesConstants.RUNTIME_VISIBLE_ANNOTATIONS);
		final ClassFileAttribute runtimeInvisibleAnnotationsAttribute = Utility.getAttribute(fieldInfo, AttributeNamesConstants.RUNTIME_INVISIBLE_ANNOTATIONS);
		if (checkMode(mode, DETAILED)) {
			// disassemble compact version of annotations
			if (runtimeInvisibleAnnotationsAttribute != null) {
				disassembleAsModifier((RuntimeInvisibleAnnotationsAttribute) runtimeInvisibleAnnotationsAttribute, buffer, lineSeparator, tabNumber, mode);
				writeNewLine(buffer, lineSeparator, tabNumber);
			}
			if (runtimeVisibleAnnotationsAttribute != null) {
				disassembleAsModifier((RuntimeVisibleAnnotationsAttribute) runtimeVisibleAnnotationsAttribute, buffer, lineSeparator, tabNumber, mode);
				writeNewLine(buffer, lineSeparator, tabNumber);
			}
		}
		decodeModifiersForField(buffer, fieldInfo.getAccessFlags());
		if (fieldInfo.isSynthetic()) {
			buffer.append("synthetic"); //$NON-NLS-1$
			buffer.append(Messages.disassembler_space);
		}
		buffer.append(returnClassName(getSignatureForField(fieldDescriptor), '.', mode));
		buffer.append(' ');
		buffer.append(new String(fieldInfo.getName()));
		ConstantValueAttribute constantValueAttribute = fieldInfo.getConstantValueAttribute();
		if (constantValueAttribute != null) {
			buffer.append(Messages.disassembler_fieldhasconstant);
			ConstantPoolEntry constantPoolEntry = constantValueAttribute.getConstantValue();
			switch (constantPoolEntry.getKind()) {
				case ConstantPoolConstant.CONSTANT_Long :
					buffer.append(constantPoolEntry.getLongValue() + "L"); //$NON-NLS-1$
					break;
				case ConstantPoolConstant.CONSTANT_Float :
					buffer.append(constantPoolEntry.getFloatValue() + "f"); //$NON-NLS-1$
					break;
				case ConstantPoolConstant.CONSTANT_Double :
					buffer.append(constantPoolEntry.getDoubleValue());
					break;
				case ConstantPoolConstant.CONSTANT_Integer :
					switch (fieldDescriptor[0]) {
						case 'C' :
							buffer.append("'" + (char) constantPoolEntry.getIntegerValue() + "'"); //$NON-NLS-1$//$NON-NLS-2$
							break;
						case 'Z' :
							buffer.append(constantPoolEntry.getIntegerValue() == 1 ? "true" : "false");//$NON-NLS-1$//$NON-NLS-2$
							break;
						case 'B' :
							buffer.append(constantPoolEntry.getIntegerValue());
							break;
						case 'S' :
							buffer.append(constantPoolEntry.getIntegerValue());
							break;
						case 'I' :
							buffer.append(constantPoolEntry.getIntegerValue());
					}
					break;
				case ConstantPoolConstant.CONSTANT_String :
					buffer.append("\"" + decodeStringValue(constantPoolEntry.getStringValue()) + "\"");//$NON-NLS-1$//$NON-NLS-2$
			}
		}
		buffer.append(Messages.disassembler_endoffieldheader);
		if (checkMode(mode, DETAILED)) {
			if (runtimeVisibleAnnotationsAttribute != null) {
				disassemble((RuntimeVisibleAnnotationsAttribute) runtimeVisibleAnnotationsAttribute, buffer, lineSeparator, tabNumber, mode);
			}
			if (runtimeInvisibleAnnotationsAttribute != null) {
				disassemble((RuntimeInvisibleAnnotationsAttribute) runtimeInvisibleAnnotationsAttribute, buffer, lineSeparator, tabNumber, mode);
			}
		}
	}

	private void disassemble(InnerClassesAttribute innerClassesAttribute, StringBuffer buffer, String lineSeparator, int tabNumber) {
		writeNewLine(buffer, lineSeparator, tabNumber);
		buffer.append(Messages.disassembler_innerattributesheader);
		writeNewLine(buffer, lineSeparator, tabNumber + 1);
		InnerClassesAttributeEntry[] innerClassesAttributeEntries = innerClassesAttribute.getInnerClassAttributesEntries();
		int length = innerClassesAttributeEntries.length;
		int innerClassNameIndex, outerClassNameIndex, innerNameIndex, accessFlags;
		InnerClassesAttributeEntry innerClassesAttributeEntry;
		if (length > 1) {
			final char[] EMPTY_CHAR_ARRAY = Utility.EMPTY_STRING.toCharArray();
			Arrays.sort(innerClassesAttributeEntries, (o1, o2) -> {
				final char[] innerClassName1 = o1.getInnerClassName();
				final char[] innerClassName2 = o2.getInnerClassName();
				final char[] innerName1 = o1.getInnerName();
				final char[] innerName2 = o2.getInnerName();
				final char[] outerClassName1 = o1.getOuterClassName();
				final char[] outerClassName2 = o2.getOuterClassName();
				StringBuilder buffer1 = new StringBuilder();
				buffer1.append(innerClassName1 == null ? EMPTY_CHAR_ARRAY : innerClassName1);
				buffer1.append(innerName1 == null ? EMPTY_CHAR_ARRAY : innerName1);
				buffer1.append(outerClassName1 == null ? EMPTY_CHAR_ARRAY : outerClassName1);
				StringBuilder buffer2 = new StringBuilder();
				buffer2.append(innerClassName2 == null ? EMPTY_CHAR_ARRAY : innerClassName2);
				buffer2.append(innerName2 == null ? EMPTY_CHAR_ARRAY : innerName2);
				buffer2.append(outerClassName2 == null ? EMPTY_CHAR_ARRAY : outerClassName2);
				return buffer1.toString().compareTo(buffer2.toString());
			});
		}
		for (int i = 0; i < length; i++) {
			if (i != 0) {
				buffer.append(Messages.disassembler_comma);
				writeNewLine(buffer, lineSeparator, tabNumber + 1);
			}
			innerClassesAttributeEntry = innerClassesAttributeEntries[i];
			innerClassNameIndex = innerClassesAttributeEntry.getInnerClassNameIndex();
			outerClassNameIndex = innerClassesAttributeEntry.getOuterClassNameIndex();
			innerNameIndex = innerClassesAttributeEntry.getInnerNameIndex();
			accessFlags = innerClassesAttributeEntry.getAccessFlags();
			buffer.append(Messages.disassembler_openinnerclassentry).append(Messages.disassembler_inner_class_info_name);
			if (innerClassNameIndex != 0) {
				buffer.append(Messages.disassembler_space).append(innerClassesAttributeEntry.getInnerClassName());
			}
			buffer.append(Messages.disassembler_comma).append(Messages.disassembler_space).append(Messages.disassembler_outer_class_info_name);
			if (outerClassNameIndex != 0) {
				buffer.append(Messages.disassembler_space).append(innerClassesAttributeEntry.getOuterClassName());
			}
			writeNewLine(buffer, lineSeparator, tabNumber);
			dumpTab(tabNumber, buffer);
			buffer.append(Messages.disassembler_space);
			buffer.append(Messages.disassembler_inner_name);
			if (innerNameIndex != 0) {
				buffer.append(Messages.disassembler_space).append(innerClassesAttributeEntry.getInnerName());
			}
			buffer.append(Messages.disassembler_comma).append(Messages.disassembler_space).append(Messages.disassembler_inner_accessflags).append(accessFlags).append(Messages.disassembler_space);
			decodeModifiersForInnerClasses(buffer, accessFlags, true);
			buffer.append(Messages.disassembler_closeinnerclassentry);
		}
	}

	private void disassemble(int index, ParameterAnnotation parameterAnnotation, StringBuffer buffer, String lineSeparator, int tabNumber, int mode) {
		Annotation[] annotations = parameterAnnotation.getAnnotations();
		writeNewLine(buffer, lineSeparator, tabNumber + 1);
		buffer.append(NLS.bind(Messages.disassembler_parameterannotationentrystart, new String[] {Integer.toString(index), Integer.toString(annotations.length)}));
		for (Annotation annotation : annotations) {
			disassemble(annotation, buffer, lineSeparator, tabNumber + 1, mode);
		}
	}

	private void disassemble(RuntimeInvisibleAnnotationsAttribute runtimeInvisibleAnnotationsAttribute, StringBuffer buffer, String lineSeparator, int tabNumber, int mode) {
		writeNewLine(buffer, lineSeparator, tabNumber + 1);
		buffer.append(Messages.disassembler_runtimeinvisibleannotationsattributeheader);
		Annotation[] annotations = runtimeInvisibleAnnotationsAttribute.getAnnotations();
		for (Annotation annotation : annotations) {
			disassemble(annotation, buffer, lineSeparator, tabNumber + 1, mode);
		}
	}

	private void disassemble(RuntimeInvisibleParameterAnnotationsAttribute runtimeInvisibleParameterAnnotationsAttribute, StringBuffer buffer, String lineSeparator, int tabNumber, int mode) {
		writeNewLine(buffer, lineSeparator, tabNumber + 1);
		buffer.append(Messages.disassembler_runtimeinvisibleparameterannotationsattributeheader);
		ParameterAnnotation[] parameterAnnotations = runtimeInvisibleParameterAnnotationsAttribute.getParameterAnnotations();
		for (int i = 0, max = parameterAnnotations.length; i < max; i++) {
			disassemble(i, parameterAnnotations[i], buffer, lineSeparator, tabNumber + 1, mode);
		}
	}

	private void disassemble(RuntimeVisibleAnnotationsAttribute runtimeVisibleAnnotationsAttribute, StringBuffer buffer, String lineSeparator, int tabNumber, int mode) {
		writeNewLine(buffer, lineSeparator, tabNumber + 1);
		buffer.append(Messages.disassembler_runtimevisibleannotationsattributeheader);
		Annotation[] annotations = runtimeVisibleAnnotationsAttribute.getAnnotations();
		for (Annotation annotation : annotations) {
			disassemble(annotation, buffer, lineSeparator, tabNumber + 1, mode);
		}
	}

	private void disassemble(RuntimeVisibleParameterAnnotationsAttribute runtimeVisibleParameterAnnotationsAttribute, StringBuffer buffer, String lineSeparator, int tabNumber, int mode) {
		writeNewLine(buffer, lineSeparator, tabNumber + 1);
		buffer.append(Messages.disassembler_runtimevisibleparameterannotationsattributeheader);
		ParameterAnnotation[] parameterAnnotations = runtimeVisibleParameterAnnotationsAttribute.getParameterAnnotations();
		for (int i = 0, max = parameterAnnotations.length; i < max; i++) {
			disassemble(i, parameterAnnotations[i], buffer, lineSeparator, tabNumber + 1, mode);
		}
	}

	private void disassembleAsModifier(Annotation annotation, StringBuffer buffer, String lineSeparator, int tabNumber, int mode) {
		final char[] typeName = CharOperation.replaceOnCopy(annotation.getTypeName(), '/', '.');
		buffer.append('@').append(returnClassName(Signature.toCharArray(typeName), '.', mode));
		final AnnotationComponent[] components = annotation.getComponents();
		final int length = components.length;
		if (length != 0) {
			buffer.append('(');
			for (int i = 0; i < length; i++) {
				if (i > 0) {
					buffer.append(',');
					writeNewLine(buffer, lineSeparator, tabNumber);
				}
				disassembleAsModifier(components[i], buffer, lineSeparator, tabNumber + 1, mode);
			}
			buffer.append(')');
		}
	}

	private void disassembleAsModifier(AnnotationComponent annotationComponent, StringBuffer buffer, String lineSeparator, int tabNumber, int mode) {
		buffer.append(annotationComponent.getComponentName()).append('=');
		disassembleAsModifier(annotationComponent.getComponentValue(), buffer, lineSeparator, tabNumber + 1, mode);
	}

	private void disassembleAsModifier(AnnotationComponentValue annotationComponentValue, StringBuffer buffer, String lineSeparator, int tabNumber, int mode) {
		switch (annotationComponentValue.getTag()) {
			case AnnotationComponentValue.BYTE_TAG :
			case AnnotationComponentValue.CHAR_TAG :
			case AnnotationComponentValue.DOUBLE_TAG :
			case AnnotationComponentValue.FLOAT_TAG :
			case AnnotationComponentValue.INTEGER_TAG :
			case AnnotationComponentValue.LONG_TAG :
			case AnnotationComponentValue.SHORT_TAG :
			case AnnotationComponentValue.BOOLEAN_TAG :
			case AnnotationComponentValue.STRING_TAG :
				ConstantPoolEntry constantPoolEntry = annotationComponentValue.getConstantValue();
				String value = null;
				switch (constantPoolEntry.getKind()) {
					case ConstantPoolConstant.CONSTANT_Long :
						value = constantPoolEntry.getLongValue() + "L"; //$NON-NLS-1$
						break;
					case ConstantPoolConstant.CONSTANT_Float :
						value = constantPoolEntry.getFloatValue() + "f"; //$NON-NLS-1$
						break;
					case ConstantPoolConstant.CONSTANT_Double :
						value = Double.toString(constantPoolEntry.getDoubleValue());
						break;
					case ConstantPoolConstant.CONSTANT_Integer :
						switch (annotationComponentValue.getTag()) {
							case AnnotationComponentValue.CHAR_TAG :
								value = "'" + (char) constantPoolEntry.getIntegerValue() + "'"; //$NON-NLS-1$//$NON-NLS-2$
								break;
							case AnnotationComponentValue.BOOLEAN_TAG :
								value = constantPoolEntry.getIntegerValue() == 1 ? "true" : "false";//$NON-NLS-1$//$NON-NLS-2$
								break;
							case AnnotationComponentValue.BYTE_TAG :
								value = "(byte) " + constantPoolEntry.getIntegerValue(); //$NON-NLS-1$
								break;
							case AnnotationComponentValue.SHORT_TAG :
								value = "(short) " + constantPoolEntry.getIntegerValue(); //$NON-NLS-1$
								break;
							case AnnotationComponentValue.INTEGER_TAG :
								value = "(int) " + constantPoolEntry.getIntegerValue(); //$NON-NLS-1$
						}
						break;
					case ConstantPoolConstant.CONSTANT_Utf8 :
						value = "\"" + decodeStringValue(constantPoolEntry.getUtf8Value()) + "\"";//$NON-NLS-1$//$NON-NLS-2$
				}
				buffer.append(value);
				break;
			case AnnotationComponentValue.ENUM_TAG :
				final char[] typeName = CharOperation.replaceOnCopy(annotationComponentValue.getEnumConstantTypeName(), '/', '.');
				final char[] constantName = annotationComponentValue.getEnumConstantName();
				buffer.append(returnClassName(Signature.toCharArray(typeName), '.', mode)).append('.').append(constantName);
				break;
			case AnnotationComponentValue.CLASS_TAG :
				constantPoolEntry = annotationComponentValue.getClassInfo();
				final char[] className = CharOperation.replaceOnCopy(constantPoolEntry.getUtf8Value(), '/', '.');
				buffer.append(returnClassName(Signature.toCharArray(className), '.', mode));
				break;
			case AnnotationComponentValue.ANNOTATION_TAG :
				Annotation annotation = annotationComponentValue.getAnnotationValue();
				disassembleAsModifier(annotation, buffer, lineSeparator, tabNumber + 1, mode);
				break;
			case AnnotationComponentValue.ARRAY_TAG :
				final AnnotationComponentValue[] annotationComponentValues = annotationComponentValue.getAnnotationComponentValues();
				buffer.append('{');
				for (int i = 0, max = annotationComponentValues.length; i < max; i++) {
					if (i > 0) {
						buffer.append(',');
					}
					disassembleAsModifier(annotationComponentValues[i], buffer, lineSeparator, tabNumber + 1, mode);
				}
				buffer.append('}');
		}
	}

	private void disassembleAsModifier(AnnotationDefaultAttribute annotationDefaultAttribute, StringBuffer buffer, String lineSeparator, int tabNumber, int mode) {
		AnnotationComponentValue componentValue = annotationDefaultAttribute.getMemberValue();
		disassembleAsModifier(componentValue, buffer, lineSeparator, tabNumber + 1, mode);
	}

	private void disassembleAsModifier(RuntimeInvisibleAnnotationsAttribute runtimeInvisibleAnnotationsAttribute, StringBuffer buffer, String lineSeparator, int tabNumber, int mode) {
		for (Annotation annotation : runtimeInvisibleAnnotationsAttribute.getAnnotations()) {
			disassembleAsModifier(annotation, buffer, lineSeparator, tabNumber + 1, mode);
		}
	}

	private void disassembleAsModifier(RuntimeInvisibleParameterAnnotationsAttribute runtimeInvisibleParameterAnnotationsAttribute, StringBuffer buffer, int index, String lineSeparator, int tabNumber, int mode) {
		ParameterAnnotation[] parameterAnnotations = runtimeInvisibleParameterAnnotationsAttribute.getParameterAnnotations();
		if (parameterAnnotations.length > index) {
			disassembleAsModifier(parameterAnnotations[index], buffer, lineSeparator, tabNumber + 1, mode);
		}
	}

	private void disassembleAsModifier(RuntimeVisibleParameterAnnotationsAttribute runtimeVisibleParameterAnnotationsAttribute, StringBuffer buffer, int index, String lineSeparator, int tabNumber, int mode) {
		ParameterAnnotation[] parameterAnnotations = runtimeVisibleParameterAnnotationsAttribute.getParameterAnnotations();
		if (parameterAnnotations.length > index) {
			disassembleAsModifier(parameterAnnotations[index], buffer, lineSeparator, tabNumber + 1, mode);
		}
	}

	private void disassembleAsModifier(ParameterAnnotation parameterAnnotation, StringBuffer buffer, String lineSeparator, int tabNumber, int mode) {
		Annotation[] annotations = parameterAnnotation.getAnnotations();
		for (int i = 0, max = annotations.length; i < max; i++) {
			if (i > 0) {
				buffer.append(' ');
			}
			disassembleAsModifier(annotations[i], buffer, lineSeparator, tabNumber + 1, mode);
		}
	}

	private void disassembleAsModifier(RuntimeVisibleAnnotationsAttribute runtimeVisibleAnnotationsAttribute, StringBuffer buffer, String lineSeparator, int tabNumber, int mode) {
		Annotation[] annotations = runtimeVisibleAnnotationsAttribute.getAnnotations();
		for (int i = 0, max = annotations.length; i < max; i++) {
			if (i > 0) {
				writeNewLine(buffer, lineSeparator, tabNumber);
			}
			disassembleAsModifier(annotations[i], buffer, lineSeparator, tabNumber + 1, mode);
		}
	}

	private void disassembleTypeMembers(ClassFileReader classFileReader, char[] className, StringBuffer buffer, String lineSeparator, int tabNumber, int mode, boolean isEnum) {
		FieldInfo[] fields = classFileReader.getFieldInfos();
		// sort fields
		Arrays.sort(fields, (fieldInfo1, fieldInfo2) -> {
			int compare = new String(fieldInfo1.getName()).compareTo(new String(fieldInfo2.getName()));
			if (compare == 0) {
				return new String(fieldInfo1.getDescriptor()).compareTo(new String(fieldInfo2.getDescriptor()));
			}
			return compare;
		});
		for (FieldInfo field : fields) {
			writeNewLine(buffer, lineSeparator, tabNumber);
			disassemble(field, buffer, lineSeparator, tabNumber, mode);
		}
		MethodInfo[] methods = classFileReader.getMethodInfos();
		// sort methods
		Arrays.sort(methods, (methodInfo1, methodInfo2) -> {
			int compare = new String(methodInfo1.getName()).compareTo(new String(methodInfo2.getName()));
			if (compare == 0) {
				return new String(methodInfo1.getDescriptor()).compareTo(new String(methodInfo2.getDescriptor()));
			}
			return compare;
		});
		for (MethodInfo method : methods) {
			writeNewLine(buffer, lineSeparator, tabNumber);
			disassemble(classFileReader, className, method, buffer, lineSeparator, tabNumber, mode);
		}
	}

	private final void dumpTab(int tabNumber, StringBuffer buffer) {
		for (int i = 0; i < tabNumber; i++) {
			buffer.append(Messages.disassembler_indentation);
		}
	}

	private EnclosingMethodAttribute getEnclosingMethodAttribute(ClassFileReader classFileReader) {
		for (ClassFileAttribute attribute : classFileReader.getAttributes()) {
			if (Arrays.equals(attribute.getAttributeName(), AttributeNamesConstants.ENCLOSING_METHOD)) {
				return (EnclosingMethodAttribute) attribute;
			}
		}
		return null;
	}

	private char[] getSignatureForField(char[] fieldDescriptor) {
		char[] newFieldDescriptor = CharOperation.replaceOnCopy(fieldDescriptor, '/', '.');
		newFieldDescriptor = CharOperation.replaceOnCopy(newFieldDescriptor, '$', '%');
		char[] fieldDescriptorSignature = Signature.toCharArray(newFieldDescriptor);
		CharOperation.replace(fieldDescriptorSignature, '%', '$');
		return fieldDescriptorSignature;
	}

	private boolean isDeprecated(ClassFileReader classFileReader) {
		for (ClassFileAttribute attribute : classFileReader.getAttributes()) {
			if (Arrays.equals(attribute.getAttributeName(), AttributeNamesConstants.DEPRECATED)) {
				return true;
			}
		}
		return false;
	}

	private boolean isSynthetic(ClassFileReader classFileReader) {
		int flags = classFileReader.getAccessFlags();
		if ((flags & IModifierConstants.ACC_SYNTHETIC) != 0) {
			return true;
		}
		for (ClassFileAttribute attribute : classFileReader.getAttributes()) {
			if (Arrays.equals(attribute.getAttributeName(), AttributeNamesConstants.SYNTHETIC)) {
				return true;
			}
		}
		return false;
	}

	private boolean checkMode(int mode, int flag) {
		return (mode & flag) != 0;
	}

	private boolean isCompact(int mode) {
		return (mode & Disassembler.COMPACT) != 0;
	}

	private char[] returnClassName(char[] classInfoName, char separator, int mode) {
		if (classInfoName.length == 0) {
			return CharOperation.NO_CHAR;
		} else if (isCompact(mode)) {
			int lastIndexOfSlash = CharOperation.lastIndexOf(separator, classInfoName);
			if (lastIndexOfSlash != -1) {
				return CharOperation.subarray(classInfoName, lastIndexOfSlash + 1, classInfoName.length);
			}
		}
		return classInfoName;
	}

	private void writeNewLine(StringBuffer buffer, String lineSeparator, int tabNumber) {
		buffer.append(lineSeparator);
		dumpTab(tabNumber, buffer);
	}
}
