// Path: gwt-sl/src/main/java/org/gwtwidgets/server/spring/ReflectionUtils.java
// public class ReflectionUtils {
// 
// 	/**
// 	 * Return array of all interfaces that are implemented by clazz and extend
// 	 * {@link RemoteService}.
// 	 * 
// 	 * @param clazz Class to scan for interfaces
// 	 * @return Array of interfaces. May be empty but never null.
// 	 */
// 	@SuppressWarnings("unchecked")
// 	public static Class<RemoteService>[] getExposedInterfaces(Class<?> clazz) {
// 		Set<Class<?>> interfaces = getInterfaces(clazz);
// 		for (Iterator<Class<?>> ite = interfaces.iterator(); ite.hasNext();) {
// 			Class<?> c = ite.next();
// 			if (!isExposed(c))
// 				ite.remove();
// 		}
// 		return interfaces.toArray(new Class[interfaces.size()]);
// 	}
// 
// 	/**
// 	 * Adds elements of an array to a set. The JRE 1.5 does include a similar
// 	 * method in the Collections class, but that breaks GWT-SL 1.4
// 	 * compatibility.
// 	 * 
// 	 * @param set Set of classes
// 	 * @param elements Elements in this array will be added to the set
// 	 */
// 	public static void addAll(Set<Class<?>> set, Class<?>[] elements) {
// 		for (Class<?> element : elements)
// 			set.add(element);
// 	}
// 
// 	/**
// 	 * Return all interfaces that are implemented by this class, traversing
// 	 * super classes and super interfaces.
// 	 * 
// 	 * @param c Class to scan
// 	 * @return Set of classes. May be empty but not null.
// 	 */
// 	public static Set<Class<?>> getInterfaces(Class<?> c) {
// 		Class<?> interfaces[] = c.getInterfaces();
// 		Set<Class<?>> classes = new HashSet<Class<?>>();
// 		if (interfaces == null)
// 			return classes;
// 		addAll(classes, interfaces);
// 		for (Class<?> cl : interfaces) {
// 			classes.addAll(getInterfaces(cl));
// 		}
// 		Class<?> superClass = c.getSuperclass();
// 		if (superClass != null) {
// 			classes.addAll(getInterfaces(superClass));
// 		}
// 		return classes;
// 	}
// 
// 	private static boolean isExposed(Class<?> c) {
// 		return RemoteService.class.isAssignableFrom(c);
// 	}
// 
// 	/**
// 	 * Will try to find method in 'serviceInterfaces' and if found, will attempt
// 	 * to return a method with the same signature from 'service', otherwise an
// 	 * exception is thrown. If 'serviceInterfaces' is a zero-sized array, the
// 	 * interface check is omitted and the method is looked up directly on the
// 	 * object.
// 	 * 
// 	 * @param target
// 	 *            Object to search method on
// 	 * @param serviceInterfaces
// 	 *            The requested method must exist on at least one of the
// 	 *            interfaces
// 	 * @param method Method to look for
// 	 * @return Method on 'service' or else a {@link NoSuchMethodException} is
// 	 *         thrown
// 	 * @throws NoSuchMethodException If method can't be found on target
// 	 */
// 	public static Method getRPCMethod(Object target, Class<?>[] serviceInterfaces, Method method) throws NoSuchMethodException {
// 		if (serviceInterfaces.length == 0)
// 			return target.getClass().getMethod(method.getName(), method.getParameterTypes());
// 		for (Class<?> serviceInterface : serviceInterfaces)
// 			try {
// 				Method template = serviceInterface.getMethod(method.getName(), method.getParameterTypes());
// 				return target.getClass().getMethod(template.getName(), template.getParameterTypes());
// 			} catch (NoSuchMethodException e) {
// 			}
// 		throw new NoSuchMethodException(method.toString());
// 	}
// 	
// 	/*
// 	 * This is from the AnnotationUtils class of the Springframework (2.5+) in
// 	 * the core packag. This code is licensed under the Apache v2 license.
// 	 */
// 	public static <A extends Annotation> A findAnnotation(Class<?> clazz,
// 			Class<A> annotationType) {
// 		A annotation = clazz.getAnnotation(annotationType);
// 		if (annotation != null) {
// 			return annotation;
// 		}
// 		for (Class<?> ifc : clazz.getInterfaces()) {
// 			annotation = findAnnotation(ifc, annotationType);
// 			if (annotation != null) {
// 				return annotation;
// 			}
// 		}
// 		Class<?> superClass = clazz.getSuperclass();
// 		if (superClass == null || superClass == Object.class) {
// 			return null;
// 		}
// 		return findAnnotation(superClass, annotationType);
// 	}
// 
// 
// }


