public class TypeDesc {
    public static void main(String[] args) {
	TypeDesc desc = new TypeDesc();
	for (int i = 0; i < args.length; i++) {
	    try {
		desc.printType(Class.forName(args[i]), 0);
	    } catch (ClassNotFoundException e) {
		System.out.println(e);	// report the error
	    }
	}
    }

    // by default print on standard output
    public java.io.PrintStream out = System.out;

    // used in printType) for labeling type named
    private static String[]
	basic    = { "class",    "interface"  },
	extended = { "extends",  "implements" };

    private static Class objectClass;
    static {			// cache ref to Class for java.lang.Object
	try {
	    objectClass = Class.forName("java.lang.Object");
	} catch (ClassNotFoundException impossible) {
	}
    }

    public void printType(Class type, int depth) {
	// print out this type
	for (int i = 0; i < depth; i++)
	    out.print("  ");
	String[] labels = (depth == 0 ? basic : extended);
	out.print(labels[type.isInterface() ? 1 : 0] + " ");
	out.println(type.getName());

	// print out any interfaces this class implements
	Class[] interfaces = type.getInterfaces();
	for (int i = 0; i < interfaces.length; i++)
	    printType(interfaces[i], depth + 1);

	// recurse on the superclass
	Class superType = type.getSuperclass();
	if (superType != null && superType != objectClass)
	    printType(superType, depth + 1);
    }
}
