/*******************************************************************************
 * Copyright (c) 2003, 2004 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.tests.proxy;
/*
 *  $RCSfile: TestStandard.java,v $
 *  $Revision: 1.8 $  $Date: 2005/02/15 23:00:16 $ 
 */
import java.io.IOException;

import org.eclipse.jem.internal.proxy.common.AmbiguousMethodException;
import org.eclipse.jem.internal.proxy.core.*;

/**
 * @author richkulp
 *
 * To change the template for this generated type comment go to
 * Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments
 */
public class TestStandard extends AbstractTestProxy {

	/**
	 * 
	 */
	public TestStandard() {
		super();
	}

	/**
	 * @param name
	 */
	public TestStandard(String name) {
		super(name);
	}

	public void testObject() {
		IBeanTypeProxy objectType = proxyTypeFactory.getBeanTypeProxy("java.lang.Object"); //$NON-NLS-1$
		assertNotNull(objectType);
		assertFalse(objectType.isArray());
		assertEquals("java.lang.Object", objectType.getTypeName());
	}
	
	public void testTypeOf() {
		IBeanTypeProxy objectType = proxyTypeFactory.getBeanTypeProxy("java.lang.Object"); //$NON-NLS-1$		
		IBeanTypeProxy integerType = proxyTypeFactory.getBeanTypeProxy("java.lang.Integer"); //$NON-NLS-1$
		assertNotNull(integerType);
		assertEquals("java.lang.Integer", integerType.getTypeName());
		assertTrue(integerType.isKindOf(objectType));		
	}
	
	public void testMethodInvoke() throws ThrowableProxy {		
		IBeanTypeProxy integerType = proxyTypeFactory.getBeanTypeProxy("java.lang.Integer"); //$NON-NLS-1$		
		IMethodProxy mthd = integerType.getMethodProxy("valueOf", "java.lang.String"); //$NON-NLS-1$ //$NON-NLS-2$
		assertNotNull(mthd);
		// See if we can invoke methods.
		IIntegerBeanProxy anInt = (IIntegerBeanProxy) mthd.invoke(null, proxyFactory.createBeanProxyWith("5")); //$NON-NLS-1$
		assertNotNull(anInt);
		assertEquals(5, anInt.intValue());
		// See if invoke with bad type throws the ExceptionProxy.
		try {
			mthd.invoke(null, proxyFactory.createBeanProxyWith(5));
			fail("Exception not thrown like it should of been.");
		} catch (ThrowableProxy e) {
			// We should of gotton the exception. See if it is of the correct type.
			assertEquals("java.lang.IllegalArgumentException", e.getTypeProxy().getTypeName()); //$NON-NLS-1$
		}						
	}

	public void testInvoke() throws ThrowableProxy {
		// Technically invokables should be used for one-shot usage, but here to test the invoke correctly
		// it will be used twice. This is not an error, just overhead.
		IBeanTypeProxy integerType = proxyTypeFactory.getBeanTypeProxy("java.lang.Integer"); //$NON-NLS-1$		
		IInvokable invokable = integerType.getInvokable("valueOf", "java.lang.String"); //$NON-NLS-1$ //$NON-NLS-2$
		assertNotNull(invokable);
		// See if we can invoke methods.
		IIntegerBeanProxy anInt = (IIntegerBeanProxy) invokable.invoke(null, proxyFactory.createBeanProxyWith("5")); //$NON-NLS-1$
		assertNotNull(anInt);
		assertEquals(5, anInt.intValue());
		// See if invoke with bad type throws the ExceptionProxy.
		try {
			invokable.invoke(null, proxyFactory.createBeanProxyWith(5));
			fail("Exception not thrown like it should of been.");
		} catch (ThrowableProxy e) {
			// We should of gotton the exception. See if it is of the correct type.
			assertEquals("java.lang.IllegalArgumentException", e.getTypeProxy().getTypeName()); //$NON-NLS-1$
		}						
	}

	public void testSimpleInitString() throws ThrowableProxy, InstantiationException {
		IBeanTypeProxy integerType = proxyTypeFactory.getBeanTypeProxy("java.lang.Integer"); //$NON-NLS-1$				
		// See if we can create it from an initialization string.
		IIntegerBeanProxy anInt = (IIntegerBeanProxy) integerType.newInstance("new java.lang.Integer(6)"); //$NON-NLS-1$
		assertNotNull(anInt);
		assertEquals(6, anInt.intValue());

		// See if string initialization works.
		IStringBeanProxy aString = (IStringBeanProxy) proxyTypeFactory.getBeanTypeProxy("java.lang.String").newInstance("\"abcd\""); //$NON-NLS-1$ //$NON-NLS-2$
		assertNotNull(aString);
		assertEquals("abcd", aString.stringValue()); //$NON-NLS-1$
	}
	
