package org.eclipse.jdi.internal;

/*
 * (c) Copyright IBM Corp. 2000, 2001.
 * All Rights Reserved.
 */

import com.sun.jdi.*;
import com.sun.jdi.connect.*;
import com.sun.jdi.event.*;
import com.sun.jdi.request.*;
import org.eclipse.jdi.internal.connect.*;
import org.eclipse.jdi.internal.request.*;
import org.eclipse.jdi.internal.event.*;
import org.eclipse.jdi.internal.jdwp.*;
import org.eclipse.jdi.internal.spy.*;
import java.util.*;
import java.io.*;

/**
 * this class implements the corresponding interfaces
 * declared by the JDI specification. See the com.sun.jdi package
 * for more information.
 *
 */
public abstract class ReferenceTypeImpl extends TypeImpl implements ReferenceType, org.eclipse.jdi.hcr.ReferenceType {
	/** ClassStatus Constants. */
	public static final int JDWP_CLASS_STATUS_VERIFIED = 1;
	public static final int JDWP_CLASS_STATUS_PREPARED = 2;
	public static final int JDWP_CLASS_STATUS_INITIALIZED = 4;
	public static final int JDWP_CLASS_STATUS_ERROR = 8;

	/** Mapping of command codes to strings. */
	private static Vector fClassStatusVector = null;
	
	/** ReferenceTypeID that corresponds to this reference. */
	private JdwpReferenceTypeID fReferenceTypeID;

	/** The following are the stored results of JDWP calls. */
	protected List fInterfaces = null;
	private List fMethods = null;
	private List fFields = null;
	private List fAllMethods = null;
	private List fVisibleMethods = null;
	private List fAllFields = null;
	private List fVisibleFields = null;
	private List fAllInterfaces = null;
	private List fAllLineLocations = null;
	private String fSourcename = null;
	private int fModifierBits = -1;
	private ClassLoaderReferenceImpl fClassLoader = null;
	private ClassObjectReferenceImpl fClassObject = null;

	private boolean fGotClassFileVersion = false;	// HCR addition.
	private int fClassFileVersion;	// HCR addition.
	private boolean fIsHCREligible;	// HCR addition.
	private boolean fIsVersionKnown;	// HCR addition.
	
	/**
	 * Creates new instance.
	 */
	protected ReferenceTypeImpl(String description, VirtualMachineImpl vmImpl, JdwpReferenceTypeID referenceTypeID) {
		super(description, vmImpl);
		fReferenceTypeID = referenceTypeID;
	}
	
	/**
	 * Creates new instance.
	 */
	protected ReferenceTypeImpl(String description, VirtualMachineImpl vmImpl, JdwpReferenceTypeID referenceTypeID, String signature) {
		super(description, vmImpl);
		fReferenceTypeID = referenceTypeID;
		setSignature(signature);
	}
	
	/**
	 * @return Returns type tag.
	 */
	public abstract byte typeTag();
	
	/**
	 * Flushes all stored Jdwp results.
	 */
	public void flushStoredJdwpResults() {
		Iterator iter;
	
		// Flush Methods.
		if (fMethods != null) {
			iter = fMethods.iterator();
			while (iter.hasNext()) {
				MethodImpl method = (MethodImpl)iter.next();
				method.flushStoredJdwpResults();
			}
			fMethods = null;
		}

		// Flush Fields.
		if (fFields != null) {
			iter = fFields.iterator();
			while (iter.hasNext()) {
				FieldImpl field = (FieldImpl)iter.next();
				field.flushStoredJdwpResults();
			}
			fFields = null;
		}

		fInterfaces = null;
		fAllMethods = null;
		fVisibleMethods = null;
		fAllFields = null;
		fVisibleFields = null;
		fAllInterfaces = null;
		fAllLineLocations = null;
		fSourcename = null;
		fModifierBits = -1;
		fClassLoader = null;
		fClassObject = null;
		fGotClassFileVersion = false;
		
		// The following cached results are stored higher up in the class hierarchy.
		fSignature = null;
		fSourcename = null;
	}
	
	/**
	 * @return Returns Jdwp Reference ID.
	 */
	public JdwpReferenceTypeID getRefTypeID() {
		return fReferenceTypeID;
	}
	