import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import org.gwtwidgets.server.spring.ReflectionUtils;
import org.junit.Test;
import com.google.gwt.user.client.rpc.RemoteService;
import static org.junit.Assert.*
;/**
			System.out.println("I did something");
		}
	}

	public static class CGLibProxy implements MethodInterceptor {

		public static MyAbstractTestClass newInstance(final Class<?> clazz) {
			try {
				final Enhancer e = new Enhancer();
				e.setSuperclass(clazz);
				e.setCallback(new CGLibProxy());
				return (MyAbstractTestClass) e.create();
			} catch (Throwable e) {
				throw new RuntimeException(e.getMessage(), e);
			}
		}


		public Object intercept(Object target, Method method, Object[] arguments, MethodProxy proxy) throws Throwable {
			System.out.println("I intercepted something - " + method.getName());
			return method.invoke(target, arguments);
		}

	}

	@Test
	public void testGetInterfaces() {
		MyAbstractTestClass instance = CGLibProxy.newInstance(MyTestClass.class);
		assertTrue(instance instanceof RemoteService);

// Path: gwt-sl/src/main/java/org/gwtwidgets/server/spring/ReflectionUtils.java
// public class ReflectionUtils {
// 
// 	/**
// 	 * Return array of all interfaces that are implemented by clazz and extend
// 	 * {@link RemoteService}.
// 	 * 
// 	 * @param clazz Class to scan for interfaces
// 	 * @return Array of interfaces. May be empty but never null.
// 	 */
// 	@SuppressWarnings("unchecked")
// 	public static Class<RemoteService>[] getExposedInterfaces(Class<?> clazz) {
// 		Set<Class<?>> interfaces = getInterfaces(clazz);
// 		for (Iterator<Class<?>> ite = interfaces.iterator(); ite.hasNext();) {
// 			Class<?> c = ite.next();
// 			if (!isExposed(c))
// 				ite.remove();
// 		}
// 		return interfaces.toArray(new Class[interfaces.size()]);
// 	}
// 
// 	/**
// 	 * Adds elements of an array to a set. The JRE 1.5 does include a similar
// 	 * method in the Collections class, but that breaks GWT-SL 1.4
// 	 * compatibility.
// 	 * 
// 	 * @param set Set of classes
// 	 * @param elements Elements in this array will be added to the set
// 	 */
// 	public static void addAll(Set<Class<?>> set, Class<?>[] elements) {
// 		for (Class<?> element : elements)
// 			set.add(element);
// 	}
// 
// 	/**
// 	 * Return all interfaces that are implemented by this class, traversing
// 	 * super classes and super interfaces.
// 	 * 
// 	 * @param c Class to scan
// 	 * @return Set of classes. May be empty but not null.
// 	 */
// 	public static Set<Class<?>> getInterfaces(Class<?> c) {
// 		Class<?> interfaces[] = c.getInterfaces();
// 		Set<Class<?>> classes = new HashSet<Class<?>>();
// 		if (interfaces == null)
// 			return classes;
// 		addAll(classes, interfaces);
// 		for (Class<?> cl : interfaces) {
// 			classes.addAll(getInterfaces(cl));
// 		}
// 		Class<?> superClass = c.getSuperclass();
// 		if (superClass != null) {
// 			classes.addAll(getInterfaces(superClass));
// 		}
// 		return classes;
// 	}
// 
// 	private static boolean isExposed(Class<?> c) {
// 		return RemoteService.class.isAssignableFrom(c);
// 	}
// 
// 	/**
// 	 * Will try to find method in 'serviceInterfaces' and if found, will attempt
// 	 * to return a method with the same signature from 'service', otherwise an
// 	 * exception is thrown. If 'serviceInterfaces' is a zero-sized array, the
// 	 * interface check is omitted and the method is looked up directly on the
// 	 * object.
// 	 * 
// 	 * @param target
// 	 *            Object to search method on
// 	 * @param serviceInterfaces
// 	 *            The requested method must exist on at least one of the
// 	 *            interfaces
// 	 * @param method Method to look for
// 	 * @return Method on 'service' or else a {@link NoSuchMethodException} is
// 	 *         thrown
// 	 * @throws NoSuchMethodException If method can't be found on target
// 	 */
// 	public static Method getRPCMethod(Object target, Class<?>[] serviceInterfaces, Method method) throws NoSuchMethodException {
// 		if (serviceInterfaces.length == 0)
// 			return target.getClass().getMethod(method.getName(), method.getParameterTypes());
// 		for (Class<?> serviceInterface : serviceInterfaces)
// 			try {
// 				Method template = serviceInterface.getMethod(method.getName(), method.getParameterTypes());
// 				return target.getClass().getMethod(template.getName(), template.getParameterTypes());
// 			} catch (NoSuchMethodException e) {
// 			}
// 		throw new NoSuchMethodException(method.toString());
// 	}
// 	
// 	/*
// 	 * This is from the AnnotationUtils class of the Springframework (2.5+) in
// 	 * the core packag. This code is licensed under the Apache v2 license.
// 	 */
// 	public static <A extends Annotation> A findAnnotation(Class<?> clazz,
// 			Class<A> annotationType) {
// 		A annotation = clazz.getAnnotation(annotationType);
// 		if (annotation != null) {
// 			return annotation;
// 		}
// 		for (Class<?> ifc : clazz.getInterfaces()) {
// 			annotation = findAnnotation(ifc, annotationType);
// 			if (annotation != null) {
// 				return annotation;
// 			}
// 		}
// 		Class<?> superClass = clazz.getSuperclass();
// 		if (superClass == null || superClass == Object.class) {
// 			return null;
// 		}
// 		return findAnnotation(superClass, annotationType);
// 	}
// 
// 
// }


// Path: test-webapp/src/test/java/org/gwtwidgets/server/spring/test/ReflectionUtilsTest.java
import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import org.gwtwidgets.server.spring.ReflectionUtils;
import org.junit.Test;
import com.google.gwt.user.client.rpc.RemoteService;
import static org.junit.Assert.*
;/**

			System.out.println("I did something");
		}
	}

	public static class CGLibProxy implements MethodInterceptor {

		public static MyAbstractTestClass newInstance(final Class<?> clazz) {
			try {
				final Enhancer e = new Enhancer();
				e.setSuperclass(clazz);
				e.setCallback(new CGLibProxy());
				return (MyAbstractTestClass) e.create();
			} catch (Throwable e) {
				throw new RuntimeException(e.getMessage(), e);
			}
		}


		public Object intercept(Object target, Method method, Object[] arguments, MethodProxy proxy) throws Throwable {
			System.out.println("I intercepted something - " + method.getName());
			return method.invoke(target, arguments);
		}

	}

	@Test
	public void testGetInterfaces() {
		MyAbstractTestClass instance = CGLibProxy.newInstance(MyTestClass.class);
		assertTrue(instance instanceof RemoteService);

		assertTrue(ReflectionUtils.getExposedInterfaces(instance.getClass()).length == 1);