	public void testGetConstructors() {
		IBeanTypeProxy stringType = proxyTypeFactory.getBeanTypeProxy("java.lang.String"); //$NON-NLS-1$				
		
		// Get all constructors.
		IConstructorProxy[] ctors = stringType.getConstructors();
		assertNotNull(ctors);
		assertEquals(11, ctors.length);		
	}

	public void testGetDeclaredConstructors() {
		IBeanTypeProxy testAccessType = proxyTypeFactory.getBeanTypeProxy("testPackage.TestAccess"); //$NON-NLS-1$				
		
		// Get all constructors.
		IConstructorProxy[] ctors = testAccessType.getDeclaredConstructors();
		assertNotNull(ctors);
		assertEquals(3, ctors.length);		
	}

	public void testSimpleConstructor() throws ThrowableProxy {
		IBeanTypeProxy integerType = proxyTypeFactory.getBeanTypeProxy("java.lang.Integer"); //$NON-NLS-1$				
		
		// See if we can create it from a constructor.
		IConstructorProxy ctor = integerType.getConstructorProxy(new String[] {"java.lang.String"}); //$NON-NLS-1$
		assertNotNull(ctor);
		IIntegerBeanProxy anInt = (IIntegerBeanProxy) ctor.newInstance(new IBeanProxy[] {proxyFactory.createBeanProxyWith("0")}); //$NON-NLS-1$
		assertEquals(0, anInt.intValue());
						
		// Zero is cached, let's see if that is what we got above.
		IIntegerBeanProxy aZero = proxyFactory.createBeanProxyWith(new Integer(0));
		assertSame(anInt, aZero);
	}

	public void testSimpleDeclaredConstructor() throws ThrowableProxy {
		IBeanTypeProxy testAccessType = proxyTypeFactory.getBeanTypeProxy("testPackage.TestAccess"); //$NON-NLS-1$				
		
		// See if we can get a private constructor.
		IConstructorProxy ctor = testAccessType.getDeclaredConstructorProxy(new String[] {"java.lang.RuntimeException"}); //$NON-NLS-1$
		assertNotNull(ctor);
	}

	public void testPrimitiveReturn() throws ThrowableProxy {
		IBeanTypeProxy integerType = proxyTypeFactory.getBeanTypeProxy("java.lang.Integer"); //$NON-NLS-1$				
		
		// See that we get a primitive back when the method return type is a primitive.
		IMethodProxy mthdPrim = integerType.getMethodProxy("intValue"); //$NON-NLS-1$
		IIntegerBeanProxy anInt = (IIntegerBeanProxy) mthdPrim.invoke(proxyFactory.createBeanProxyWith(5));
		assertEquals("int", anInt.getTypeProxy().getTypeName()); //$NON-NLS-1$
		assertEquals(5, anInt.intValue());
		
		// See that we get a primitive back when the field is a primitive.
		IFieldProxy fieldPrim = integerType.getFieldProxy("MIN_VALUE"); //$NON-NLS-1$
		anInt = (IIntegerBeanProxy) fieldPrim.get(null);
		assertEquals("int", anInt.getTypeProxy().getTypeName()); //$NON-NLS-1$
		assertEquals(Integer.MIN_VALUE, anInt.intValue());	
	}
	
	public void testPrimitiveArrayType() {
		// Test Primitive arrays.
		IArrayBeanTypeProxy arrayType = (IArrayBeanTypeProxy) proxyTypeFactory.getBeanTypeProxy("[I"); //$NON-NLS-1$
		assertNotNull(arrayType);
		assertTrue(arrayType.isArray());
		assertEquals("[I", arrayType.getTypeName()); //$NON-NLS-1$
		assertEquals(proxyTypeFactory.getBeanTypeProxy("int"), arrayType.getComponentType()); //$NON-NLS-1$
	}
	
	public void testObjectArrayType() {
		// Test simple object type array
		IArrayBeanTypeProxy arrayType = (IArrayBeanTypeProxy) proxyTypeFactory.getBeanTypeProxy("[Ljava.lang.Integer;"); //$NON-NLS-1$
		assertNotNull(arrayType);
		assertTrue(arrayType.isArray());
		assertEquals("[Ljava.lang.Integer;", arrayType.getTypeName()); //$NON-NLS-1$
		assertEquals(proxyTypeFactory.getBeanTypeProxy("java.lang.Integer"), arrayType.getComponentType()); //$NON-NLS-1$		
	}
	