	/**
	 * @return Returns modifier bits.
	 */
	public int modifiers() {
		if (fModifierBits != -1)
			return fModifierBits;
			
		initJdwpRequest();
		try {
			JdwpReplyPacket replyPacket = requestVM(JdwpCommandPacket.RT_MODIFIERS, this);
			defaultReplyErrorHandler(replyPacket.errorCode());
			DataInputStream replyData = replyPacket.dataInStream();
			fModifierBits = readInt("modifiers", AccessibleImpl.modifierVector(), replyData);
			return fModifierBits;
		} catch (IOException e) {
			defaultIOExceptionHandler(e);
			return 0;
		} finally {
			handledJdwpRequest();
		}
	}
	
	/** 
	 * Add methods to a set of methods if they are not overriden, add new names+signature combinations to set of names+signature combinations.
	 */
	private void addVisibleMethods(List newMethods, HashSet nameAndSignatures, Vector resultMethods) {
		Iterator iter = newMethods.iterator();
		MethodImpl method;
		while (iter.hasNext()) {
			method = (MethodImpl)iter.next();
			String nameAndSignature = method.name() + method.signature();
			if (!nameAndSignatures.contains(nameAndSignature)) {
				resultMethods.add(method);
				nameAndSignatures.add(nameAndSignature);
			}
		}
	}
	
	/**
	 * @return Returns a list containing each unhidden and unambiguous Method in this type.
	 */
	public List visibleMethods() {
		if (fVisibleMethods != null)
			return fVisibleMethods;

		/* Recursion:
		 * The methods of its own (own methods() command);
		 * All methods of the interfaces it implements;
		 * If it is a class, all methods of it's superclass.
		 */
		// The name+signature combinations of methods are maintained in a set, to avoid including methods that have been overriden.
		HashSet namesAndSignatures = new HashSet();
		
		// The methods of its own (own methods() command).
	 	Vector visibleMethods = new Vector();
	 	addVisibleMethods(methods(), namesAndSignatures, visibleMethods);
		
		// All methods of the interfaces it implements.
		Iterator interfaces = interfaces().iterator();
		InterfaceTypeImpl inter;
		while (interfaces.hasNext()) {
			inter = (InterfaceTypeImpl)interfaces.next();
			addVisibleMethods(inter.visibleMethods(), namesAndSignatures, visibleMethods);
		}
		
		// If it is a class, all methods of it's superclass.
		if (this instanceof ClassType) {
			ClassType superclass = ((ClassType)this).superclass();
			if (superclass != null)
				addVisibleMethods(superclass.visibleMethods(), namesAndSignatures, visibleMethods);
		}
		
		fVisibleMethods  = visibleMethods;
		return fVisibleMethods;
	}

	/**
	 * @return Returns a list containing each Method declared in this type, and its superclasses, implemented interfaces, and/or superinterfaces.
	 */
	public List allMethods() {
		if (fAllMethods != null)
			return fAllMethods;

		/* Recursion:
		 * The methods of its own (own methods() command);
		 * All methods of the interfaces it implements;
		 * If it is a class, all methods of it's superclass.
		 */
		// The name+signature combinations of methods are maintained in a set.
		HashSet resultSet = new HashSet();
		
		// The methods of its own (own methods() command).
		resultSet.addAll(methods());
		
		// All methods of the interfaces it implements.
		Iterator interfaces = interfaces().iterator();
		InterfaceTypeImpl inter;
		while (interfaces.hasNext()) {
			inter = (InterfaceTypeImpl)interfaces.next();
			resultSet.addAll(inter.allMethods());
		}
		
		// If it is a class, all methods of it's superclass.
		if (this instanceof ClassType) {
			ClassType superclass = ((ClassType)this).superclass();
			if (superclass != null)
				resultSet.addAll(superclass.allMethods());
		}
		
		fAllMethods  = new ArrayList(resultSet);
		return fAllMethods;
	}

