/*******************************************************************************
 * Copyright (c) 2001, 2005 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.internal.proxy.remote;

/*
 *  $RCSfile: REMStandardBeanTypeProxyFactory.java,v $
 *  $Revision: 1.16 $  $Date: 2005/08/24 20:39:06 $ 
 */

import java.text.MessageFormat;
import java.util.*;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jem.internal.proxy.core.*;
import org.eclipse.jem.internal.proxy.core.ExpressionProxy.ProxyEvent;
import org.eclipse.jem.internal.proxy.common.CommandException;
import org.eclipse.jem.internal.proxy.common.MapTypes;
import org.eclipse.jem.internal.proxy.common.remote.CommandErrorException;
import org.eclipse.jem.internal.proxy.common.remote.Commands;

/**
 * We are a beanTypeProxyFactory for creating REMBeanTypeProxy objects Primitive types as well as common types like String are cached for speed of
 * lookup. We are the standard one that the VCE uses. Creation date: (12/3/99 2:32:48 PM)
 * 
 * @author: Joe Winchester
 */
public final class REMStandardBeanTypeProxyFactory implements IStandardBeanTypeProxyFactory {

	protected final REMProxyFactoryRegistry fFactoryRegistry;

	protected REMStandardBeanProxyFactory fBeanFactory;

	// Hashtable to cache proxies for classes so they are found on second and subsequent lookups
	protected Map fBeanProxies = new HashMap(1000);

	// A Cache of bean type proxies that should not ever be released. These are the standard ones
	// that we create here. They are never released because they wouldn't be correctly re-created
	// if they were. Also they are standard ones with standard ID's that don't change so they
	// don't need to be re-created later.
	protected Set fPermanentProxies = new HashSet(30);

	// Cache of requested but not found bean types. If not maintaining the list, this variable will be null.
	// The values are strings (classnames in JNI format).
	protected Set fNotFoundTypes = null;

	// Cached copy of a few typical bean type proxies.
	REMBeanTypeProxy objectClass;

	REMClassBeanTypeProxy classClass;

	REMVoidBeanTypeProxy voidType;

	REMBooleanTypeBeanTypeProxy booleanType;

	REMBooleanClassBeanTypeProxy booleanClass;

	REMIntegerTypeBeanTypeProxy intType;

	REMIntegerClassBeanTypeProxy integerClass;

	REMByteTypeBeanTypeProxy byteType;

	REMByteClassBeanTypeProxy byteClass;

	REMShortClassBeanTypeProxy shortClass;

	REMShortTypeBeanTypeProxy shortType;

	REMLongClassBeanTypeProxy longClass;

	REMLongTypeBeanTypeProxy longType;

	REMDoubleClassBeanTypeProxy doubleClass;

	REMDoubleTypeBeanTypeProxy doubleType;

	REMFloatClassBeanTypeProxy floatClass;

	REMFloatTypeBeanTypeProxy floatType;

	REMBigDecimalBeanTypeProxy bigDecimalClass;

	REMBigIntegerBeanTypeProxy bigIntegerClass;

	REMCharacterTypeBeanTypeProxy charType;

	REMCharacterClassBeanTypeProxy characterClass;

	REMStringBeanTypeProxy stringClass;

	/**
	 * Available to all REM beantypes.
	 */
	public REMProxyConstants proxyConstants;