	public void testPrimitive2DArrayType() {
		// Test two dimension primitive array
		IArrayBeanTypeProxy arrayType = (IArrayBeanTypeProxy) proxyTypeFactory.getBeanTypeProxy("[[I"); //$NON-NLS-1$
		assertNotNull(arrayType);
		assertTrue(arrayType.isArray());
		assertEquals("[[I", arrayType.getTypeName()); //$NON-NLS-1$
		assertEquals(proxyTypeFactory.getBeanTypeProxy("[I"), arrayType.getComponentType()); //$NON-NLS-1$
		
		// Test construction using accessor.
		arrayType = (IArrayBeanTypeProxy) proxyTypeFactory.getBeanTypeProxy("int", 2); //$NON-NLS-1$
		assertNotNull(arrayType);
		assertTrue(arrayType.isArray());
		assertEquals("[[I", arrayType.getTypeName()); //$NON-NLS-1$
	}
	
	public void testObject2DArrayType() {
		// Test two dimension object type array
		IArrayBeanTypeProxy arrayType = (IArrayBeanTypeProxy) proxyTypeFactory.getBeanTypeProxy("[[Ljava.lang.Integer;"); //$NON-NLS-1$
		assertNotNull(arrayType);
		assertTrue(arrayType.isArray());
		assertEquals("[[Ljava.lang.Integer;", arrayType.getTypeName()); //$NON-NLS-1$
		assertEquals(proxyTypeFactory.getBeanTypeProxy("[Ljava.lang.Integer;"), arrayType.getComponentType()); //$NON-NLS-1$
		
		// Test get type using accessor.
		arrayType = (IArrayBeanTypeProxy) proxyTypeFactory.getBeanTypeProxy("java.lang.Integer", 2); //$NON-NLS-1$
		assertNotNull(arrayType);
		assertTrue(arrayType.isArray());
		assertEquals("[[Ljava.lang.Integer;", arrayType.getTypeName()); //$NON-NLS-1$		
	}
	
	public void testArrayTypeFromArrayType() {
		// Test creating an array type from an array type, i.e. adding dimensions.
		IArrayBeanTypeProxy arrayType = (IArrayBeanTypeProxy) proxyTypeFactory.getBeanTypeProxy("[Ljava.lang.Integer;", 2); //$NON-NLS-1$
		assertNotNull(arrayType);
		assertTrue(arrayType.isArray());
		assertEquals("[[[Ljava.lang.Integer;", arrayType.getTypeName()); //$NON-NLS-1$
	}
	
	public void testArrayFromAccessorSimpleType() throws ThrowableProxy {
		IBeanTypeProxy integerType = proxyTypeFactory.getBeanTypeProxy("java.lang.Integer"); //$NON-NLS-1$				
		
		// Test creating an array with accessor of more than one dimension with component type not an array.
		IArrayBeanProxy arrayProxy = proxyFactory.createBeanProxyWith(integerType, new int[] {3, 4});
		assertNotNull(arrayProxy);
		assertEquals("[[Ljava.lang.Integer;", arrayProxy.getTypeProxy().getTypeName()); //$NON-NLS-1$
		assertEquals(3, arrayProxy.getLength());
		
		// get(0) should be an Integer[4].
		arrayProxy = (IArrayBeanProxy) arrayProxy.get(0);
		assertNotNull(arrayProxy);
		assertEquals(4, arrayProxy.getLength());				
	}
	
	public void testArrayFromAccessorArrayType() throws ThrowableProxy {
		IArrayBeanTypeProxy arrayType = (IArrayBeanTypeProxy) proxyTypeFactory.getBeanTypeProxy("java.lang.Integer", 1); //$NON-NLS-1$
		
		// Test creating an array with accessor but component type is an array.		
		IArrayBeanProxy arrayProxy = proxyFactory.createBeanProxyWith(arrayType, new int[] {1});
		assertNotNull(arrayProxy);
		assertEquals("[Ljava.lang.Integer;", arrayProxy.getTypeProxy().getTypeName()); //$NON-NLS-1$
		assertEquals(1, arrayProxy.getLength());
	}
	