	/** 
	 * @return Returns the interfaces declared as implemented by this class. Interfaces indirectly implemented (extended by the implemented interface or implemented by a superclass) are not included.
	 */
	public List interfaces() {
		if (fInterfaces != null)
			return fInterfaces;
			
		initJdwpRequest();
		try {
			JdwpReplyPacket replyPacket = requestVM(JdwpCommandPacket.RT_INTERFACES, this);
			defaultReplyErrorHandler(replyPacket.errorCode());
			DataInputStream replyData = replyPacket.dataInStream();
			Vector elements = new Vector();
			int nrOfElements = readInt("elements", replyData);
			for (int i = 0; i < nrOfElements; i++) {
				InterfaceTypeImpl ref = InterfaceTypeImpl.read(this, replyData);
				if (ref == null)
					continue;
				elements.add(ref);
			}
			fInterfaces = elements;
			return elements;
		} catch (IOException e) {
			defaultIOExceptionHandler(e);
			return null;
		} finally {
			handledJdwpRequest();
		}
	}
			
	/** 
	 * @return Returns the interfaces declared as implemented by this class. Interfaces indirectly implemented (extended by the implemented interface or implemented by a superclass) are not included.
	 */
	public List allInterfaces() {
		if (fAllInterfaces != null)
			return fAllInterfaces;

		/* Recursion:
		 * The interfaces that it directly implements;
		 * All interfaces that are implemented by its interfaces;
		 * If it is a class, all interfaces that are implemented by its superclass.
		 */
		// The interfaces are maintained in a set, to avoid duplicates.
		// The interfaces of its own (own interfaces() command) are first inserted.
		HashSet allInterfacesSet = new HashSet(interfaces());
		
		// All interfaces of the interfaces it implements.
		Iterator interfaces = interfaces().iterator();
		InterfaceTypeImpl inter;
		while (interfaces.hasNext()) {
			inter = (InterfaceTypeImpl)interfaces.next();
			allInterfacesSet.addAll(inter.allInterfaces());
		}
		
		// If it is a class, all interfaces of it's superclass.
		if (this instanceof ClassType) {
			ClassType superclass = ((ClassType)this).superclass();
			if (superclass != null)
				allInterfacesSet.addAll(superclass.allInterfaces());
		}
				
		fAllInterfaces = new ArrayList(allInterfacesSet);
		return fAllInterfaces;
	}


	/** 
	 * Add fields to a set of fields if they are not overriden, add new fieldnames to set of fieldnames.
	 */
	private void addVisibleFields(List newFields, HashSet names, Vector resultFields) {
		Iterator iter = newFields.iterator();
		FieldImpl field;
		while (iter.hasNext()) {
			field = (FieldImpl)iter.next();
			String name = field.name();
			if (!names.contains(name)) {
				resultFields.add(field);
				names.add(name);
			}
		}
	}
	
	/**
	 * @return Returns a list containing each unhidden and unambiguous Field in this type.
	 */
	public List visibleFields() {
		if (fVisibleFields != null)
			return fVisibleFields;

		/* Recursion:
		 * The fields of its own (own fields() command);
		 * All fields of the interfaces it implements;
		 * If it is a class, all fields of it's superclass.
		 */
		// The names of fields are maintained in a set, to avoid including fields that have been overriden.
		HashSet fieldNames = new HashSet();
		
		// The fields of its own (own fields() command).
		Vector visibleFields = new Vector();
		addVisibleFields(fields(), fieldNames, visibleFields);
		
		// All fields of the interfaces it implements.
		Iterator interfaces = interfaces().iterator();
		InterfaceTypeImpl inter;
		while (interfaces.hasNext()) {
			inter = (InterfaceTypeImpl)interfaces.next();
			addVisibleFields(inter.visibleFields(), fieldNames, visibleFields);
		}
		
		// If it is a class, all fields of it's superclass.
		if (this instanceof ClassType) {
			ClassType superclass = ((ClassType)this).superclass();
			if (superclass != null)
				addVisibleFields(superclass.visibleFields(), fieldNames, visibleFields);
		}
				
		fVisibleFields = visibleFields;
		return fVisibleFields;
	}