	/**
	 * IDEBeanTypeProxyFactory constructor comment.
	 */
	REMStandardBeanTypeProxyFactory(REMProxyFactoryRegistry aRegistry) {
		fFactoryRegistry = aRegistry;
		aRegistry.registerBeanTypeProxyFactory(this);

		proxyConstants = new REMProxyConstants(aRegistry);

		// Now initialize the cache.
		objectClass = new REMBeanTypeProxy(fFactoryRegistry, new Integer(Commands.OBJECT_CLASS), Object.class.getName(), null);
		classClass = new REMClassBeanTypeProxy(fFactoryRegistry, objectClass);
		voidType = new REMVoidBeanTypeProxy(fFactoryRegistry);
		booleanType = new REMBooleanTypeBeanTypeProxy(fFactoryRegistry);
		booleanClass = new REMBooleanClassBeanTypeProxy(fFactoryRegistry, objectClass);
		IBeanTypeProxy numberClass = objectClass.newBeanTypeForClass(new Integer(Commands.NUMBER_CLASS), Number.class.getName(), true);
		intType = new REMIntegerTypeBeanTypeProxy(fFactoryRegistry);
		integerClass = new REMIntegerClassBeanTypeProxy(fFactoryRegistry, numberClass);
		byteType = new REMByteTypeBeanTypeProxy(fFactoryRegistry);
		byteClass = new REMByteClassBeanTypeProxy(fFactoryRegistry, numberClass);
		shortType = new REMShortTypeBeanTypeProxy(fFactoryRegistry);
		shortClass = new REMShortClassBeanTypeProxy(fFactoryRegistry, numberClass);
		longType = new REMLongTypeBeanTypeProxy(fFactoryRegistry);
		longClass = new REMLongClassBeanTypeProxy(fFactoryRegistry, numberClass);
		doubleType = new REMDoubleTypeBeanTypeProxy(fFactoryRegistry);
		doubleClass = new REMDoubleClassBeanTypeProxy(fFactoryRegistry, numberClass);
		floatType = new REMFloatTypeBeanTypeProxy(fFactoryRegistry);
		floatClass = new REMFloatClassBeanTypeProxy(fFactoryRegistry, numberClass);
		bigDecimalClass = new REMBigDecimalBeanTypeProxy(fFactoryRegistry, numberClass);
		bigIntegerClass = new REMBigIntegerBeanTypeProxy(fFactoryRegistry, numberClass);
		charType = new REMCharacterTypeBeanTypeProxy(fFactoryRegistry);
		characterClass = new REMCharacterClassBeanTypeProxy(fFactoryRegistry, objectClass);
		stringClass = new REMStringBeanTypeProxy(fFactoryRegistry, objectClass);
		IBeanTypeProxy throwableClass = new REMThrowableBeanTypeProxy(fFactoryRegistry, new Integer(Commands.THROWABLE_CLASS), Throwable.class
				.getName(), objectClass);
		IBeanTypeProxy threadClass = objectClass.newBeanTypeForClass(new Integer(Commands.THREAD_CLASS), Thread.class.getName(), false);
		IBeanTypeProxy expressionProcessorControllerClass = objectClass.newBeanTypeForClass(new Integer(Commands.EXPRESSIONPROCESSERCONTROLLER_CLASS), "org.eclipse.jem.internal.proxy.vm.remote.ExpressionProcesserController", false); //$NON-NLS-1$

		// Initialize the hashtable with the primitives, their lang equivalents, and also common classes like String

		// Primitives
		fBeanProxies.put(voidType.getTypeName(), voidType);
		fBeanProxies.put(intType.getTypeName(), intType);
		fBeanProxies.put(booleanType.getTypeName(), booleanType);
		fBeanProxies.put(charType.getTypeName(), charType);
		fBeanProxies.put(byteType.getTypeName(), byteType);
		fBeanProxies.put(shortType.getTypeName(), shortType);
		fBeanProxies.put(longType.getTypeName(), longType);
		fBeanProxies.put(floatType.getTypeName(), floatType);
		fBeanProxies.put(doubleType.getTypeName(), doubleType);

		// java.lang primitive peers
		// Note that special classes are used for some of these which allow the IDE to get the
		// lang objects from the objects that are holding proxies
		fBeanProxies.put(integerClass.getTypeName(), integerClass);
		fBeanProxies.put(booleanClass.getTypeName(), booleanClass);
		fBeanProxies.put(characterClass.getTypeName(), characterClass);
		fBeanProxies.put(byteClass.getTypeName(), byteClass);
		fBeanProxies.put(shortClass.getTypeName(), shortClass);
		fBeanProxies.put(longClass.getTypeName(), longClass);
		fBeanProxies.put(floatClass.getTypeName(), floatClass);
		fBeanProxies.put(doubleClass.getTypeName(), doubleClass);
		fBeanProxies.put(bigDecimalClass.getTypeName(), bigDecimalClass);
		fBeanProxies.put(bigIntegerClass.getTypeName(), bigIntegerClass);
		fBeanProxies.put(stringClass.getTypeName(), stringClass);
		fBeanProxies.put(throwableClass.getTypeName(), throwableClass);
		fBeanProxies.put(objectClass.getTypeName(), objectClass);
		fBeanProxies.put(classClass.getTypeName(), classClass);
		fBeanProxies.put(numberClass.getTypeName(), numberClass);
		fBeanProxies.put(threadClass.getTypeName(), threadClass);
		fBeanProxies.put(expressionProcessorControllerClass.getTypeName(), expressionProcessorControllerClass);

		// Mark these as permanent.
		fPermanentProxies.addAll(fBeanProxies.values());
	}

