/*******************************************************************************
 * Copyright (c) 2001, 2006 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
/*


 */
package org.eclipse.jem.java.internal.impl;

import java.util.*;

import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.NotificationChain;
import org.eclipse.emf.common.util.ECollections;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.*;
import org.eclipse.emf.ecore.impl.EClassImpl;
import org.eclipse.emf.ecore.impl.ENotificationImpl;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.util.*;

import org.eclipse.jem.internal.java.adapters.*;
import org.eclipse.jem.internal.java.beaninfo.IIntrospectionAdapter;
import org.eclipse.jem.internal.java.instantiation.IInstantiationInstance;
import org.eclipse.jem.java.*;

/**
 * <!-- begin-user-doc -->
 * 
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * <ul>
 *   <li>{@link org.eclipse.jem.java.internal.impl.JavaClassImpl#getKind <em>Kind</em>}</li>
 *   <li>{@link org.eclipse.jem.java.internal.impl.JavaClassImpl#isPublic <em>Public</em>}</li>
 *   <li>{@link org.eclipse.jem.java.internal.impl.JavaClassImpl#isFinal <em>Final</em>}</li>
 *   <li>{@link org.eclipse.jem.java.internal.impl.JavaClassImpl#getImplementsInterfaces <em>Implements Interfaces</em>}</li>
 *   <li>{@link org.eclipse.jem.java.internal.impl.JavaClassImpl#getClassImport <em>Class Import</em>}</li>
 *   <li>{@link org.eclipse.jem.java.internal.impl.JavaClassImpl#getPackageImports <em>Package Imports</em>}</li>
 *   <li>{@link org.eclipse.jem.java.internal.impl.JavaClassImpl#getFields <em>Fields</em>}</li>
 *   <li>{@link org.eclipse.jem.java.internal.impl.JavaClassImpl#getMethods <em>Methods</em>}</li>
 *   <li>{@link org.eclipse.jem.java.internal.impl.JavaClassImpl#getInitializers <em>Initializers</em>}</li>
 *   <li>{@link org.eclipse.jem.java.internal.impl.JavaClassImpl#getDeclaredClasses <em>Declared Classes</em>}</li>
 *   <li>{@link org.eclipse.jem.java.internal.impl.JavaClassImpl#getDeclaringClass <em>Declaring Class</em>}</li>
 *   <li>{@link org.eclipse.jem.java.internal.impl.JavaClassImpl#getJavaPackage <em>Java Package</em>}</li>
 *   <li>{@link org.eclipse.jem.java.internal.impl.JavaClassImpl#getEvents <em>Events</em>}</li>
 *   <li>{@link org.eclipse.jem.java.internal.impl.JavaClassImpl#getAllEvents <em>All Events</em>}</li>
 * </ul>
 * </p>
 *
 * @generated
 */
public class JavaClassImpl extends EClassImpl implements JavaClass {

	/**
	 * The default value of the '{@link #getKind() <em>Kind</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getKind()
	 * @generated
	 * @ordered
	 */
	protected static final TypeKind KIND_EDEFAULT = TypeKind.UNDEFINED_LITERAL;

	/**
	 * @generated This field/method will be replaced during code generation.
	 */
	/**
	 * @generated This field/method will be replaced during code generation.
	 */
	protected TypeKind kind = KIND_EDEFAULT;

	/**
	 * The default value of the '{@link #isPublic() <em>Public</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #isPublic()
	 * @generated
	 * @ordered
	 */
	protected static final boolean PUBLIC_EDEFAULT = false;

	/**
	 * The flag representing the value of the '{@link #isPublic() <em>Public</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #isPublic()
	 * @generated
	 * @ordered
	 */
	protected static final int PUBLIC_EFLAG = 1 << 10;

	/**
	 * The default value of the '{@link #isFinal() <em>Final</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #isFinal()
	 * @generated
	 * @ordered
	 */
	protected static final boolean FINAL_EDEFAULT = false;

	/**
	 * The flag representing the value of the '{@link #isFinal() <em>Final</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #isFinal()
	 * @generated
	 * @ordered
	 */
	protected static final int FINAL_EFLAG = 1 << 11;

	/**
	 * The cached value of the '{@link #getImplementsInterfaces() <em>Implements Interfaces</em>}' reference list.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getImplementsInterfaces()
	 * @generated
	 * @ordered
	 */
	protected EList implementsInterfaces = null;

	/**
	 * The cached value of the '{@link #getClassImport() <em>Class Import</em>}' reference list.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getClassImport()
	 * @generated
	 * @ordered
	 */
	protected EList classImport = null;

	/**
	 * The cached value of the '{@link #getPackageImports() <em>Package Imports</em>}' reference list.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getPackageImports()
	 * @generated
	 * @ordered
	 */
	protected EList packageImports = null;

	/**
	 * The cached value of the '{@link #getFields() <em>Fields</em>}' containment reference list.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getFields()
	 * @generated
	 * @ordered
	 */
	protected EList fields = null;

	/**
	 * The cached value of the '{@link #getMethods() <em>Methods</em>}' containment reference list.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getMethods()
	 * @generated
	 * @ordered
	 */
	protected EList methods = null;

	/**
	 * The cached value of the '{@link #getInitializers() <em>Initializers</em>}' containment reference list.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getInitializers()
	 * @generated
	 * @ordered
	 */
	protected EList initializers = null;

	/**
	 * The cached value of the '{@link #getDeclaredClasses() <em>Declared Classes</em>}' reference list.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getDeclaredClasses()
	 * @generated
	 * @ordered
	 */
	protected EList declaredClasses = null;

	/**
	 * The cached value of the '{@link #getDeclaringClass() <em>Declaring Class</em>}' reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getDeclaringClass()
	 * @generated
	 * @ordered
	 */
	protected JavaClass declaringClass = null;

	/**
	 * The cached value of the '{@link #getEvents() <em>Events</em>}' containment reference list.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getEvents()
	 * @generated
	 * @ordered
	 */
	protected EList events = null;

	protected JavaClassImpl() {
		super();
	}
	