	/** 
	 * @return Returns a list containing each Field declared in this type, and its superclasses, implemented interfaces, and/or superinterfaces.
	 */
	public List allFields() {
		if (fAllFields != null)
			return fAllFields;

		/* Recursion:
		 * The fields of its own (own fields() command);
		 * All fields of the interfaces it implements;
		 * If it is a class, all fields of it's superclass.
		 */
		// The names of fields are maintained in a set, to avoid including fields that have been inherited double.
		HashSet resultSet = new HashSet();
		
		// The fields of its own (own fields() command).
		resultSet.addAll(fields());
		
		// All fields of the interfaces it implements.
		Iterator interfaces = interfaces().iterator();
		InterfaceTypeImpl inter;
		while (interfaces.hasNext()) {
			inter = (InterfaceTypeImpl)interfaces.next();
			resultSet.addAll(inter.allFields());
		}
		
		// If it is a class, all fields of it's superclass.
		if (this instanceof ClassType) {
			ClassType superclass = ((ClassType)this).superclass();
			if (superclass != null)
				resultSet.addAll(superclass.allFields());
		}
				
		fAllFields = new ArrayList(resultSet);
		return fAllFields;
	}
	
	/** 
	 * @return Returns the classloader object which loaded the class corresponding to this type.
	 */
	public ClassLoaderReference classLoader() {
		if (fClassLoader != null)
			return fClassLoader;

		initJdwpRequest();
		try {
	   		JdwpReplyPacket replyPacket = requestVM(JdwpCommandPacket.RT_CLASS_LOADER, this);
			defaultReplyErrorHandler(replyPacket.errorCode());
			DataInputStream replyData = replyPacket.dataInStream();
			fClassLoader = ClassLoaderReferenceImpl.read(this, replyData);
			return fClassLoader;
		} catch (IOException e) {
			defaultIOExceptionHandler(e);
	   		return null;
		} finally {
			handledJdwpRequest();
		}
	}
		
	/** 
	 * @return Returns the class object that corresponds to this type in the target VM. 
	 */
	public ClassObjectReference classObject() {
		if (fClassObject != null)
			return fClassObject;

		initJdwpRequest();
		try {
	   		JdwpReplyPacket replyPacket = requestVM(JdwpCommandPacket.RT_CLASS_OBJECT, this);
			defaultReplyErrorHandler(replyPacket.errorCode());
			DataInputStream replyData = replyPacket.dataInStream();
			fClassObject = ClassObjectReferenceImpl.read(this, replyData);
			return fClassObject;
		} catch (IOException e) {
			defaultIOExceptionHandler(e);
	   		return null;
		} finally {
			handledJdwpRequest();
		}
	}

	/** 
	 * @return Returns status of class/interface.
	 */
	protected int status() { 
		// Note that this information should not be cached.
		initJdwpRequest();
		try {
			JdwpReplyPacket replyPacket = requestVM(JdwpCommandPacket.RT_STATUS, this);
			defaultReplyErrorHandler(replyPacket.errorCode());
			DataInputStream replyData = replyPacket.dataInStream();
			int status = readInt("status", classStatusVector(), replyData);
			return status;
		} catch (IOException e) {
			defaultIOExceptionHandler(e);
			return 0;
		} finally {
			handledJdwpRequest();
		}
	}
	
	/** 
	 * @return Returns true if initialization failed for this class.
	 */
	public boolean failedToInitialize() {
		return (status() & JDWP_CLASS_STATUS_ERROR) != 0;
	}

	/** 
	 * @return Returns true if this type has been initialized.
	 */
	public boolean isInitialized() {
		return (status() & JDWP_CLASS_STATUS_INITIALIZED) != 0;
	}

	/** 
	 * @return Returns true if this type has been prepared.
	 */
	public boolean isPrepared() {
		return (status() & JDWP_CLASS_STATUS_PREPARED) != 0;
	}

	/** 
	 * @return Returns true if this type has been verified.
	 */
	public boolean isVerified() {
		return (status() & JDWP_CLASS_STATUS_VERIFIED) != 0;
	}

	/** 
	 * @return Returns the visible Field with the given non-ambiguous name. 
	 */
	public Field fieldByName(String name) {
		Iterator iter = visibleFields().iterator();
		while (iter.hasNext()) {
			FieldImpl field = (FieldImpl)iter.next();
			if (field.name().equals(name))
				return field;
		}
		return null;
	}
	