	public void testArrayFromAccessorArrayTypeMultiDim() throws ThrowableProxy {
		IArrayBeanTypeProxy arrayType = (IArrayBeanTypeProxy) proxyTypeFactory.getBeanTypeProxy("java.lang.Integer", 1); //$NON-NLS-1$

		// Test creating an array with accessor but component type is an array, but extend and add a dimension.		
		IArrayBeanProxy arrayProxy = proxyFactory.createBeanProxyWith(arrayType, new int[] {2 ,3});
		assertNotNull(arrayProxy);
		assertEquals("[[Ljava.lang.Integer;", arrayProxy.getTypeProxy().getTypeName()); //$NON-NLS-1$
		assertEquals(2, arrayProxy.getLength());

		// Test first entry is an Integer[3]		
		IArrayBeanProxy idx1 = (IArrayBeanProxy) arrayProxy.get(0);
		assertNotNull(idx1);
		assertEquals(3, idx1.getLength());
		
		// Test [1][2] is null.
		IBeanProxy idx2 = arrayProxy.get(new int [] {1,2});
		assertNull(idx2);
	}
	
	public void testArraySet() throws ThrowableProxy {
		IBeanProxy anInt = proxyFactory.createBeanProxyWith(new java.lang.Integer(23));
		IArrayBeanTypeProxy arrayType = (IArrayBeanTypeProxy) proxyTypeFactory.getBeanTypeProxy("java.lang.Integer", 1); //$NON-NLS-1$
		
		IArrayBeanProxy arrayProxy = proxyFactory.createBeanProxyWith(arrayType, new int[] {2 ,3});
		assertNotNull(arrayProxy);
		assertEquals("[[Ljava.lang.Integer;", arrayProxy.getTypeProxy().getTypeName()); //$NON-NLS-1$
		assertEquals(2, arrayProxy.getLength());

		// Test first entry is an Integer[3]		
		IArrayBeanProxy idx1 = (IArrayBeanProxy) arrayProxy.get(0);
		
		// Test set into array idx1, but retrieve from arrayProxy. Tests
		//   1) Set with one index into array from outer array[0]
		//   2) Get with multi index from outer array
		//   3) And that the same array is set that exists within the first array.
		idx1.set(anInt, 2);
		IBeanProxy idx3 = arrayProxy.get(new int[] {0, 2});
		assertNotNull(idx3);
		assertEquals("java.lang.Integer", idx3.getTypeProxy().getTypeName()); //$NON-NLS-1$
		assertEquals(anInt, idx3);
		
		// Inverse test of above, multi set, single get of same array.
		arrayProxy.set(anInt, new int[] {0,1});
		assertEquals(anInt, idx1.get(1));
	}

	public void testArraySnapshot2DimArray() throws ThrowableProxy {
		IArrayBeanTypeProxy arrayType = (IArrayBeanTypeProxy) proxyTypeFactory.getBeanTypeProxy("java.lang.Integer", 2); //$NON-NLS-1$
		
		IArrayBeanProxy arrayProxy = proxyFactory.createBeanProxyWith(arrayType, new int[] {2, 3});
		assertNotNull(arrayProxy);

		// Get the two entries which are Integer[3]		
		IArrayBeanProxy idx0 = (IArrayBeanProxy) arrayProxy.get(0);
		IArrayBeanProxy idx1 = (IArrayBeanProxy) arrayProxy.get(1);
		
		// Now get the snapshot and see if the entries are idx0 and idx1.
		IBeanProxy[] snapshot = arrayProxy.getSnapshot();
		assertEquals(idx0, snapshot[0]);
		assertEquals(idx1, snapshot[1]);
	}

	public void testArraySnapshotPrimitiveArray() throws ThrowableProxy {
		IArrayBeanTypeProxy arrayType = (IArrayBeanTypeProxy) proxyTypeFactory.getBeanTypeProxy("int", 1); //$NON-NLS-1$
		
		IArrayBeanProxy arrayProxy = proxyFactory.createBeanProxyWith(arrayType, new int[] {2});
		assertNotNull(arrayProxy);

		// Set the two entries to int values.
		arrayProxy.set(proxyFactory.createBeanProxyWith(2), 0);
		arrayProxy.set(proxyFactory.createBeanProxyWith(3), 1);
		IIntegerBeanProxy idx0 = (IIntegerBeanProxy) arrayProxy.get(0);
		IIntegerBeanProxy idx1 = (IIntegerBeanProxy) arrayProxy.get(1);
		assertEquals(2, idx0.intValue());
		assertEquals(3, idx1.intValue());
		
		// Now get the snapshot and see if the entries are idx0 and idx1.
		IBeanProxy[] snapshot = arrayProxy.getSnapshot();
		assertEquals(idx0, snapshot[0]);
		assertEquals(idx1, snapshot[1]);
	}