	/**
	 * Initialize AFTER BeanProxyFactory has been created. This is REQUIRED! NOTE: It is package protected so that only REMStandardBeanProxyFactory
	 * can call it when ready.
	 */
	synchronized void initialize(REMStandardBeanProxyFactory proxyFactory) {
		fBeanFactory = proxyFactory;
		fBeanFactory.registerProxies(fBeanProxies.values());
	}

	/*
	 * This is called when we know we don't have the class registered, so we need to create the proxy. We have a connection passed in and will reuse
	 * it as necessary
	 * 
	 * It is important that this be called only from within a transaction.
	 */
	private synchronized IREMBeanTypeProxy createBeanTypeProxy(String typeName, IREMConnection connection) throws CommandException {

		// We don't have the beantype proxy, so create it.
		IREMBeanTypeProxy beanTypeProxy = null;
		Commands.GetClassReturn ret = null;
		try {
			ret = getClassReturn(connection, typeName);
		} catch (ThrowableProxy ep) {
			// Print out the trace and return proxy with init error.
			ProxyPlugin.getPlugin().getLogger().log(new Status(IStatus.WARNING, ProxyPlugin.getPlugin().getBundle().getSymbolicName(), 0, "", ep)); //$NON-NLS-1$
			IREMBeanTypeProxy proxy = new REMInitErrorBeanTypeProxy(fFactoryRegistry, MessageFormat.format(ProxyRemoteMessages.ExceptionErrorMsg_EXC_, new Object[] { ep.getTypeProxy().getTypeName(), ep.getProxyLocalizedMessage()}), typeName); //$NON-NLS-1$
			registerBeanTypeProxy(proxy, false);
			return proxy;
		}
		if (ret == null) {
			if (fNotFoundTypes != null)
				fNotFoundTypes.add(typeName);
			return null; // The class doesn't even exist on the server.
		}

		if (typeName.charAt(0) != '[') {
			// It is not an array.
			IREMBeanTypeProxy superTypeProxy = null;
			if (!ret.isInterface && ret.superClassname.length() != 0) {
				// Get the beantype proxy of the superclass.
				superTypeProxy = getBeanTypeProxy(ret.superClassname, connection);
			}

			// First check with the factory for the package of the class.
			// Inner classes have to use the dollar notation since if they didn't we couldn't tell where
			// the package ended and the class started. This check is here in case the
			// extension factory can handle this class but needs the id from the server to
			// create it.
			int packageIndex = typeName.lastIndexOf('.');
			if (packageIndex != -1) {
				String packageName = typeName.substring(0, packageIndex);
				IREMBeanTypeProxyFactory packageFactory = (IREMBeanTypeProxyFactory) fFactoryRegistry.getBeanTypeProxyFactoryExtension(packageName);
				if (packageFactory != null) {
					beanTypeProxy = packageFactory.getExtensionBeanTypeProxy(typeName, new Integer(ret.classID), superTypeProxy);
					if (beanTypeProxy != null) {
						registerBeanTypeProxy(beanTypeProxy, false);
						return beanTypeProxy;
					}
				}
			}

			if (ret.isInterface) {
				// Interface never have a super type, so we will create a specific type.
				beanTypeProxy = new REMInterfaceBeanTypeProxy(fFactoryRegistry, new Integer(ret.classID), typeName);
			} else {
				// Ask the supertype
				// to create a beantype proxy of the same beantype proxy class.
				// This is so that any subclasses will get the same beantype proxy class
				// for it if it is special.
				if (superTypeProxy != null)
					beanTypeProxy = superTypeProxy.newBeanTypeForClass(new Integer(ret.classID), typeName, ret.isAbstract);
			}
		} else
			beanTypeProxy = new REMArrayBeanTypeProxy(fFactoryRegistry, new Integer(ret.classID), typeName, objectClass);

		// Cache the instance so we can re-use it again
		if (beanTypeProxy != null)
			registerBeanTypeProxy(beanTypeProxy, false);
		return beanTypeProxy;
	}