	/** 
	 * @return Returns a list containing each Field declared in this type. 
	 */
	public List fields() {
		if (fFields != null)
			return fFields;
		
		// Note: Fields are returned in the order they occur in the class file, therefore their
		// order in this list can be used for comparisons.
		initJdwpRequest();
		try {
			JdwpReplyPacket replyPacket = requestVM(JdwpCommandPacket.RT_FIELDS, this);
			defaultReplyErrorHandler(replyPacket.errorCode());
			DataInputStream replyData = replyPacket.dataInStream();
			Vector elements = new Vector();
			int nrOfElements = readInt("elements", replyData);
			for (int i = 0; i < nrOfElements; i++) {
				FieldImpl elt = FieldImpl.readWithNameSignatureModifiers(this, this, replyData);
				if (elt == null)
					continue;
				elements.add(elt);
			}
			fFields = elements;
			return elements;
		} catch (IOException e) {
			defaultIOExceptionHandler(e);
			return null;
		} finally {
			handledJdwpRequest();
		}
	}
	
	/** 
	 * @return Returns FieldImpl of a field in the reference specified by a given fieldID, or null if not found.
	 */
	public FieldImpl findField(JdwpFieldID fieldID) {
		Iterator iter = allFields().iterator();
		while(iter.hasNext()) {
			FieldImpl field = (FieldImpl)iter.next();
			if (field.getFieldID().equals(fieldID))
				return field;
		}
		return null;
	}
	
	/** 
	 * @return Returns MethodImpl of a method in the reference specified by a given methodID, or null if not found.
	 */
	public MethodImpl findMethod(JdwpMethodID methodID) {
		Iterator iter = allMethods().iterator();
		while(iter.hasNext()) {
			MethodImpl method = (MethodImpl)iter.next();
			if (method.getMethodID().equals(methodID))
				return method;
		}
		return null;
	}
	
	/** 
	 * @return Returns the Value of a given static Field in this type. 
	 */
	public Value getValue(Field field) {
		ArrayList list = new ArrayList(1);
		list.add(field);
		return (ValueImpl)getValues(list).get(field);
	}
		
	/** 
	 * @return a Map of the requested static Field objects with their Value.
	 */
	public Map getValues(List fields) {
		// Note that this information should not be cached.
		initJdwpRequest();
		try {
			ByteArrayOutputStream outBytes = new ByteArrayOutputStream();
			DataOutputStream outData = new DataOutputStream(outBytes);
			int fieldsSize = fields.size();
			write(this, outData);
			writeInt(fieldsSize, "size", outData);
			for (int i = 0; i < fieldsSize; i++) {
				FieldImpl field = (FieldImpl)fields.get(i);
				checkVM(field);
				field.getFieldID().write(outData);
			}
	
			JdwpReplyPacket replyPacket = requestVM(JdwpCommandPacket.RT_GET_VALUES, outBytes);
			defaultReplyErrorHandler(replyPacket.errorCode());
			
			DataInputStream replyData = replyPacket.dataInStream();
			HashMap map = new HashMap();
			int nrOfElements = readInt("elements", replyData);
			if (nrOfElements != fieldsSize) 
				throw new InternalError("Retrieved a different number of values from the VM than requested.");
				
			for (int i = 0; i < nrOfElements; i++) {
				map.put(fields.get(i), ValueImpl.readWithTag(this, replyData));
			}
			return map;
		} catch (IOException e) {
			defaultIOExceptionHandler(e);
			return null;
		} finally {
			handledJdwpRequest();
		}
	}
	
	/** 
	 * @return Returns the hash code value.
	 */
	public int hashCode() {
		return fReferenceTypeID.hashCode();
	}
	
	/**
	 * @return Returns true if two mirrors refer to the same entity in the target VM.
	 * @see java.lang.Object#equals(Object)
	 */
	public boolean equals(Object object) {
		return object != null
			&& object.getClass().equals(this.getClass())
			&& fReferenceTypeID.equals(((ReferenceTypeImpl)object).fReferenceTypeID)
			&& virtualMachine().equals(((MirrorImpl)object).virtualMachine());
	}
	
	/**
	 * @return Returns a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object.
	 */
	public int compareTo(Object object) {
		if (object == null || !object.getClass().equals(this.getClass()))
			throw new ClassCastException("Can't compare reference type to given object.");
		return name().compareTo(((ReferenceType)object).name());
	}
	