	public EList getEAnnotationsInternal() {
		return super.getEAnnotations();
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected EClass eStaticClass() {
		return JavaRefPackage.Literals.JAVA_CLASS;
	}

	/**
	 * Protected helper methods.
	 */
	protected void collectFieldsExtended(List fields) {
		fields.addAll(getFields());
		Iterator it;
		it = getExtendedLookupIterator();
		while (it.hasNext())
			((JavaClassImpl) it.next()).collectFieldsExtended(fields);
	}

	protected void collectMethodsExtended(Map methods, boolean onlyPublic, List excludedClasses, List excludedMethods) {
		Iterator it1, it2;
		it2 = getExtendedLookupIterator();
		JavaClassImpl javaClass;
		while (it2.hasNext()) {
			javaClass = (JavaClassImpl) it2.next();
			if (!excludedClasses.contains(javaClass))
				javaClass.collectMethodsExtended(methods, onlyPublic, excludedClasses, excludedMethods);
		}
		
		List allMethods = null;
		if(onlyPublic){
			allMethods = getPublicMethods();
		} else{
			allMethods = new ArrayList();
			synchronized(getMethods()){
				allMethods.addAll(getMethods());
			}
		}
		it1 = allMethods.iterator();
		Method nextMethod;
		while (it1.hasNext()) {
			nextMethod = (Method) it1.next();
			if (!excludedMethods.contains(nextMethod))
				methods.put(nextMethod.getMethodElementSignature(), nextMethod);
		}
	}

	/**
	 * createClassRef - return a JavaURL reference to the named Java class
	 * 
	 * @deprecated @see org.eclipse.jem.java.JavaRefFactory#createClassRef(java.lang.String)
	 */
	public static JavaClass createClassRef(String targetName) {
		return JavaRefFactory.eINSTANCE.createClassRef(targetName);
	}

	/**
	 * Get the method of this name and these parameters. It will look up the supertype hierarchy.
	 */
	protected Method findClassMethodExtended(String methodName, List parameterTypes) {
		Method method = getMethod(methodName, parameterTypes);
		if (method != null)
			return method;
		else {
			JavaClassImpl mySuper;
			mySuper = (JavaClassImpl) getSupertype();
			if (mySuper != null)
				return mySuper.findClassMethodExtended(methodName, parameterTypes);
		}
		return null;
	}

	/**
	 * Get the method of this name and these parameters. It will look up the supertype hierarchy.
	 */
	protected Method findInterfaceMethodExtended(String methodName, List parameterTypes) {
		Method method = getMethod(methodName, parameterTypes);
		if (method != null)
			return method;
		else {
			JavaClassImpl superInterface;
			List list = getImplementsInterfaces();
			for (int i = 0; i < list.size(); i++) {
				superInterface = (JavaClassImpl) list.get(i);
				method = superInterface.findInterfaceMethodExtended(methodName, parameterTypes);
				if (method != null)
					return method;
			}
		}
		return null;
	}

	/**
	 * 
	 * @return
	 * @deprecated If anyone is referencing this, please use getEAllSuperTypes() instead. This was placed here and misspelled by mistake.
	 */
	public EList getAllSupertypes() {
		getESuperTypes(); //Force reflection, if needed, before getting all supertypes.
		return super.getEAllSuperTypes();
	}

	/**
	 * Overrides to perform reflection if necessary
	 */
	public EList getClassImport() {
		reflectBase();
		return getClassImportGen();
	}

	public EList getEAllOperations() {
		IIntrospectionAdapter ia = getIntrospectionAdapter();
		if (ia == null)
			return super.getEAllOperations(); // No introspection, do normal.
		if (eAllOperations == null)
			eAllOperations = ia.getEAllOperations();
		return eAllOperations;
	}
	
	/**
	 * This is not meant to be used by others. It is here so that BeanInfo adapter can access
	 * un-introspected all operations.
	 * @return
	 * 
	 * @since 1.1.0
	 */
	public EList primGetEAllOperations() {
		return super.getEAllOperations();
	}

	public EList getEOperations() {
		IIntrospectionAdapter adapter = getIntrospectionAdapter();
		if (adapter != null)
			return adapter.getEOperations();
		return super.getEOperations();
	}

	/**
	 * This method is not meant to be used by others. It is here so that BeanInfo adapters can go to
	 * the non-introspected operations.
	 * @return
	 * 
	 * @since 1.1.0
	 */
	public EList getEOperationsInternal() {
		// An internal method for returning actual wo fluffing up.
		return super.getEOperations();
	}

	public EList getEAnnotations() {
		IIntrospectionAdapter adapter = getIntrospectionAdapter();
		if (adapter != null)
			adapter.introspectIfNecessary(); // To cause introspection so the appropriate decorator is added.
		return super.getEAnnotations();
	}

	public EList getEStructuralFeatures() {
		IIntrospectionAdapter adapter = getIntrospectionAdapter();
		if (adapter != null)
			return adapter.getEStructuralFeatures();
		return super.getEStructuralFeatures();
	}

	public EList getEStructuralFeaturesInternal() {
		// An internal method for returning actual wo fluffing up.
		return super.getEStructuralFeatures();
	}

	/**
	 * Return an Iterator on the implemntsInferface List if this is an interface class or on the super List if it is a class.
	 */
	protected Iterator getExtendedLookupIterator() {
		if (isInterface())
			return getImplementsInterfaces().iterator();
		else
			return getESuperTypes().iterator();
	}

	/**
	 * Return an Field with the passed name, or null.
	 */
	public Field getField(String fieldName) {
		java.util.List fields = getFields();
		Field field;
		for (int i = 0; i < fields.size(); i++) {
			field = (Field) fields.get(i);
			if (field.getName().equals(fieldName))
				return field;
		}
		return null;
	}

	/**
	 * Return an Field with the passed name from this JavaClass or any supertypes.
	 * 
	 * Return null if a Field named fieldName is not found.
	 */
	public Field getFieldExtended(String fieldName) {
		Field field = getFieldNamed(fieldName);
		if (field != null)
			return field;
		Iterator it = getExtendedLookupIterator();
		while (it.hasNext()) {
			Field result = ((JavaClass) it.next()).getFieldExtended(fieldName);
			if (result != null)
				return result;
		}
		return null;
	}

	/**
	 * Return an Field with the passed name, or null.
	 */
	public Field getFieldNamed(String fieldName) {
		return getField(fieldName);
	}

	public EList getFields() {
		reflectFields();
		return getFieldsGen();
	}

	/**
	 * Return all fields, including those from supertypes.
	 */
	public List getFieldsExtended() {
		List fields = new ArrayList();
		collectFieldsExtended(fields);
		return fields;
	}

	public EList getImplementsInterfaces() {
		reflectBase();
		return getImplementsInterfacesGen();
	}

	/**
	 * Return an IntrospectionAdaptor which can introspect our Java properties
	 */
	protected synchronized IIntrospectionAdapter getIntrospectionAdapter() {
		// Need to sync this because we are now in multi-thread env.
		return (IIntrospectionAdapter) EcoreUtil.getRegisteredAdapter(this, IIntrospectionAdapter.ADAPTER_KEY);
	}

	public String getJavaName() {
		return getQualifiedName();
	}

	/*
	 *  (non-Javadoc)
	 * @see org.eclipse.jem.java.JavaHelpers#getSimpleName()
	 */
	public String getSimpleName() {
		return primGetName().replace('$', '.');
	}
	/**
	 * getJavaPackage. This is a derived relationship, so we must implement it here to get the EPackage that this object is contained in.
	 */
	public JavaPackage getJavaPackage() {
		return (JavaPackage) getEPackage();
	}

	/**
	 * Get the method of this name and these parameters. It will not look up the supertype hierarchy.
	 */
	public Method getMethod(String methodName, List parameterTypes) {
		return getMethod(methodName, parameterTypes, getMethods());
	}

	protected Method getMethod(String name, List parameterTypes, List methodList) {
		boolean found = false;
		Method method;
		for (int i = 0; i < methodList.size(); i++) {
			method = (Method) methodList.get(i);
			JavaParameter[] params;
			if (method.getName().equals(name)) {
				params = method.listParametersWithoutReturn();
				if (params.length == parameterTypes.size()) {
					found = true; //Maybe; we need more info
					for (int j = 0; j < params.length; j++) {
						//if any one of the parameters doesn't match then flip back to false
						JavaHelpers jh = (JavaHelpers) params[j].getEType();
						if (!jh.getQualifiedName().equals(parameterTypes.get(j))) {
							found = false;
							break;
						} // end if params equal
					} // end compare all params
					if (found) //short circuit out of this loop and return the winner
						return method;
				} // end compare lengths
			} // end compare names
		} // end loop through all methodList
		return null;
	}

	/**
	 * Return a List of Strings that represent MethodElement signatures from most general to most specific.
	 */
	public List getMethodElementSignatures() {
		List methods, signatures, sameNames;
		methods = getMethodsExtended();
		sameNames = new ArrayList();
		signatures = new ArrayList(methods.size() + 1);
		signatures.add(DEFAULT_METHOD_NAME);
		Iterator it = methods.iterator();
		Method aMethod;
		String methodName;
		String signature;
		while (it.hasNext()) {
			aMethod = (Method) it.next();
			methodName = aMethod.getName();
			signature = aMethod.getMethodElementSignature();
			if (sameNames.contains(methodName)) {
				if (!signatures.contains(signature))
					signatures.add(signature);
			} else {
				sameNames.add(methodName);
				signatures.add(signature);
			}
		}
		Collections.sort(signatures);
		return signatures;
	}

	/**
	 * Get the method of this name and these parameters. It will look up the supertype hierarchy.
	 */
	public Method getMethodExtended(String methodName, List parameterTypes) {
		if (isInterface())
			return findInterfaceMethodExtended(methodName, parameterTypes);
		else
			return findClassMethodExtended(methodName, parameterTypes);
	}

	public EList getMethods() {
		reflectMethods();
		return getMethodsGen();
	}

	/**
	 * Return all methods, including those from supertypes.
	 */
	public List getMethodsExtended() {
		Map methods = new HashMap();
		collectMethodsExtended(methods, false, Collections.EMPTY_LIST, Collections.EMPTY_LIST);
		return new ArrayList(methods.values());
	}

	/*
	 * @see getMethodsExtendedWithFilters(List, List) on JavaClass.
	 */
	public List getMethodsExtendedWithFilters(List excludedClasses, List excludedMethods) {
		Map methods = new HashMap();
		collectMethodsExtended(methods, false, excludedClasses, excludedMethods);
		return new ArrayList(methods.values());
	}

	public String getName() {
		String result = this.primGetName();
		if (result == null && eIsProxy()) {
			return JavaRefFactory.eINSTANCE.getTypeName(eProxyURI());
		}
		return result;
	}

	/**
	 * Return a List of Methods that begins with @aMethodNamePrefix and is not included in the @excludedNames list. If @aMethodNamePrefix is null, all methods will be returned.
	 
	 */
	public List getOnlySpecificMethods(String aMethodNamePrefix, List excludedNames) {
		List methods, specific;
		methods = getMethodsExtended();
		specific = new ArrayList(methods.size());
		Iterator it = methods.iterator();
		Method aMethod;
		String methodName;
		while (it.hasNext()) {
			aMethod = (Method) it.next();
			methodName = aMethod.getName();
			if (aMethodNamePrefix != null && methodName.startsWith(aMethodNamePrefix) && excludedNames != null && !excludedNames.contains(methodName))
				specific.add(aMethod);
		}
		return specific;
	}

	public EList getPackageImports() {
		reflectBase();
		return getPackageImportsGen();
	}

	/**
	 * getPrimitive method comment.
	 */
	public JavaDataType getPrimitive() {
		String primitiveName = getPrimitiveName();
		if (primitiveName != null) {
			Resource res = eResource();
			return (JavaDataType) JavaClassImpl.reflect(primitiveName, res.getResourceSet());
		}
		return null;
	}
	
	
	/* (non-Javadoc)
	 * @see org.eclipse.jem.java.JavaHelpers#getPrimitiveID()
	 */
	public int getPrimitiveID() {
		String myName = getQualifiedName();
		if (myName.equals(INTEGER_NAME))
			return PRIM_INTEGER_ID;
		if (myName.equals(BOOLEAN_NAME))
			return PRIM_BOOLEAN_ID;
		if (myName.equals(BYTE_NAME))
			return PRIM_BYTE_ID;
		if (myName.equals(SHORT_NAME))
			return PRIM_SHORT_ID;
		if (myName.equals(LONG_NAME))
			return PRIM_LONG_ID;
		if (myName.equals(FLOAT_NAME))
			return PRIM_FLOAT_ID;
		if (myName.equals(DOUBLE_NAME))
			return PRIM_DOUBLE_ID;
		if (myName.equals(CHARACTER_NAME))
			return PRIM_CHARACTER_ID;
		return PRIM_NOT_ID;
	}

	/**
	 * Return the primitive name for this type if one exists.
	 */
	protected String getPrimitiveName() {
		String myName = getQualifiedName();
		if (myName.equals(INTEGER_NAME))
			return PRIM_INTEGER_NAME;
		if (myName.equals(BOOLEAN_NAME))
			return PRIM_BOOLEAN_NAME;
		if (myName.equals(BYTE_NAME))
			return PRIM_BYTE_NAME;
		if (myName.equals(SHORT_NAME))
			return PRIM_SHORT_NAME;
		if (myName.equals(LONG_NAME))
			return PRIM_LONG_NAME;
		if (myName.equals(FLOAT_NAME))
			return PRIM_FLOAT_NAME;
		if (myName.equals(DOUBLE_NAME))
			return PRIM_DOUBLE_NAME;
		if (myName.equals(CHARACTER_NAME))
			return PRIM_CHARACTER_NAME;
		return null;
	}

	/**
	 * Return a method matching the name, and non-return parameters with fully qualified types matching all the types in the list, if it exists. It
	 * will not look up the supertype hierarchy.
	 */
	public Method getPublicMethod(String methodName, List parameterTypes) {
		return getMethod(methodName, parameterTypes, getPublicMethods());
	}

	/**
	 * Return a method matching the name, and non-return parameters with fully qualified types matching all the types in the list, if it exists. It
	 * will not look up the supertype hierarchy.
	 */
	public Method getPublicMethodExtended(String methodName, List parameterTypes) {
		return getMethod(methodName, parameterTypes, getPublicMethodsExtended());
	}

	/**
	 * Return all methods, it will not go up the supertype hierarchy.
	 */
	public List getPublicMethods() {
		List publicMethods = new ArrayList();
		List theMethods = getMethods();
		for (int i = 0; i < theMethods.size(); i++) {
			Method m = (Method) theMethods.get(i);
			if (JavaVisibilityKind.PUBLIC_LITERAL == m.getJavaVisibility())
				publicMethods.add(m);
		}
		return publicMethods;
	}

	/**
	 * Return all public methods, including those from supertypes.
	 */
	public List getPublicMethodsExtended() {
		Map methods = new HashMap();
		collectMethodsExtended(methods, true, Collections.EMPTY_LIST, Collections.EMPTY_LIST);
		return new ArrayList(methods.values());
	}

	/**
	 * Returns a filtered list on the methods of this class, having a name equal to that of the parameter.
	 */
	public List getPublicMethodsExtendedNamed(String name) {
		List publicMethods = new ArrayList();
		List theMethods = getPublicMethodsExtended();
		for (int i = 0; i < theMethods.size(); i++) {
			Method m = (Method) theMethods.get(i);
			if (m.getName().equals(name))
				publicMethods.add(m);
		}
		return publicMethods;
	}

	/**
	 * Returns a filtered list on the methods of this class, having a name equal to that of the parameter.
	 */
	public List getPublicMethodsNamed(String name) {
		List publicMethods = new ArrayList();
		List theMethods = getPublicMethods();
		for (int i = 0; i < theMethods.size(); i++) {
			Method m = (Method) theMethods.get(i);
			if (m.getName().equals(name))
				publicMethods.add(m);
		}
		return publicMethods;
	}

	public String getQualifiedName() {
		String result = null;
		if (eIsProxy()) {
			result = JavaRefFactory.eINSTANCE.getFullTypeName(eProxyURI());
		} else {
			result = primGetQualifiedName();
		}
		if (result != null)
			result = result.replace('$', '.');
		return result;
	}

	/**
	 * To be used by people that need to get the qualified name used for reflection. Typically bean info would need to use something like this.
	 */
	public String getQualifiedNameForReflection() {
		return primGetQualifiedName();
	}

	/**
	 * Return a ReadAdaptor which can reflect our Java properties
	 */
	protected synchronized ReadAdaptor getReadAdapter() {
		// Need to sync because now in a multi-thread env.
		return (ReadAdaptor) EcoreUtil.getRegisteredAdapter(this, ReadAdaptor.TYPE_KEY);
	}

	private static final int NOT_REFLECTED = 0x0, REFLECTED_BASE = 0x1, REFLECTED_METHODS = 0x2, REFLECTED_FIELDS = 0x4;

	protected int reflectionStatus = NOT_REFLECTED;

	protected void reflectBase() {
		// We only want the testing of the hasReflected and get readadapter to be sync(this) so that
		// it is short and no deadlock possibility (this is because the the method reflection adapter may go
		// back to the containing java class to get its reflection adapter, which would lock on itself. So
		// we need to keep the sections that are sync(this) to not be deadlockable by not doing significant work
		// during the sync.
		ReadAdaptor readAdaptor = null;
		synchronized (this) {
			if ((reflectionStatus & REFLECTED_BASE) == 0) {
				readAdaptor = getReadAdapter();
			}
		}
		if (readAdaptor != null) {
			boolean setReflected = readAdaptor.reflectValuesIfNecessary();
			synchronized (this) {
				// Don't want to set it false. That is job of reflection adapter. Otherwise we could have a race.
				if (setReflected)
					reflectionStatus |= REFLECTED_BASE;
			}
		}
	}

	protected void reflectFields() {
		// We only want the testing of the hasReflected and get readadapter to be sync(this) so that
		// it is short and no deadlock possibility (this is because the the method reflection adapter may go
		// back to the containing java class to get its reflection adapter, which would lock on itself. So
		// we need to keep the sections that are sync(this) to not be deadlockable by not doing significant work
		// during the sync.
		ReadAdaptor readAdaptor = null;
		synchronized (this) {
			if ((reflectionStatus & REFLECTED_FIELDS) == 0) {
				readAdaptor = getReadAdapter();
			}
		}
		if (readAdaptor != null) {
			boolean setReflected = ((IJavaClassAdaptor) readAdaptor).reflectFieldsIfNecessary();
			synchronized (this) {
				// Don't want to set it false. That is job of reflection adapter. Otherwise we could have a race.
				if (setReflected)
					reflectionStatus |= (REFLECTED_FIELDS | REFLECTED_BASE); // We can be certain base will be done by reflect fields if not already
																			 // done.
			}
		}
	}

	protected void reflectMethods() {
		// We only want the testing of the hasReflected and get readadapter to be sync(this) so that
		// it is short and no deadlock possibility (this is because the the method reflection adapter may go
		// back to the containing java class to get its reflection adapter, which would lock on itself. So
		// we need to keep the sections that are sync(this) to not be deadlockable by not doing significant work
		// during the sync.
		ReadAdaptor readAdaptor = null;
		synchronized (this) {
			if ((reflectionStatus & REFLECTED_METHODS) == 0) {
				readAdaptor = getReadAdapter();
			}
		}
		if (readAdaptor != null) {
			boolean setReflected = ((IJavaClassAdaptor) readAdaptor).reflectMethodsIfNecessary();
			synchronized (this) {
				// Don't want to set it false. That is job of reflection adapter. Otherwise we could have a race.
				if (setReflected)
					reflectionStatus |= (REFLECTED_METHODS | REFLECTED_BASE); // We can be certain base will be done by reflect fields if not already
																			  // done.
			}
		}
	}

	public JavaClass getSupertype() {
		// If this is an interface, there is no supertype. However, the eSuperTypes IS filled in with any interface that this extends. 
		if (isInterface())
			return null;
		List list = getESuperTypes();
		return (!list.isEmpty()) ? (JavaClass) list.get(0) : null;
	}

	public JavaClass getWrapper() {
		return this;
	}

	/**
	 * Test whether the receiver implements the passed interface (or one of its supertypes).
	 */
	public boolean implementsInterface(JavaClass interfaceType) {
		if (this == interfaceType)
			return true;
		EList implemented = getImplementsInterfaces();
		JavaClass anInterface;
		for (int i = 0; i < implemented.size(); i++) {
			anInterface = (JavaClass) implemented.get(i);
			if (anInterface.implementsInterface(interfaceType))
				return true;
		}
		if (getSupertype() != null)
			return getSupertype().implementsInterface(interfaceType);
		else
			return false;
	}

	/**
	 * Return a string showing our details.
	 */
	public String infoString() {
		StringBuffer out = new StringBuffer();
		// trip class reflection
		//FB this.eGet(JavaRefPackage.eINSTANCE.getJavaClass_Public());
		reflectBase(); //FB
		out.append("Java class: " + getQualifiedName() + "\n");
		out.append("  superclass: " + this.getSupertype() + "\n");
		EList fields = getFields();
		Field field;
		if (fields.size() > 0) {
			out.append("  Fields:\n");
			for (int i = 0; i < fields.size(); i++) {
				field = (Field) fields.get(i);
				out.append("    " + ((JavaHelpers) field.getEType()).getJavaName() + " " + field.getName() + "\n");
			}
		}
		EList methods = getMethods();
		Method method;
		if (methods.size() > 0) {
			out.append("  Methods:\n");
			for (int i = 0; i < methods.size(); i++) {
				method = (Method) methods.get(i);
				// trip method reflection
				method.isStatic();
				if (method.getReturnType() != null)
					out.append("    " + method.getReturnType().getJavaName() + " ");
				else
					out.append("    void ");
				out.append(method.getName() + "(");
				EList parms = method.getParameters();
				JavaParameter parm;
				if (parms.size() > 0) {
					for (int ii = 0; ii < parms.size(); ii++) {
						parm = (JavaParameter) parms.get(ii);
						//FB if (!parm.isReturn()) {
						out.append(((JavaHelpers) parm.getEType()).getJavaName() + " " + parm.getName());
						if (ii < parms.size() - 1)
							out.append(", ");
						//FB }
					}
				}
				out.append(")\n");
			}
		}
		return out.toString();
	}

	/**
	 * Tests whether this class inherits from the passed in class.
	 */
	public boolean inheritsFrom(JavaClass javaClass) {
		if (this == javaClass)
			return true;
		else if (getSupertype() != null)
			return getSupertype().inheritsFrom(javaClass);
		else
			return false;
	}

	public boolean isArray() {
		return false;
	}

	/**
	 * Can an object of the passed in class be assigned to an object of this class. In other words is this class a supertype of the passed in class,
	 * or is it superinterface of it.
	 */
	public boolean isAssignableFrom(EClassifier aClass) {
		if (aClass instanceof JavaClass) {
			JavaClass theClass = (JavaClass) aClass;
			// If either this class or aClass kind is unknown then it isn't assignableFrom.
			if (getKind() == TypeKind.UNDEFINED_LITERAL || theClass.getKind() == TypeKind.UNDEFINED_LITERAL)
				return false;
			// If the "aClass" is not a JavaClass (i.e. it is either a JavaDatatype or
			// some other kind of MOF classifier), then it cannot be
			// assigned to something of this class.
			if (getKind() != TypeKind.INTERFACE_LITERAL)
				if (theClass.getKind() != TypeKind.INTERFACE_LITERAL)
					return theClass.inheritsFrom(this);
				else {
					// aClass is an interface, so it is assignable only if
					// "this" is "java.lang.Object".
					return getQualifiedName().equals("java.lang.Object");
				}
			else
				return theClass.implementsInterface(this);
		}
		return false;
	}

	/**
	 * Does this type exist.
	 */
	public boolean isExistingType() {
		// TODO: Temporary, inefficient implementation
		JavaReflectionAdaptor adapter = (JavaReflectionAdaptor) getReadAdapter();
		if (adapter != null)
		    return (adapter).hasReflectionSource();
		else
			return false;
	}

	/**
	 * See if this is valid object of this type.
	 */
	public boolean isInstance(Object o) {
		return o instanceof IInstantiationInstance ? isAssignableFrom(((IInstantiationInstance) o).getJavaType()) : false;
	}

	/**
	 * Is this an interface.
	 */
	public boolean isInterface() {
		return getKind() == TypeKind.INTERFACE_LITERAL;
	}

	public boolean isNested() {
		return getDeclaringClass() != null;
	}

	public boolean isPrimitive() {
		return false;
	}

	/**
	 * Return an array listing our fields, including inherited fields. The field relationship is derived from contents. This implementation depends on
	 * the assumption that supertypes above JavaClass will hold Attributes rather than Fields.
	 */
	public Field[] listFieldExtended() {
		List fields = getFieldsExtended();
		Field[] result = new Field[fields.size()];
		fields.toArray(result);
		return result;
	}

	/**
	 * Return an array listing our Methods, including inherited methods. The method relationship is derived from contents. This implementation depends
	 * on the assumption that supertypes above JavaClass will hold Operations rather than Methods.
	 */
	public Method[] listMethodExtended() {
		java.util.List methods = getMethodsExtended();
		Method[] result = new Method[methods.size()];
		methods.toArray(result);
		return result;
	}

	/**
	 * This is required for internal reflection do not use.
	 */
	public String primGetName() {
		return super.getName();
	}

	/**
	 * This is required for internal reflection do not use.
	 */
	public String primGetQualifiedName() {
		String result = "";
		if (eIsProxy()) {
			result = JavaRefFactory.eINSTANCE.getFullTypeName(eProxyURI());
		} else {
			JavaPackage pack = getJavaPackage();
			if (pack != null && pack.getPackageName().length() != 0)
				result = pack.getPackageName() + "." + ((JavaRefFactoryImpl) JavaRefFactory.eINSTANCE).primGetTypeName(this.primGetName());
			else
				result = this.getName();
		}
		return result;
	}

	/**
	 * reflect - reflect a JavaClass for a given qualified name. If the package or class does not exist, one will be created through the reflection
	 * mechanism. Lookup the JavaClass in the context of the passed object, handling some error cases.
	 * 
	 * @deprecated @see org.eclipse.jem.java.JavaRefFactory#reflectType(java.lang.String, org.eclipse.emf.ecore.EObject)
	 *  
	 */
	public static JavaHelpers reflect(String aQualifiedName, EObject relatedObject) {
		return JavaRefFactory.eINSTANCE.reflectType(aQualifiedName, relatedObject);
	}

	/**
	 * reflect - reflect a JavaClass for a given qualified name. If the package or class does not exist, one will be created through the reflection
	 * mechanism.
	 * 
	 * @deprecated @see org.eclipse.jem.java.JavaRefFactory#reflectType(java.lang.String, org.eclipse.emf.ecore.resource.ResourceSet)
	 */
	public static JavaHelpers reflect(String aQualifiedName, ResourceSet set) {
		return JavaRefFactory.eINSTANCE.reflectType(aQualifiedName, set);
	}

	/**
	 * reflect - reflect a JavaClass for a given package name or class name. If the package or class does not exist, one will be created through the
	 * reflection mechanism.
	 * 
	 * @deprecated @see org.eclipse.jem.java.JavaRefFactory#reflectType(java.lang.String, java.lang.String,
	 *             org.eclipse.emf.ecore.resource.ResourceSet)
	 */
	public static JavaHelpers reflect(String aPackageName, String aClassName, ResourceSet set) {
		return JavaRefFactory.eINSTANCE.reflectType(aPackageName, aClassName, set);
	}

	public void setSupertype(JavaClass aJavaClass) throws InheritanceCycleException {
		validateSupertype(aJavaClass);
		List s = super.getESuperTypes();
		s.clear();
		if (aJavaClass != null)
			s.add(aJavaClass);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain eInverseAdd(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
		switch (featureID) {
			case JavaRefPackage.JAVA_CLASS__FIELDS:
				return ((InternalEList)getFields()).basicAdd(otherEnd, msgs);
			case JavaRefPackage.JAVA_CLASS__METHODS:
				return ((InternalEList)getMethods()).basicAdd(otherEnd, msgs);
			case JavaRefPackage.JAVA_CLASS__INITIALIZERS:
				return ((InternalEList)getInitializers()).basicAdd(otherEnd, msgs);
			case JavaRefPackage.JAVA_CLASS__DECLARED_CLASSES:
				return ((InternalEList)getDeclaredClasses()).basicAdd(otherEnd, msgs);
			case JavaRefPackage.JAVA_CLASS__DECLARING_CLASS:
				if (declaringClass != null)
					msgs = ((InternalEObject)declaringClass).eInverseRemove(this, JavaRefPackage.JAVA_CLASS__DECLARED_CLASSES, JavaClass.class, msgs);
				return basicSetDeclaringClass((JavaClass)otherEnd, msgs);
		}
		return super.eInverseAdd(otherEnd, featureID, msgs);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
		switch (featureID) {
			case JavaRefPackage.JAVA_CLASS__FIELDS:
				return ((InternalEList)getFields()).basicRemove(otherEnd, msgs);
			case JavaRefPackage.JAVA_CLASS__METHODS:
				return ((InternalEList)getMethods()).basicRemove(otherEnd, msgs);
			case JavaRefPackage.JAVA_CLASS__INITIALIZERS:
				return ((InternalEList)getInitializers()).basicRemove(otherEnd, msgs);
			case JavaRefPackage.JAVA_CLASS__DECLARED_CLASSES:
				return ((InternalEList)getDeclaredClasses()).basicRemove(otherEnd, msgs);
			case JavaRefPackage.JAVA_CLASS__DECLARING_CLASS:
				return basicSetDeclaringClass(null, msgs);
			case JavaRefPackage.JAVA_CLASS__EVENTS:
				return ((InternalEList)getEvents()).basicRemove(otherEnd, msgs);
		}
		return super.eInverseRemove(otherEnd, featureID, msgs);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public Object eGet(int featureID, boolean resolve, boolean coreType) {
		switch (featureID) {
			case JavaRefPackage.JAVA_CLASS__KIND:
				return getKind();
			case JavaRefPackage.JAVA_CLASS__PUBLIC:
				return isPublic() ? Boolean.TRUE : Boolean.FALSE;
			case JavaRefPackage.JAVA_CLASS__FINAL:
				return isFinal() ? Boolean.TRUE : Boolean.FALSE;
			case JavaRefPackage.JAVA_CLASS__IMPLEMENTS_INTERFACES:
				return getImplementsInterfaces();
			case JavaRefPackage.JAVA_CLASS__CLASS_IMPORT:
				return getClassImport();
			case JavaRefPackage.JAVA_CLASS__PACKAGE_IMPORTS:
				return getPackageImports();
			case JavaRefPackage.JAVA_CLASS__FIELDS:
				return getFields();
			case JavaRefPackage.JAVA_CLASS__METHODS:
				return getMethods();
			case JavaRefPackage.JAVA_CLASS__INITIALIZERS:
				return getInitializers();
			case JavaRefPackage.JAVA_CLASS__DECLARED_CLASSES:
				return getDeclaredClasses();
			case JavaRefPackage.JAVA_CLASS__DECLARING_CLASS:
				if (resolve) return getDeclaringClass();
				return basicGetDeclaringClass();
			case JavaRefPackage.JAVA_CLASS__JAVA_PACKAGE:
				if (resolve) return getJavaPackage();
				return basicGetJavaPackage();
			case JavaRefPackage.JAVA_CLASS__EVENTS:
				return getEvents();
			case JavaRefPackage.JAVA_CLASS__ALL_EVENTS:
				return getAllEvents();
		}
		return super.eGet(featureID, resolve, coreType);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void eSet(int featureID, Object newValue) {
		switch (featureID) {
			case JavaRefPackage.JAVA_CLASS__KIND:
				setKind((TypeKind)newValue);
				return;
			case JavaRefPackage.JAVA_CLASS__PUBLIC:
				setPublic(((Boolean)newValue).booleanValue());
				return;
			case JavaRefPackage.JAVA_CLASS__FINAL:
				setFinal(((Boolean)newValue).booleanValue());
				return;
			case JavaRefPackage.JAVA_CLASS__IMPLEMENTS_INTERFACES:
				getImplementsInterfaces().clear();
				getImplementsInterfaces().addAll((Collection)newValue);
				return;
			case JavaRefPackage.JAVA_CLASS__CLASS_IMPORT:
				getClassImport().clear();
				getClassImport().addAll((Collection)newValue);
				return;
			case JavaRefPackage.JAVA_CLASS__PACKAGE_IMPORTS:
				getPackageImports().clear();
				getPackageImports().addAll((Collection)newValue);
				return;
			case JavaRefPackage.JAVA_CLASS__FIELDS:
				getFields().clear();
				getFields().addAll((Collection)newValue);
				return;
			case JavaRefPackage.JAVA_CLASS__METHODS:
				getMethods().clear();
				getMethods().addAll((Collection)newValue);
				return;
			case JavaRefPackage.JAVA_CLASS__INITIALIZERS:
				getInitializers().clear();
				getInitializers().addAll((Collection)newValue);
				return;
			case JavaRefPackage.JAVA_CLASS__DECLARED_CLASSES:
				getDeclaredClasses().clear();
				getDeclaredClasses().addAll((Collection)newValue);
				return;
			case JavaRefPackage.JAVA_CLASS__DECLARING_CLASS:
				setDeclaringClass((JavaClass)newValue);
				return;
			case JavaRefPackage.JAVA_CLASS__EVENTS:
				getEvents().clear();
				getEvents().addAll((Collection)newValue);
				return;
			case JavaRefPackage.JAVA_CLASS__ALL_EVENTS:
				getAllEvents().clear();
				getAllEvents().addAll((Collection)newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void eUnset(int featureID) {
		switch (featureID) {
			case JavaRefPackage.JAVA_CLASS__KIND:
				setKind(KIND_EDEFAULT);
				return;
			case JavaRefPackage.JAVA_CLASS__PUBLIC:
				setPublic(PUBLIC_EDEFAULT);
				return;
			case JavaRefPackage.JAVA_CLASS__FINAL:
				setFinal(FINAL_EDEFAULT);
				return;
			case JavaRefPackage.JAVA_CLASS__IMPLEMENTS_INTERFACES:
				getImplementsInterfaces().clear();
				return;
			case JavaRefPackage.JAVA_CLASS__CLASS_IMPORT:
				getClassImport().clear();
				return;
			case JavaRefPackage.JAVA_CLASS__PACKAGE_IMPORTS:
				getPackageImports().clear();
				return;
			case JavaRefPackage.JAVA_CLASS__FIELDS:
				getFields().clear();
				return;
			case JavaRefPackage.JAVA_CLASS__METHODS:
				getMethods().clear();
				return;
			case JavaRefPackage.JAVA_CLASS__INITIALIZERS:
				getInitializers().clear();
				return;
			case JavaRefPackage.JAVA_CLASS__DECLARED_CLASSES:
				getDeclaredClasses().clear();
				return;
			case JavaRefPackage.JAVA_CLASS__DECLARING_CLASS:
				setDeclaringClass((JavaClass)null);
				return;
			case JavaRefPackage.JAVA_CLASS__EVENTS:
				getEvents().clear();
				return;
			case JavaRefPackage.JAVA_CLASS__ALL_EVENTS:
				getAllEvents().clear();
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case JavaRefPackage.JAVA_CLASS__KIND:
				return kind != KIND_EDEFAULT;
			case JavaRefPackage.JAVA_CLASS__PUBLIC:
				return ((eFlags & PUBLIC_EFLAG) != 0) != PUBLIC_EDEFAULT;
			case JavaRefPackage.JAVA_CLASS__FINAL:
				return ((eFlags & FINAL_EFLAG) != 0) != FINAL_EDEFAULT;
			case JavaRefPackage.JAVA_CLASS__IMPLEMENTS_INTERFACES:
				return implementsInterfaces != null && !implementsInterfaces.isEmpty();
			case JavaRefPackage.JAVA_CLASS__CLASS_IMPORT:
				return classImport != null && !classImport.isEmpty();
			case JavaRefPackage.JAVA_CLASS__PACKAGE_IMPORTS:
				return packageImports != null && !packageImports.isEmpty();
			case JavaRefPackage.JAVA_CLASS__FIELDS:
				return fields != null && !fields.isEmpty();
			case JavaRefPackage.JAVA_CLASS__METHODS:
				return methods != null && !methods.isEmpty();
			case JavaRefPackage.JAVA_CLASS__INITIALIZERS:
				return initializers != null && !initializers.isEmpty();
			case JavaRefPackage.JAVA_CLASS__DECLARED_CLASSES:
				return declaredClasses != null && !declaredClasses.isEmpty();
			case JavaRefPackage.JAVA_CLASS__DECLARING_CLASS:
				return declaringClass != null;
			case JavaRefPackage.JAVA_CLASS__JAVA_PACKAGE:
				return basicGetJavaPackage() != null;
			case JavaRefPackage.JAVA_CLASS__EVENTS:
				return events != null && !events.isEmpty();
			case JavaRefPackage.JAVA_CLASS__ALL_EVENTS:
				return !getAllEvents().isEmpty();
		}
		return super.eIsSet(featureID);
	}

	/**
	 * Check to make sure that the passed JavaClass is a valid super class (i.e., it does not create any cycles in the inheritance.
	 * 
	 * @param aJavaClass
	 */
	protected void validateSupertype(JavaClass aJavaClass) throws InheritanceCycleException {
		if (!isValidSupertype(aJavaClass))
			throw new InheritanceCycleException(this, aJavaClass);
	}

	public boolean isValidSupertype(JavaClass aJavaClass) {
		if (aJavaClass != null) {
			if (this.equals(aJavaClass))
				return false;
			return extendedIsValidSupertype(getSubtypes(), aJavaClass);
		}
		return true;
	}

	/**
	 * @param subtypes
	 * @param aJavaClass
	 */
	private boolean extendedIsValidSupertype(List subtypes, JavaClass aJavaClass) {
		if (!basicIsValidSupertype(subtypes, aJavaClass))
			return false;
		JavaClass subtype;
		for (int i = 0; i < subtypes.size(); i++) {
			subtype = (JavaClass) subtypes.get(i);
			if (!subtype.isValidSupertype(aJavaClass))
				return false;
		}
		return true;
	}

	private boolean basicIsValidSupertype(List subtypes, JavaClass aJavaClass) {
		JavaClass subtype;
		for (int i = 0; i < subtypes.size(); i++) {
			subtype = (JavaClass) subtypes.get(i);
			if (subtype.equals(aJavaClass))
				return false;
		}
		return true;
	}

	protected List getSubtypes() {
		return getESuperAdapter().getSubclasses();
	}

	public String toString() {
		return getClass().getName() + "(" + getQualifiedName() + ")";
	}

	public TypeKind getKind() {
		reflectBase();
		return getKindGen();
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setKind(TypeKind newKind) {
		TypeKind oldKind = kind;
		kind = newKind == null ? KIND_EDEFAULT : newKind;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, JavaRefPackage.JAVA_CLASS__KIND, oldKind, kind));
	}

	public boolean isPublic() {
		reflectBase();
		return isPublicGen();
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setPublic(boolean newPublic) {
		boolean oldPublic = (eFlags & PUBLIC_EFLAG) != 0;
		if (newPublic) eFlags |= PUBLIC_EFLAG; else eFlags &= ~PUBLIC_EFLAG;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, JavaRefPackage.JAVA_CLASS__PUBLIC, oldPublic, newPublic));
	}

	public boolean isFinal() {
		reflectBase();
		return isFinalGen();
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setFinal(boolean newFinal) {
		boolean oldFinal = (eFlags & FINAL_EFLAG) != 0;
		if (newFinal) eFlags |= FINAL_EFLAG; else eFlags &= ~FINAL_EFLAG;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, JavaRefPackage.JAVA_CLASS__FINAL, oldFinal, newFinal));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public TypeKind getKindGen() {
		return kind;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public boolean isPublicGen() {
		return (eFlags & PUBLIC_EFLAG) != 0;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public boolean isFinalGen() {
		return (eFlags & FINAL_EFLAG) != 0;
	}

	public EList getInitializers() {
		if (initializers == null) {
			initializers = new EObjectContainmentWithInverseEList(Initializer.class, this, JavaRefPackage.JAVA_CLASS__INITIALIZERS,
					JavaRefPackage.INITIALIZER__JAVA_CLASS);
		}
		return initializers;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setDeclaringClass(JavaClass newDeclaringClass) {
		if (newDeclaringClass != declaringClass) {
			NotificationChain msgs = null;
			if (declaringClass != null)
				msgs = ((InternalEObject)declaringClass).eInverseRemove(this, JavaRefPackage.JAVA_CLASS__DECLARED_CLASSES, JavaClass.class, msgs);
			if (newDeclaringClass != null)
				msgs = ((InternalEObject)newDeclaringClass).eInverseAdd(this, JavaRefPackage.JAVA_CLASS__DECLARED_CLASSES, JavaClass.class, msgs);
			msgs = basicSetDeclaringClass(newDeclaringClass, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, JavaRefPackage.JAVA_CLASS__DECLARING_CLASS, newDeclaringClass, newDeclaringClass));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public JavaClass getDeclaringClass() {
		if (declaringClass != null && declaringClass.eIsProxy()) {
			InternalEObject oldDeclaringClass = (InternalEObject)declaringClass;
			declaringClass = (JavaClass)eResolveProxy(oldDeclaringClass);
			if (declaringClass != oldDeclaringClass) {
				if (eNotificationRequired())
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, JavaRefPackage.JAVA_CLASS__DECLARING_CLASS, oldDeclaringClass, declaringClass));
			}
		}
		return declaringClass;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public JavaClass basicGetDeclaringClass() {
		return declaringClass;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain basicSetDeclaringClass(JavaClass newDeclaringClass, NotificationChain msgs) {
		JavaClass oldDeclaringClass = declaringClass;
		declaringClass = newDeclaringClass;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, JavaRefPackage.JAVA_CLASS__DECLARING_CLASS, oldDeclaringClass, newDeclaringClass);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

	public EList getDeclaredClasses() {
		reflectBase();
		return getDeclaredClassesGen();
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public EList getDeclaredClassesGen() {
		if (declaredClasses == null) {
			declaredClasses = new EObjectWithInverseResolvingEList(JavaClass.class, this, JavaRefPackage.JAVA_CLASS__DECLARED_CLASSES, JavaRefPackage.JAVA_CLASS__DECLARING_CLASS);
		}
		return declaredClasses;
	}

	public EList getProperties() {
		return getEStructuralFeatures(); // As of EMF 2.0, local properties are the local features. Used to be a merge of eattributes and ereferences.
	}

	public EList getEvents() {
		IIntrospectionAdapter adapter = getIntrospectionAdapter();
		if (adapter != null)
			return adapter.getEvents();
		return getEventsGen();
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public EList getEventsGen() {
		if (events == null) {
			events = new EObjectContainmentEList(JavaEvent.class, this, JavaRefPackage.JAVA_CLASS__EVENTS);
		}
		return events;
	}

	private EList allEvents;

	public EList getAllEvents() {
		IIntrospectionAdapter ia = getIntrospectionAdapter();
		if (ia == null)
			return ECollections.EMPTY_ELIST; // No introspection, do normal.
		return allEvents = ia.getAllEvents();
	}

	public EList getAllEventsGen() {
		return allEvents;
	}

	private EList allProperties;

	public EList getAllProperties() {
		IIntrospectionAdapter ia = getIntrospectionAdapter();
		if (ia == null)
			return ECollections.EMPTY_ELIST; // No introspection, do normal.
		return allProperties = ia.getAllProperties();
	}

	public EList getAllPropertiesGen() {
		return allProperties;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *  
	 */
	public EList getImplementsInterfacesGen() {
		if (implementsInterfaces == null) {
			implementsInterfaces = new EObjectResolvingEList(JavaClass.class, this, JavaRefPackage.JAVA_CLASS__IMPLEMENTS_INTERFACES) {

				/**
				 * Comment for <code>serialVersionUID</code>
				 * 
				 * @since 1.1.0
				 */
				private static final long serialVersionUID = 1L;

				public Object get(int index) {
					if (isInterface())
						getInterfaceSuperTypes().get(index); //force resolution so the ESuperAdapter will be updated correctly
					return super.get(index);
				}

				public void clear() {
					super.clear();
					if (isInterface())
						getInterfaceSuperTypes().clear();
				}

				public Object remove(int index) {
					Object result = super.remove(index);
					if (isInterface())
						getInterfaceSuperTypes().remove(index);
					return result;

				}

				public boolean removeAll(Collection collection) {
					boolean result = super.removeAll(collection);
					if (isInterface())
						getInterfaceSuperTypes().removeAll(collection);
					return result;
				}

				public void add(int index, Object object) {
					super.add(index, object);
					if (isInterface())
						getInterfaceSuperTypes().add(index, object);
				}

				public boolean add(Object object) {
					boolean result = super.add(object);
					if (isInterface())
						getInterfaceSuperTypes().add(object);
					return result;
				}

				public boolean addAll(Collection collection) {
					boolean result = super.addAll(collection);
					if (isInterface())
						getInterfaceSuperTypes().addAll(collection);
					return result;
				}

				public boolean addAll(int index, Collection collection) {
					boolean result = super.addAll(index, collection);
					if (isInterface())
						getInterfaceSuperTypes().addAll(index, collection);
					return result;
				}
			};
		}
		return implementsInterfaces;
	}

	private EList getInterfaceSuperTypes() {
		return super.getESuperTypes();
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public EList getClassImportGen() {
		if (classImport == null) {
			classImport = new EObjectResolvingEList(JavaClass.class, this, JavaRefPackage.JAVA_CLASS__CLASS_IMPORT);
		}
		return classImport;
	}

	public EList getEAllSuperTypes() {
		reflectBase();//Force reflection, if needed, before getting all supertypes.
		return super.getEAllSuperTypes();
	}

	public EList getESuperTypes() {
		reflectBase();
		return super.getESuperTypes();
	}
	
	/**
	 * This method is not meant to be used by others. It is here so that the reflection
	 * adapters can reference the unreflected supertypes.
	 *  
	 * @return
	 * 
	 * @since 1.1.0
	 */
	public EList primGetESuperTypes() {
		return super.getESuperTypes();
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public EList getPackageImportsGen() {
		if (packageImports == null) {
			packageImports = new EObjectResolvingEList(JavaPackage.class, this, JavaRefPackage.JAVA_CLASS__PACKAGE_IMPORTS);
		}
		return packageImports;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public EList getFieldsGen() {
		if (fields == null) {
			fields = new EObjectContainmentWithInverseEList(Field.class, this, JavaRefPackage.JAVA_CLASS__FIELDS, JavaRefPackage.FIELD__JAVA_CLASS);
		}
		return fields;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public EList getMethodsGen() {
		if (methods == null) {
			methods = new EObjectContainmentWithInverseEList(Method.class, this, JavaRefPackage.JAVA_CLASS__METHODS, JavaRefPackage.METHOD__JAVA_CLASS);
		}
		return methods;
	}

	/**
	 * @generated This field/method will be replaced during code generation 
	 */
	public JavaPackage getJavaPackageGen() {
		JavaPackage javaPackage = basicGetJavaPackage();
		return javaPackage != null && javaPackage.eIsProxy() ? (JavaPackage)eResolveProxy((InternalEObject)javaPackage) : javaPackage;
	}

	/*
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 */
	public JavaPackage basicGetJavaPackage() {
		return getJavaPackage();
	}

	/**
	 * @generated This field/method will be replaced during code generation.
	 */
	public String toStringGen() {
		if (eIsProxy()) return super.toString();

		StringBuffer result = new StringBuffer(super.toString());
		result.append(" (kind: ");
		result.append(kind);
		result.append(", public: ");
		result.append((eFlags & PUBLIC_EFLAG) != 0);
		result.append(", final: ");
		result.append((eFlags & FINAL_EFLAG) != 0);
		result.append(')');
		return result.toString();
	}

	/*
	 * This should never be called with true. It is basically only for reset of reflection, not to set a particular state. But InternalReadAdaptable
	 * may be used by someone that shouldn't so to be be safe we keep it. TODO Remove InternalReadAdaptable in next version. Need to wait because we
	 * need time to notify everyone.
	 * 
	 * @see org.eclipse.jem.java.adapters.InternalReadAdaptable#setReflected(boolean)
	 */
	public synchronized void setReflected(boolean aBoolean) {
		if (!aBoolean)
			reflectionStatus = NOT_REFLECTED;
	}
	/* (non-Javadoc)
	 * @see org.eclipse.jem.java.JavaClass#getReflectionType()
	 */
	public Object getReflectionType() {
		JavaReflectionAdaptor ja = ((JavaReflectionAdaptor) getReadAdapter());
		return ja != null ? ja.getReflectionSource() : null;
	}
	@Override
	  public EList<EObject> eContents()
	  {
	    return EContentsEList.createEContentsEList(this);
	  }

	  @Override
	  public EList<EObject> eCrossReferences()
	  {
	    return ECrossReferenceEList.createECrossReferenceEList(this);
	  }
}