	/**
	 * Using the helper class to find a class by name, then create the proxy.
	 */
	public IBeanTypeProxy getBeanTypeProxy(String typeName) {
		try {
			return getBeanTypeProxy(MapTypes.getJNIFormatName(typeName), (IREMConnection) null);
		} catch (CommandException e) {
			// Try once more (we won't have received recoverable exceptions here, they were already caught and handled)
			try {
				return getBeanTypeProxy(typeName, (IREMConnection) null);
			} catch (CommandException eAgain) {
				// Failed again.
				ProxyPlugin.getPlugin().getLogger().log(
						new Status(IStatus.WARNING, ProxyPlugin.getPlugin().getBundle().getSymbolicName(), 0, "", eAgain)); //$NON-NLS-1$
			}
		}
		return null;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jem.internal.proxy.core.IStandardBeanTypeProxyFactory#getBeanTypeProxy(org.eclipse.jem.internal.proxy.core.IExpression,
	 *      java.lang.String)
	 */
	public synchronized IProxyBeanType getBeanTypeProxy(IExpression expression, String typeName) {
		typeName = MapTypes.getJNIFormatName(typeName);
		// See whether we already have the proxy for the argument name
		IProxyBeanType beanTypeProxy = (IProxyBeanType) fBeanProxies.get(typeName);
		if (beanTypeProxy != null)
			return beanTypeProxy;
		
		// Now see if an expression proxy cached.
		beanTypeProxy = ((REMExpression) expression).getBeanType(typeName);
		if (beanTypeProxy != null)
			return beanTypeProxy;		

		// If not an array, then see if the package extension mechanism can find it.
		// Do this here so that if it is found in the package extension we won't necessarily create an
		// extra connection when not needed.
		if (typeName.charAt(0) != '[') {
			// It is not an array
			// First check with the factory for the package of the class.
			// Inner classes have to use the dollar notation since if they didn't we couldn't tell where
			// the package ended and the class started.
			int packageIndex = typeName.lastIndexOf('.');
			if (packageIndex != -1) {
				String packageName = typeName.substring(0, packageIndex);
				IREMBeanTypeProxyFactory packageFactory = (IREMBeanTypeProxyFactory) fFactoryRegistry.getBeanTypeProxyFactoryExtension(packageName);
				if (packageFactory != null) {
					beanTypeProxy = packageFactory.getExtensionBeanTypeProxy(typeName, expression);
					if (beanTypeProxy != null) {
						registerBeanTypeProxy(beanTypeProxy, false);
						return beanTypeProxy;
					}
				}
			}
		}

		// Need to create the expression proxy for it.
		beanTypeProxy = ((Expression) expression).createBeanTypeExpressionProxy(typeName);
		registerBeanTypeProxy(beanTypeProxy, false);
		return beanTypeProxy;

	}