	/** 
	 * @return Returns true if the type was declared abstract.
	 */
	public boolean isAbstract() {
		return (modifiers() & MODIFIER_ACC_ABSTRACT) != 0;
	}
	
	/** 
	 * @return Returns true if the type was declared final.
	 */
	public boolean isFinal() {
		return (modifiers() & MODIFIER_ACC_FINAL) != 0;
	}
	
	/** 
	 * @return Returns true if the type was declared static.
	 */
	public boolean isStatic() {
		return (modifiers() & MODIFIER_ACC_STATIC) != 0;
	}
	
	/**
	 * @return Returns a List filled with all Location objects that map to the given line number. 
	 */
	public List locationsOfLine(int line) throws AbsentInformationException {
		Iterator allMethods = methods().iterator();
		List locations;
		while (allMethods.hasNext()) {
			MethodImpl method = (MethodImpl)allMethods.next();
			try {
				locations = method.locationsOfLine(line);
			} catch (AbsentInformationException e) {
				continue;
			} catch (InvalidLineNumberException e) {
				continue;
			}
			return locations;
		}
		throw new InvalidLineNumberException("No executable code at line " + line  + ".");
	}
	
	/**
	 * @return Returns a list containing each Method declared directly in this type.
	 */
	public List methods() {
		// Note that ArrayReference overwrites this method by returning an empty list.
		if (fMethods != null)
			return fMethods;
		
		// Note: Methods are returned in the order they occur in the class file, therefore their
		// order in this list can be used for comparisons.
		initJdwpRequest();
		try {
			JdwpReplyPacket replyPacket = requestVM(JdwpCommandPacket.RT_METHODS, this);
			defaultReplyErrorHandler(replyPacket.errorCode());
			DataInputStream replyData = replyPacket.dataInStream();
			Vector elements = new Vector();
			int nrOfElements = readInt("elements", replyData);
			for (int i = 0; i < nrOfElements; i++) {
				MethodImpl elt = MethodImpl.readWithNameSignatureModifiers(this, this, replyData);
				if (elt == null)
					continue;
				elements.add(elt);
			}
			fMethods = elements;
			return elements;
		} catch (IOException e) {
			defaultIOExceptionHandler(e);
			return null;
		} finally {
			handledJdwpRequest();
		}
	}
	
	/**
	 * @return Returns a List containing each visible Method that has the given name.
	 */
	public List methodsByName(String name) {
		Vector elements = new Vector();
		Iterator iter = visibleMethods().iterator();
		while (iter.hasNext()) {
			MethodImpl method = (MethodImpl)iter.next();
			if (method.name().equals(name))
				elements.add(method);
		}
		return elements;
	}

	/**
	 * @return Returns a List containing each visible Method that has the given name and signature.
	 */
	public List methodsByName(String name, String signature) {
		Vector elements = new Vector();
		Iterator iter = visibleMethods().iterator();
		while (iter.hasNext()) {
			MethodImpl method = (MethodImpl)iter.next();
			if (method.name().equals(name) && method.signature().equals(signature))
				elements.add(method);
		}
		return elements;
	}

	/** 
	 * @return Returns the fully qualified name of this type.
	 */
	public String name() {
		// Make sure that we know the signature, from which the name is derived.
		if (fName == null)
			setName(signatureToName(signature()));
		
		return fName;
	}
	
	/** 
	 * @return Returns the JNI-style signature for this type. 
	 */
	public String signature() {
		if (fSignature != null)
			return fSignature;

		initJdwpRequest();
		try {
	   		JdwpReplyPacket replyPacket = requestVM(JdwpCommandPacket.RT_SIGNATURE, this);
			defaultReplyErrorHandler(replyPacket.errorCode());
			DataInputStream replyData = replyPacket.dataInStream();
			setSignature(readString("signature", replyData));
			return fSignature;
		} catch (IOException e) {
			defaultIOExceptionHandler(e);
	   		return null;
		} finally {
			handledJdwpRequest();
		}
	}