	public void testEmptyArray() throws ThrowableProxy {
		IArrayBeanTypeProxy arrayType = (IArrayBeanTypeProxy) proxyTypeFactory.getBeanTypeProxy("java.lang.Integer", 1); //$NON-NLS-1$

		// Create an empty one dimensional array		
		IArrayBeanProxy arrayProxy = proxyFactory.createBeanProxyWith(arrayType, null);
		assertNotNull(arrayProxy);
		assertEquals("[Ljava.lang.Integer;", arrayProxy.getTypeProxy().getTypeName()); //$NON-NLS-1$
		assertEquals(0, arrayProxy.getLength());
	}
	
	public void testEmpty2DArray() throws ThrowableProxy {
		// Create an emtpy two dimensional array		
		IArrayBeanProxy arrayProxy = proxyFactory.createBeanProxyWith(proxyTypeFactory.getBeanTypeProxy("java.lang.Integer", 2), null); //$NON-NLS-1$
		assertNotNull(arrayProxy);
		assertEquals("[[Ljava.lang.Integer;", arrayProxy.getTypeProxy().getTypeName()); //$NON-NLS-1$
		assertEquals(0, arrayProxy.getLength());		
	}
	
	public void test2DArray() throws ThrowableProxy {
		// Create a 2D array with three empty entries in dim 0. 
		IArrayBeanProxy arrayProxy = proxyFactory.createBeanProxyWith(proxyTypeFactory.getBeanTypeProxy("java.lang.Integer", 2), 3); //$NON-NLS-1$
		assertNotNull(arrayProxy);
		assertEquals("[[Ljava.lang.Integer;", arrayProxy.getTypeProxy().getTypeName()); //$NON-NLS-1$
		assertEquals(3, arrayProxy.getLength());
		// Array entry should be empty.
		IArrayBeanProxy idx1 = (IArrayBeanProxy) arrayProxy.get(0);
		assertNull(idx1);		
	}
	
	public void testPrimitiveArray() throws ThrowableProxy {
		// Make sure that if the final component type is an
		// int (primitive) that we get a primitive proxy back and not an Integer object.		
		IArrayBeanTypeProxy arrayType = (IArrayBeanTypeProxy) proxyTypeFactory.getBeanTypeProxy("int", 1); //$NON-NLS-1$
		IArrayBeanProxy arrayProxy = proxyFactory.createBeanProxyWith(arrayType, 3);
		arrayProxy.set(proxyFactory.createBeanProxyWith(44), 1);
		IBeanProxy idx1 = arrayProxy.get(1);
		assertNotNull(idx1);
		assertEquals("int", idx1.getTypeProxy().getTypeName()); //$NON-NLS-1$
		assertEquals(44, ((IIntegerBeanProxy) idx1).intValue());
	}
	
	public void testCollections() throws ThrowableProxy {
		IBeanTypeProxy vectorType = proxyTypeFactory.getBeanTypeProxy("java.util.Vector"); //$NON-NLS-1$
		IBeanProxy vectorProxy = vectorType.newInstance();
		CollectionBeanProxyWrapper col = new CollectionBeanProxyWrapper(vectorProxy);
		
		// Test adding
		assertTrue(col.add(proxyFactory.createBeanProxyWith(33)));
		assertEquals(1, col.size());
			
		// Test toArray, first entry should be 33 and length should be 1.
		IArrayBeanProxy arrayOut = col.toArray();
		assertEquals(1, arrayOut.getLength());
		assertEquals(33, ((IIntegerBeanProxy) arrayOut.get(0)).intValue());
		
		// Test toArray(array).
		IArrayBeanProxy arrayInto = proxyFactory.createBeanProxyWith(arrayOut.getTypeProxy(), arrayOut.getLength()); //$NON-NLS-1$
		IArrayBeanProxy arrayOut2 = col.toArray(arrayInto);
		// It should of been the exact same array (arrayInto == arrayOut2 under the proxies).
		assertTrue(arrayInto.sameAs(arrayOut2));
		assertEquals(33, ((IIntegerBeanProxy) arrayOut.get(0)).intValue());
		
		// Test setting with wrong type throws exception.
		try {
			// Test the setting with wrong type throws an exception
			col = new CollectionBeanProxyWrapper(arrayOut);
			fail("ClassCastException should of been thrown.");
		} catch (ClassCastException e) {
			// If here, then the test was passed
		}
	}
	