	/**
	 * One that internally allows that we already have a connection to work with. If the connection is null, then one will be created.
	 * 
	 * It is important that if the connection is not null, then we are in a transaction.
	 */
	private synchronized IREMBeanTypeProxy getBeanTypeProxy(String typeName, IREMConnection inConnect) throws CommandException {

		// See whether we already have the proxy for the argument name
		IProxyBeanType beanTypeProxy = (IProxyBeanType) fBeanProxies.get(typeName);
		// See if there and resolved, if so, return it. If not resolved, that means we need it NOW
		// so we must go for it. When finally resolved the original ExpressionProxy will be deregistered and
		// the resolved beantypeproxy will be in its place.
		if (beanTypeProxy != null && beanTypeProxy.isBeanProxy()) { return (IREMBeanTypeProxy) beanTypeProxy; }

		// If not an array, then see if the package extension mechanism can find it.
		// Do this here so that if it is found in the package extension we won't necessarily create an
		// extra connection when not needed.
		if (typeName.charAt(0) != '[') {
			// It is not an array
			// First check with the factory for the package of the class.
			// Inner classes have to use the dollar notation since if they didn't we couldn't tell where
			// the package ended and the class started.
			int packageIndex = typeName.lastIndexOf('.');
			if (packageIndex != -1) {
				String packageName = typeName.substring(0, packageIndex);
				IREMBeanTypeProxyFactory packageFactory = (IREMBeanTypeProxyFactory) fFactoryRegistry.getBeanTypeProxyFactoryExtension(packageName);
				if (packageFactory != null) {
					beanTypeProxy = packageFactory.getExtensionBeanTypeProxy(typeName);
					if (beanTypeProxy != null) {
						registerBeanTypeProxy((IREMBeanTypeProxy) beanTypeProxy, false);
						return (IREMBeanTypeProxy) beanTypeProxy;
					}
				}
			}
		}

		IREMConnection connect = inConnect != null ? inConnect : fFactoryRegistry.getFreeConnection();
		if (inConnect == null)
			fBeanFactory.startTransaction(); // Start a transation.
		try {
			return createBeanTypeProxy(typeName, connect);
		} catch (CommandException e) {
			if (inConnect == null) {
				// Need to close the connection, not return it.
				fFactoryRegistry.closeConnection(connect);
				connect = null; // So that it won't be returned.
			}
			throw e; // Pass it on up
		} finally {
			if (inConnect == null)
				fBeanFactory.stopTransaction();
			if (inConnect == null && connect != null)
				fFactoryRegistry.returnConnection(connect);
		}
	}

	/*
	 * It is important this be called only from within a transaction.
	 */
	private Commands.GetClassReturn getClassReturn(IREMConnection connection, String className) throws CommandException, ThrowableProxy {
		try {
			return connection.getClass(className);
		} catch (CommandErrorException e) {
			fBeanFactory.processErrorReturn(e); // Let proxy factory handle the error return
		}
		return null;
	}

	/**
	 * Return an Array type proxy for the given class name of the specified dimensions. This is a helper method. The same result can be gotton from
	 * getBeanTypeProxy. e.g. getBeanTypeProxy("java.lang.Object", 3) is the same as: getBeanTypeProxy("[[[Ljava.lang.Object;")
	 * 
	 * They both result in a type of: Object [][][]
	 * 
	 * or getBeanTypeProxy("[Ljava.langObject;", 3) becomes Object [][][][]
	 */
	public IBeanTypeProxy getBeanTypeProxy(String componentClassName, int dimensions) {
		return getBeanTypeProxy(getArrayClassName(componentClassName, dimensions));
	}