	/** 
	 * @return Returns a List containing each ReferenceType declared within this type. 
	 */
	public List nestedTypes() {
		// Note that the VM gives an empty reply on RT_NESTED_TYPES, therefore we search for the
		// nested types in the loaded types.
		Vector result = new Vector();
		Enumeration enum = virtualMachineImpl().allRefTypesEnum();
		while (enum.hasMoreElements()) {
			try {
				ReferenceTypeImpl refType = (ReferenceTypeImpl)enum.nextElement();
				String refName = refType.name();
				if (refName.length() > name().length() && refName.startsWith(name()) && refName.charAt(name().length()) == '$')
					result.add(refType);
			} catch (ClassNotPreparedException e) {
				continue;
			}
		}
		return result;
	}

	/** 
	 * @return Returns an identifing name for the source corresponding to the declaration of this type.
	 */
	public String sourceName() throws AbsentInformationException {
		if (fSourcename != null)
			return fSourcename;

		initJdwpRequest();
		try {
			JdwpReplyPacket replyPacket = requestVM(JdwpCommandPacket.RT_SOURCE_FILE, this);
			if (replyPacket.errorCode() == JdwpReplyPacket.ABSENT_INFORMATION)
				throw new AbsentInformationException("Source name is not known.");
			else
				defaultReplyErrorHandler(replyPacket.errorCode());
		
			DataInputStream replyData = replyPacket.dataInStream();
			fSourcename = readString("source name", replyData);
			return fSourcename;
		} catch (IOException e) {
			defaultIOExceptionHandler(e);
			return null;
		} finally {
			handledJdwpRequest();
		}
	}

	/**
	 * @return Returns the CRC-32 of the given reference type, undefined if unknown.
	 */
	public int getClassFileVersion() {
		virtualMachineImpl().checkHCRSupported();
		if (fGotClassFileVersion)
			return fClassFileVersion;
		
		initJdwpRequest();
		try {
	   		JdwpReplyPacket replyPacket = requestVM(JdwpCommandPacket.HCR_GET_CLASS_VERSION, this);
			defaultReplyErrorHandler(replyPacket.errorCode());
			DataInputStream replyData = replyPacket.dataInStream();
			fIsHCREligible = readBoolean("HCR eligible", replyData);
			fIsVersionKnown = readBoolean("version known", replyData);
			fClassFileVersion = readInt("class file version", replyData);
			fGotClassFileVersion = true;
			return fClassFileVersion;
		} catch (IOException e) {
			defaultIOExceptionHandler(e);
	   		return 0;
		} finally {
			handledJdwpRequest();
		}
	}
	
	/**
	 * @return Returns whether the CRC-32 of the given reference type is known.
	 */
	public boolean isVersionKnown() {
		getClassFileVersion();
		return fIsVersionKnown;
	}
	
	/**
	 * @return Returns whether the reference type is HCR-eligible.
	 */
	public boolean isHCREligible() {
		getClassFileVersion();
		return fIsHCREligible;
	}
	
	/**
	 * Writes JDWP representation.
	 */
	public void write(MirrorImpl target, DataOutputStream out) throws IOException {
		fReferenceTypeID.write(out);
		if (target.fVerboseWriter != null)
			target.fVerboseWriter.println("referenceType", fReferenceTypeID.value());
	}
	
	/**
	 * Writes representation of null referenceType.
	 */
	public static void writeNull(MirrorImpl target, DataOutputStream out) throws IOException {
		// create null id
		JdwpReferenceTypeID ID = new JdwpReferenceTypeID(target.virtualMachineImpl());
		ID.write(out);
		if (target.fVerboseWriter != null)
			target.fVerboseWriter.println("referenceType", ID.value());
	}
	
	/**
	 * Writes JDWP representation.
	 */
	public void writeWithTag(MirrorImpl target, DataOutputStream out) throws IOException {
		target.writeByte(typeTag(), "type tag", JdwpID.typeTagMap(), out);
		write(target, out);
	}
	
	/**
	 * @return Reads JDWP representation and returns new or cached instance.
	 */
	public static ReferenceTypeImpl readWithTypeTag(MirrorImpl target, DataInputStream in) throws IOException {
		byte typeTag = target.readByte("type tag", JdwpID.typeTagMap(), in);
		switch (typeTag) {
	   		case 0:
				return null;
			case ArrayTypeImpl.typeTag:
				return ArrayTypeImpl.read(target, in);
			case ClassTypeImpl.typeTag:
				return ClassTypeImpl.read(target, in);
			case InterfaceTypeImpl.typeTag:
				return InterfaceTypeImpl.read(target, in);
		}
		throw new InternalException("Invalid ReferenceTypeID tag encountered: " + typeTag);
	}
	
