private static void printClass(Class<?> aClass, Map<Class<?>, Collection<Class<?>>> classes, StringBuilder sb) {
    final boolean isInterface = aClass.isInterface();
    sb.append(isInterface ? "interface ": "class ");
    dumpType(aClass, aClass, sb, classes);
    final Type superClass = aClass.getGenericSuperclass();
    final Class<?> rawSuperClass = (Class<?>)(superClass instanceof ParameterizedType ? ((ParameterizedType)superClass).getRawType() : superClass);
    if (superClass != null && classes.containsKey(rawSuperClass)) {
      sb.append(" extends ");
      dumpType(null, superClass, sb, classes);
    }
    int implementsIdx = 1;
    for (Type superInterface : aClass.getGenericInterfaces()) {
      final Class<?> rawSuperInterface = (Class<?>)(superInterface instanceof ParameterizedType ? ((ParameterizedType)superInterface).getRawType() : superInterface);
      if (classes.containsKey(rawSuperInterface)) {
        if (implementsIdx++ == 1) sb.append(isInterface? " extends " : " implements ");
        else sb.append(", ");
        dumpType(null, superInterface, sb, classes);
      }
    }
    sb.append(" {\n");
    for (Method method : aClass.getDeclaredMethods()) {
      if (Modifier.isStatic(method.getModifiers()) ||
          !Modifier.isPublic(method.getModifiers()) ||
          Modifier.isVolatile(method.getModifiers())) continue;
      printMethodDeclaration(method, sb.append("  "), classes);
    }
    Collection<Class<?>> innerClasses = classes.get(aClass);
    sb.append("}\n");
    if (innerClasses != null) {
      for (Class<?> innerClass : innerClasses) {
        printClass(innerClass, classes, sb);
      }
    }
  }
private static void printClass(Class<?> aClass, Map<Class<?>, Collection<Class<?>>> classes, StringBuilder sb)