	/**
	 * @param componentClassName
	 * @param dimensions
	 * @return
	 * 
	 * @since 1.1.0
	 */
	private String getArrayClassName(String componentClassName, int dimensions) {
		String jniComponentClassName = MapTypes.getJNIFormatName(componentClassName);
		String compType = jniComponentClassName;
		if (jniComponentClassName.charAt(0) != '[') {
			// We're not already an array, so create correct template.
			compType = (String) MapTypes.MAP_TYPENAME_TO_SHORTSIG.get(jniComponentClassName);
			if (compType == null) {
				// It is a class, and not a type.
				compType = "L" + jniComponentClassName + ";"; //$NON-NLS-1$ //$NON-NLS-2$
			}
		}

		// Now create it with the appropriate number of '[' in front.
		StringBuffer buffer = new StringBuffer(dimensions + compType.length());
		for (int i = 0; i < dimensions; i++)
			buffer.append('[');
		buffer.append(compType);
		return buffer.toString();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jem.internal.proxy.core.IStandardBeanTypeProxyFactory#getBeanTypeProxy(org.eclipse.jem.internal.proxy.core.IExpression,
	 *      java.lang.String, int)
	 */
	public IProxyBeanType getBeanTypeProxy(IExpression expression, String componentClassName, int dimensions) {
		return getBeanTypeProxy(expression, getArrayClassName(componentClassName, dimensions));
	}

	/**
	 * Get the bean type proxy from a class id. This means that a new class id was sent back from the server that we don't have yet. We need to go ask
	 * the server for information on this type so that we can create it.
	 * 
	 * NOTE: This is package protected so that only the standard bean proxy factory can call it.
	 * 
	 * It is important that this has been called within a transaction.
	 */
	IREMBeanTypeProxy createBeanTypeProxy(Integer classID) {
		IREMConnection connect = fFactoryRegistry.getFreeConnection();
		try {
			return createBeanTypeProxy(classID, connect);
		} catch (CommandException e) {
			if (e.isRecoverable()) {
				// It is recoverable, print message, keep connection live and return it.
				ProxyPlugin.getPlugin().getLogger().log(new Status(IStatus.WARNING, ProxyPlugin.getPlugin().getBundle().getSymbolicName(), 0, "", e)); //$NON-NLS-1$
			} else {
				// Try again, close connection, get a new one.
				fFactoryRegistry.closeConnection(connect);
				connect = null;
				connect = fFactoryRegistry.getFreeConnection();
				try {
					return createBeanTypeProxy(classID, connect);
				} catch (CommandException eAgain) {
					// Failed again. Close connection, don't return it.
					ProxyPlugin.getPlugin().getLogger().log(
							new Status(IStatus.WARNING, ProxyPlugin.getPlugin().getBundle().getSymbolicName(), 0, "", eAgain)); //$NON-NLS-1$
					fFactoryRegistry.closeConnection(connect);
					connect = null;
				}
			}
		} finally {
			if (connect != null)
				fFactoryRegistry.returnConnection(connect);
		}
		return null;
	}