	/**
	 * @return Returns the Location objects for each executable source line in this reference type.
	 */
	public List allLineLocations() throws AbsentInformationException {
		if (fAllLineLocations != null)
			return fAllLineLocations;

		Iterator allMethods = methods().iterator();
		Vector locations = new Vector();
		while (allMethods.hasNext()) {
			MethodImpl method = (MethodImpl)allMethods.next();
			locations.addAll(method.allLineLocations());
		}
		fAllLineLocations = locations;
		return fAllLineLocations;
	}
	
	/**
	 * @return Reads JDWP representation and returns new or cached instance.
	 */
	public static ReferenceTypeImpl readWithTypeTagAndSignature(MirrorImpl target, DataInputStream in) throws IOException {
		byte typeTag = target.readByte("type tag", JdwpID.typeTagMap(), in);
		switch (typeTag) {
	   		case 0:
				return null;
			case ArrayTypeImpl.typeTag:
				return ArrayTypeImpl.readWithSignature(target, in);
			case ClassTypeImpl.typeTag:
				return ClassTypeImpl.readWithSignature(target, in);
			case InterfaceTypeImpl.typeTag:
				return InterfaceTypeImpl.readWithSignature(target, in);
		}
		throw new InternalException("Invalid ReferenceTypeID tag encountered: " + typeTag);
	}
		
	/**
	 * @return Returns new instance based on signature and classLoader.
	 * @throws ClassNotLoadedException when the ReferenceType has not been loaded by the specified class loader.
	 */
	public static TypeImpl create(VirtualMachineImpl vmImpl, String signature, ClassLoaderReference classLoader) throws ClassNotLoadedException {
		Iterator iter = vmImpl.classesBySignature(signature).iterator();
		ReferenceTypeImpl refTypeBootstrap = null;
		
		while (iter.hasNext()) {
			ReferenceTypeImpl type = (ReferenceTypeImpl)iter.next();
			if (type.classLoader() == null) {	// bootstrap classloader
				if (classLoader == null)
					return type;
				else
					refTypeBootstrap = type;
			}
					
			if (classLoader != null && classLoader.equals(type.classLoader()))
				return (ReferenceTypeImpl)type;
		}
		
		// If no ReferenceType is found with the specified classloader, but there is one with the
		// bootstrap classloader, the latter is returned.
		if (refTypeBootstrap != null)
			return refTypeBootstrap;

		throw new ClassNotLoadedException(TypeImpl.classSignatureToName(signature), "Type has not been loaded.");
	}
	
	/**
	 * Retrieves constant mappings.
	 */
	public static void getConstantMaps() {
		if (fClassStatusVector != null)
			return;
		
		java.lang.reflect.Field[] fields = ReferenceTypeImpl.class.getDeclaredFields();
		fClassStatusVector = new Vector();
		fClassStatusVector.setSize(32);	// Integer
		
		for (int i = 0; i < fields.length; i++) {
			java.lang.reflect.Field field = fields[i];
			if ((field.getModifiers() & java.lang.reflect.Modifier.PUBLIC) == 0 || (field.getModifiers() & java.lang.reflect.Modifier.STATIC) == 0 || (field.getModifiers() & java.lang.reflect.Modifier.FINAL) == 0)
				continue;
				
			String name = field.getName();
			if (!name.startsWith("JDWP_CLASS_STATUS_"))
				continue;
				
			name = name.substring(18);
			
			try {
				int value = field.getInt(null);
				
				for (int j = 0; j < fClassStatusVector.size(); j++) {
					if ((1 << j & value) != 0) {
						fClassStatusVector.set(j, name);
						break;
					}
				}
			} catch (IllegalAccessException e) {
				// Will not occur for own class.
			} catch (IllegalArgumentException e) {
				// Should not occur.
				// We should take care that all public static final constants
				// in this class are numbers that are convertible to int.
			}
		}
	}
	
	/**
	 * @return Returns a map with string representations of tags.
	 */
	 public static Vector classStatusVector() {
	 	getConstantMaps();
	 	return fClassStatusVector;
	 }
}