	public void testIterator() throws ThrowableProxy {
		IBeanTypeProxy vectorType = proxyTypeFactory.getBeanTypeProxy("java.util.Vector"); //$NON-NLS-1$
		IBeanProxy vectorProxy = vectorType.newInstance();
		CollectionBeanProxyWrapper col = new CollectionBeanProxyWrapper(vectorProxy);
		col.add(proxyFactory.createBeanProxyWith(33));		
		
		// See if the iterator interface works.
		IteratorBeanProxyWrapper itrProxy = col.iterator();
		assertNotNull(itrProxy);
		int iterations = 0;
		while (itrProxy.hasNext()) {
			iterations++;
			assertTrue(iterations < 2);
			IBeanProxy itrValue = itrProxy.next();
			assertEquals(33, ((IIntegerBeanProxy) itrValue).intValue());
		}
	}
	
	public void testListInterface() throws ThrowableProxy {
		IBeanTypeProxy vectorType = proxyTypeFactory.getBeanTypeProxy("java.util.Vector"); //$NON-NLS-1$
		IBeanProxy vectorProxy = vectorType.newInstance();
		
		// See if the list inteface works.
		ListBeanProxyWrapper list = new ListBeanProxyWrapper(vectorProxy);
		assertTrue(list.add(proxyFactory.createBeanProxyWith(33)));	// First entry.
		list.add(0, proxyFactory.createBeanProxyWith(true));	// Now becomes first entry.
		assertEquals(2, list.size());
		assertEquals(true, ((IBooleanBeanProxy) list.get(0)).booleanValue());
		assertEquals(33, ((IIntegerBeanProxy) list.get(1)).intValue());	// Swapped to second entry due to add(0,...)		
	}
	
	public void testListIterator() throws ThrowableProxy {
		IBeanTypeProxy vectorType = proxyTypeFactory.getBeanTypeProxy("java.util.Vector"); //$NON-NLS-1$
		IBeanProxy vectorProxy = vectorType.newInstance();
		ListBeanProxyWrapper list = new ListBeanProxyWrapper(vectorProxy);
		list.add(proxyFactory.createBeanProxyWith(33));	// First entry.
		list.add(0, proxyFactory.createBeanProxyWith(true));	// Now becomes first entry.

		// See if the ListIterator interface works
		ListIteratorBeanProxyWrapper lItrProxy = list.listIterator();
		assertNotNull(lItrProxy);
		assertTrue(lItrProxy.hasNext());
		IBooleanBeanProxy bool1 = (IBooleanBeanProxy) lItrProxy.next();
		assertEquals(true, bool1.booleanValue());
		IIntegerBeanProxy int1 = (IIntegerBeanProxy) lItrProxy.next();
		assertEquals(33, int1.intValue());	// Old first entry moved to second entry by add(0,...) above.
		assertFalse(lItrProxy.hasNext());
		assertEquals(1, lItrProxy.previousIndex());
	}
	
	public void testMethodAccessors() throws ThrowableProxy {
		IBeanTypeProxy integerType = proxyTypeFactory.getBeanTypeProxy("java.lang.Integer"); //$NON-NLS-1$				
		
		// Test able to access beantype proxy and invoke methods on it. This isn't
		// the approved way of getting methods, but it tests that method proxies
		// are created correctly if returned from an invoke method.
		IBeanTypeProxy classTypeProxy = proxyTypeFactory.getBeanTypeProxy("java.lang.Class"); //$NON-NLS-1$
		IMethodProxy getMethodMethod = classTypeProxy.getMethodProxy("getMethod", new String[] {"java.lang.String", "[Ljava.lang.Class;"}); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
		// Get the Integer.byteValue() method through an invoke instead of a method factory or bean type.
		IBeanProxy method = getMethodMethod.invoke(integerType, new IBeanProxy[] {
			proxyFactory.createBeanProxyWith("byteValue"), null}); //$NON-NLS-1$
		assertNotNull(method);
		assertTrue(method instanceof IMethodProxy);
		
		// Now invoke it to see if correct answer comes back.
		IBeanProxy byteValue = ((IMethodProxy) method).invoke(proxyFactory.createBeanProxyWith(new Integer(254)));
		assertNotNull(byteValue);
		assertEquals("byte", byteValue.getTypeProxy().getTypeName()); //$NON-NLS-1$
		assertEquals((byte)254, ((INumberBeanProxy) byteValue).byteValue());
	}
	