	/*
	 * One that internally allows that we already have a connection to work with. If the connection is null, then one will be created.
	 * 
	 * It is important this be called only from within a transaction.
	 */
	private synchronized IREMBeanTypeProxy createBeanTypeProxy(Integer classID, IREMConnection connect) throws CommandException {
		// We don't have the beantype proxy, so create it.
		IREMBeanTypeProxy beanTypeProxy = null;

		Commands.GetClassIDReturn ret = null;
		try {
			ret = getClassIDReturn(connect, classID);
		} catch (ThrowableProxy ep) {
			// Just print out the trace and return proxy not found.
			ProxyPlugin.getPlugin().getLogger().log(new Status(IStatus.WARNING, ProxyPlugin.getPlugin().getBundle().getSymbolicName(), 0, "", ep)); //$NON-NLS-1$
			return null;
		}

		// If the signature is that of a class.
		if (ret.className.charAt(0) != '[') {
			// It is not an array.
			IREMBeanTypeProxy superTypeProxy = null;
			if (!ret.isInterface && ret.superClassname.length() != 0) {
				// Get the beantype proxy of the superclass.
				superTypeProxy = getBeanTypeProxy(ret.superClassname, connect);
			}

			// First check with the factory for the package of the class.
			// Inner classes have to use the dollar notation since if they didn't we couldn't tell where
			// the package ended and the class started.
			int packageIndex = ret.className.lastIndexOf('.');
			if (packageIndex != -1) {
				String packageName = ret.className.substring(0, packageIndex);
				IREMBeanTypeProxyFactory packageFactory = (IREMBeanTypeProxyFactory) fFactoryRegistry.getBeanTypeProxyFactoryExtension(packageName);
				if (packageFactory != null) {
					beanTypeProxy = packageFactory.getExtensionBeanTypeProxy(ret.className, classID, superTypeProxy);
					if (beanTypeProxy != null) {
						registerBeanTypeProxy(beanTypeProxy, false);
						return beanTypeProxy;
					}
				}
			}

			if (ret.isInterface) {
				// Interface never have a super type, so we will let the object class do it for us.
				beanTypeProxy = new REMInterfaceBeanTypeProxy(fFactoryRegistry, classID, ret.className);
			} else {
				// Ask the beantype proxy of the superclass
				// to create a beantype proxy of the same beantype proxy class.
				// This is so that any subclasses will get the same beantype proxy class
				// for it if it is special.
				if (superTypeProxy != null)
					beanTypeProxy = superTypeProxy.newBeanTypeForClass(classID, ret.className, ret.isAbstract);
			}

			// Cache the instance so we can re-use it again
			if (beanTypeProxy != null)
				registerBeanTypeProxy(beanTypeProxy, false);
			return beanTypeProxy;
		} else {
			// It is an array.
			beanTypeProxy = new REMArrayBeanTypeProxy(fFactoryRegistry, classID, ret.className, objectClass);
			registerBeanTypeProxy(beanTypeProxy, false);
			return beanTypeProxy;
		}
	}

	/*
	 * It is important that this be called only from within a transaction.
	 */
	private Commands.GetClassIDReturn getClassIDReturn(IREMConnection connection, Integer classID) throws CommandException, ThrowableProxy {
		try {
			return connection.getClassFromID(classID.intValue());
		} catch (CommandErrorException e) {
			fBeanFactory.processErrorReturn(e); // Let proxy factory handle the error return
		}
		return null;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jem.internal.proxy.core.IStandardBeanTypeProxyFactory#registerBeanTypeProxy(org.eclipse.jem.internal.proxy.core.IBeanTypeProxy,
	 *      boolean)
	 */
	public synchronized void registerBeanTypeProxy(IBeanTypeProxy aBeanTypeProxy, boolean permanent) {
		fBeanProxies.put(aBeanTypeProxy.getTypeName(), aBeanTypeProxy);
		fBeanFactory.registerProxy((IREMBeanProxy) aBeanTypeProxy);
		if (permanent)
			fPermanentProxies.add(aBeanTypeProxy);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jem.internal.proxy.core.IStandardBeanTypeProxyFactory#registerBeanTypeProxy(org.eclipse.jem.internal.proxy.core.IProxyBeanType,
	 *      boolean)
	 */
	public void registerBeanTypeProxy(IProxyBeanType aProxyBeanType, final boolean permanent) {
		if (aProxyBeanType.isBeanProxy())
			registerBeanTypeProxy((IBeanTypeProxy) aProxyBeanType, permanent); // A regular kind, do regular registration.
		else {
			ExpressionProxy beanExpressionProxy = ((ExpressionProxy) aProxyBeanType);
			final String typeName = aProxyBeanType.getTypeName();
			((REMExpression) beanExpressionProxy.getExpression()).addBeanType(typeName, aProxyBeanType);
			beanExpressionProxy.addProxyListener(new ExpressionProxy.ProxyAdapter() {

				public void proxyResolved(ProxyEvent event) {
					String typeName = ((IProxyBeanType) event.getSource()).getTypeName();
					synchronized (REMStandardBeanTypeProxyFactory.this) {
						if (!fBeanProxies.containsKey(typeName)) {
							// It hasn't been resolved through some other means. So this is good. Actually this should never
							// occur because upon resolution we've already registered the bean type proxy through the
							// normal mechanisms. But to be safe, we'll do it here.
							fBeanProxies.put(typeName, event.getProxy());
							if (permanent)
								fPermanentProxies.add(event.getProxy());
						}
					}
				}
				
				public void proxyNotResolved(ExpressionProxy.ProxyEvent event) {
					((REMExpression) ((ExpressionProxy) event.getSource()).getExpression()).removeBeanType(typeName);
				}
			});
		}

	}

