private static void introspectSpreadsheetDateClass() {

		Object o = new SpreadsheetDate(30, 6, 2012); // Some unknown object to investigate
		Class<? extends Object> c = o.getClass(); // Get its type
		System.out.println("\n\nIntrospect: " + c.getName());

		// If it is an array, figure out its base type
		while (c.isArray())
			c = c.getComponentType();

		// If c is not a primitive type, print its class hierarchy
		if (!c.isPrimitive()) {
			for (Class<? extends Object> s = c; s != null; s = s.getSuperclass())
				System.out.println(s.getName() + " extends");
		}

		// Try to create a new instance of c; this requires a no-arg constructor
		Object newobj = new SpreadsheetDate(30, 6, 2011);
		try {
			newobj = c.newInstance();
		} catch (Exception e) {
			// Handle InstantiationException, IllegalAccessException
		}

		// See if the class has a method named setText that takes a single String
		// If so, call it with a string argument
		try {
			Method m = c.getMethod("setText", new Class[] { String.class });
			m.invoke(newobj, new Object[] { "My Label" });
			System.out.println("FOUND METHOD: " + m.getName());
		} catch (Exception e) { /* Handle exceptions here */
			e.printStackTrace();
		}

		try {
			Method m = c.getMethod("setDescription", new Class[] { String.class });
			m.invoke(newobj, new Object[] { "My Description" });
			System.out.println("FOUND METHOD: " + m.getName());
		} catch (Exception e) { /* Handle exceptions here */
			e.printStackTrace();
		}

		// These are varargs methods in Java 5.0 so the syntax is much cleaner.
		try {
			Method m = c.getMethod("isInRange", c.getSuperclass(), c.getSuperclass());
			m.invoke(newobj, o, o);
			System.out.println("FOUND METHOD: " + m.getName());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}