	public void testInvokableAccessors() throws ThrowableProxy {
		IBeanTypeProxy integerType = proxyTypeFactory.getBeanTypeProxy("java.lang.Integer"); //$NON-NLS-1$				
		
		// Test able to access beantype proxy and invoke methods on it. This isn't
		// the approved way of getting methods, but it tests that method proxies
		// are created correctly if returned from an invoke method.
		IBeanTypeProxy classTypeProxy = proxyTypeFactory.getBeanTypeProxy("java.lang.Class"); //$NON-NLS-1$
		IInvokable getMethodInvokable = classTypeProxy.getInvokable("getMethod", new String[] {"java.lang.String", "[Ljava.lang.Class;"}); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
		// Get the Integer.byteValue() method through an invoke instead of a method factory or bean type.
		IBeanProxy method = getMethodInvokable.invoke(integerType, new IBeanProxy[] {
			proxyFactory.createBeanProxyWith("byteValue"), null}); //$NON-NLS-1$
		assertNotNull(method);
		assertTrue(method instanceof IMethodProxy);
		
		// Now invoke it to see if correct answer comes back.
		IBeanProxy byteValue = ((IMethodProxy) method).invoke(proxyFactory.createBeanProxyWith(new Integer(254)));
		assertNotNull(byteValue);
		assertEquals("byte", byteValue.getTypeProxy().getTypeName()); //$NON-NLS-1$
		assertEquals((byte)254, ((INumberBeanProxy) byteValue).byteValue());
	}	
	
	public void testCallback() throws ThrowableProxy {
		System.out.println("--- Starting the callback test ---"); //$NON-NLS-1$
		IBeanTypeProxy callbackType = proxyTypeFactory.getBeanTypeProxy("org.eclipse.jem.tests.proxy.vm.TestCallback"); //$NON-NLS-1$
		assertNotNull(callbackType);
		Object testObject = new Object();
		IBeanProxy callbackProxy = callbackType.newInstance();
		TestCallback cb = new TestCallback(testObject, registry);
		registry.getCallbackRegistry().registerCallback(callbackProxy, cb);
		IInvokable start = callbackType.getInvokable("start");	//$NON-NLS-1$
		IInvokable stop = callbackType.getInvokable("stop");	//$NON-NLS-1$
		synchronized(testObject) {
			start.invokeCatchThrowableExceptions(callbackProxy);
			try {
				testObject.wait(30000);	// Should be done by 30 seconds.
			} catch (InterruptedException e) {
			}
		}				
		stop.invokeCatchThrowableExceptions(callbackProxy);
		registry.getCallbackRegistry().deregisterCallback(callbackProxy);				
		cb.testCompleted();
		System.out.println("If there is anything in the .log file, then the test failed.");			 //$NON-NLS-1$		
	}
	
	public void testCallbackStream() throws ThrowableProxy, IOException {
		System.out.println("--- Starting the callback stream test ---"); //$NON-NLS-1$
		IBeanTypeProxy callbackType = proxyTypeFactory.getBeanTypeProxy("org.eclipse.jem.tests.proxy.vm.TestCallbackStream"); //$NON-NLS-1$
		assertNotNull(callbackType);
		Object testObject = new Object();
		IBeanProxy callbackProxy = callbackType.newInstance();
		TestCallbackStream cb = new TestCallbackStream(testObject);
		registry.getCallbackRegistry().registerCallback(callbackProxy, cb);
		IMethodProxy start = callbackType.getMethodProxy("start");							 //$NON-NLS-1$
		synchronized(testObject) {			
			start.invokeCatchThrowableExceptions(callbackProxy);
		try {
				testObject.wait(30000);	// Should be done by 30 seconds.
			} catch (InterruptedException e) {
			}	
		}		
		registry.getCallbackRegistry().deregisterCallback(callbackProxy);				
		cb.testComplete();
		System.out.println("If there is anything in the .log file, then the test failed.");			 //$NON-NLS-1$		
	}
	
	public void testSimpleGetField() throws ThrowableProxy {
		IBeanTypeProxy integerType = proxyTypeFactory.getBeanTypeProxy("java.lang.Integer"); //$NON-NLS-1$				
		
		// Get the public field.
		IFieldProxy field = integerType.getFieldProxy("MAX_VALUE"); //$NON-NLS-1$
		assertNotNull(field);
	}

	public void testSimpleGetDeclaredField() throws ThrowableProxy {
		IBeanTypeProxy integerType = proxyTypeFactory.getBeanTypeProxy("java.lang.Integer"); //$NON-NLS-1$				
		
		// Get the public field.
		IFieldProxy field = integerType.getDeclaredFieldProxy("value"); //$NON-NLS-1$
		assertNotNull(field);
	}

	public void testGetFields() {
		IBeanTypeProxy testAccessType = proxyTypeFactory.getBeanTypeProxy("testPackage.TestAccess"); //$NON-NLS-1$				
		
		// Get all fields.
		IFieldProxy[] fields = testAccessType.getFields();
		assertNotNull(fields);
		assertEquals(1, fields.length);		
	}