	/**
	 * A beantype proxy is asked to be released. We can only release ones that were not in the permanent set that we initialized with. Those in the
	 * permanent set can't be changed so we can't release them.
	 * 
	 * Answer whether it can be released from the server too.
	 * 
	 * NOTE: Package protected since only REMStandardBeanProxyFactory should call it.
	 */
	boolean releaseProxy(IBeanTypeProxy proxy) {
		/**
		 * Currently we won't allow any bean type proxies to be released. We don't have a good strategy for handling that there may be hard refs from
		 * subtypes. One thought is that beanproxies table should store SoftReferences so that only when space is needed, that any beantype that
		 * doesn't have a subtype (since subtypes hold a strong ref) or, is in the permanent table (since that is hardref) could be GC'd. Then what
		 * would happen is on releaseProxy we don't actually release, we change it to a WeakRef so that it would definitely be released on a GC. These
		 * are complicated arch. and we're not sure if it should be allowed or not. So for now, we don't allow them to be released. if
		 * (!fPermanentProxies.contains(proxy)) { // We can release it. It is not one of the permanent ones. synchronized(this) {
		 * fBeanProxies.remove(proxy.getTypeName()); return true; } }
		 */
		return false;
	}

	/*
	 * Terminate this factory. Since all of the proxies are registered in the proxy factory, there is no need to release them here. There is no need
	 * to clear out any fields since this factory will not be held onto by anything and so it will be GC'd.
	 */
	public void terminateFactory(boolean wait) {
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jem.internal.proxy.core.IStandardBeanTypeProxyFactory#isBeanTypeRegistered(String)
	 */
	public synchronized boolean isBeanTypeRegistered(String className) {
		return fBeanProxies.containsKey(MapTypes.getJNIFormatName(className));
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jem.internal.proxy.core.IStandardBeanTypeProxyFactory#registeredTypes()
	 */
	public Set registeredTypes() {
		return fBeanProxies.keySet();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jem.internal.proxy.core.IStandardBeanTypeProxyFactory#isBeanTypeNotFound(String)
	 */
	public synchronized boolean isBeanTypeNotFound(String className) {
		return fNotFoundTypes != null && fNotFoundTypes.contains(MapTypes.getJNIFormatName(className));
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jem.internal.proxy.core.IStandardBeanTypeProxyFactory#isMaintainNotFoundTypes()
	 */
	public synchronized boolean isMaintainNotFoundTypes() {
		return fNotFoundTypes != null;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jem.internal.proxy.core.IStandardBeanTypeProxyFactory#setMaintainNotFoundTypes(boolean)
	 */
	public synchronized void setMaintainNotFoundTypes(boolean maintain) {
		if (maintain) {
			if (fNotFoundTypes == null)
				fNotFoundTypes = new HashSet();
		} else
			fNotFoundTypes = null;
	}

}