	public void testGetDeclaredFields() {
		IBeanTypeProxy testAccessType = proxyTypeFactory.getBeanTypeProxy("testPackage.TestAccess"); //$NON-NLS-1$				
		
		// Get all fields.
		IFieldProxy[] fields = testAccessType.getDeclaredFields();
		assertNotNull(fields);
		assertEquals(2, fields.length);		
	}
	
	public void testSimpleGetMethod() throws ThrowableProxy {
		IBeanTypeProxy testAccessType = proxyTypeFactory.getBeanTypeProxy("testPackage.TestAccess"); //$NON-NLS-1$	
		
		// Get the public field.
		IMethodProxy method = testAccessType.getMethodProxy("xyz"); //$NON-NLS-1$
		assertNotNull(method);
	}

	public void testSimpleGetDeclaredMethod() throws ThrowableProxy {
		IBeanTypeProxy testAccessType = proxyTypeFactory.getBeanTypeProxy("testPackage.TestAccess"); //$NON-NLS-1$	
		
		// Get the public field.
		IMethodProxy method = testAccessType.getDeclaredMethodProxy("qxr", (String[]) null); //$NON-NLS-1$
		assertNotNull(method);
	}

	public void testGetMethods() {
		IBeanTypeProxy testAccessType = proxyTypeFactory.getBeanTypeProxy("testPackage.TestAccess"); //$NON-NLS-1$
		IBeanTypeProxy testObjectType = proxyTypeFactory.getBeanTypeProxy("java.lang.Object"); //$NON-NLS-1$
		
		// Get all methods. Need to get all of Object too since getMethods() gets them all including inherited. We will
		// then take the diff to show what's only at the local level.
		IMethodProxy[] methods = testAccessType.getMethods();
		IMethodProxy[] objectMethods = testObjectType.getMethods();
		assertNotNull(methods);
		assertNotNull(objectMethods);
		assertEquals(6, methods.length-objectMethods.length);		
	}

	public void testGetDeclaredMethods() {
		IBeanTypeProxy testAccessType = proxyTypeFactory.getBeanTypeProxy("testPackage.TestAccess"); //$NON-NLS-1$				
		
		// Get all fields.
		IMethodProxy[] methods = testAccessType.getDeclaredMethods();
		assertNotNull(methods);
		assertEquals(7, methods.length);		
	}

	public void testFindCompatibleConstructor() throws AmbiguousMethodException, NoSuchMethodException {
		IBeanTypeProxy testAccessType = proxyTypeFactory.getBeanTypeProxy("testPackage.TestAccess"); //$NON-NLS-1$				

		IConstructorProxy ctor = testAccessType.getCompatibleConstructor(new IBeanTypeProxy[] {proxyTypeFactory.getBeanTypeProxy("java.lang.ArrayStoreException")});
		IConstructorProxy comp = testAccessType.getDeclaredConstructorProxy(new IBeanTypeProxy[] {proxyTypeFactory.getBeanTypeProxy("java.lang.RuntimeException")});
		
		assertNotNull(ctor);
		assertNotNull(comp);
		assertEquals(ctor, comp);
	}
	
	public void testFindCompatibleMethod() throws AmbiguousMethodException, NoSuchMethodException {
		IBeanTypeProxy testAccessType = proxyTypeFactory.getBeanTypeProxy("testPackage.TestAccess"); //$NON-NLS-1$				

		IMethodProxy method = testAccessType.getCompatibleMethod("xyz", new IBeanTypeProxy[] {proxyTypeFactory.getBeanTypeProxy("java.lang.Integer")});
		IMethodProxy comp = testAccessType.getDeclaredMethodProxy("xyz", new IBeanTypeProxy[] {proxyTypeFactory.getBeanTypeProxy("java.lang.Number")});
		
		assertNotNull(method);
		assertNotNull(comp);
		assertEquals(method, comp);
	}
	
	public void testFindAmbiguousMethod() throws NoSuchMethodException {
		IBeanTypeProxy testAccessType = proxyTypeFactory.getBeanTypeProxy("testPackage.TestAccess"); //$NON-NLS-1$				

		try {
			testAccessType.getCompatibleMethod("ddd", new IBeanTypeProxy[] {proxyTypeFactory.getBeanTypeProxy("java.lang.Integer"), proxyTypeFactory.getBeanTypeProxy("java.lang.Integer")});
			fail("Should of been ambiguous");
		} catch (AmbiguousMethodException e) {
		} 
	}
}
