@Test
  public void generatePlantUmlClassDiagram() throws IOException {
    JavaProjectBuilder javaProjectBuilder = new JavaProjectBuilder();
    javaProjectBuilder.addSourceTree(new File("./src/main/java"));

    StringBuilder stringBuilder = new StringBuilder();

    for (JavaClass javaClass : javaProjectBuilder.getClasses()) {
      if (shouldIgnore(javaClass)) {
        continue;
      }

      String classType;
      if (javaClass.isInterface()) {
        classType = "interface";
      } else if (javaClass.isAbstract()) {
        classType = "abstract class";
      } else {
        classType = "class";
      }

      stringBuilder.append(String.format("%s %s", classType, javaClass.getFullyQualifiedName()));

      // extends
      JavaClass superClass = javaClass.getSuperJavaClass();
      if (superClass != null) {
        if (!shouldIgnore(superClass)) {
          stringBuilder.append(String.format(" extends %s", superClass.getFullyQualifiedName()));
        }
      }

      // implements
      List<JavaClass> interfaces = javaClass.getInterfaces();
      if (!interfaces.isEmpty()) {
        List<String> interfaceNames =
            interfaces
                .stream()
                .filter(i -> !shouldIgnore(i))
                .map(i -> i.getFullyQualifiedName())
                .collect(Collectors.toList());
        String implementsString = " implements " + String.join(", ", interfaceNames);
        stringBuilder.append(implementsString);
      }

      stringBuilder.append("\n");
    }

    for (JavaClass javaClass : javaProjectBuilder.getClasses()) {
      if (shouldIgnore(javaClass)) {
        continue;
      }

      // delegation
      List<JavaField> fields = javaClass.getFields();
      for (JavaField field : fields) {
        if (shouldIgnore(field.getType())) {
          continue;
        }

        stringBuilder.append(
            String.format(
                "%s -> %s: delegates\n",
                javaClass.getFullyQualifiedName(), field.getType().getFullyQualifiedName()));
      }
    }

    documentation.text("classDiagram", stringBuilder.toString());
  }
  public void processSources(
      File[] sourceDirectories,
      File outputFile,
      boolean containerDescriptor,
      ComponentDescriptor[] roleDefaults)
      throws ComponentDescriptorCreatorException {
    // ----------------------------------------------------------------------
    // Check and register all directories to scan
    // ----------------------------------------------------------------------

    JavaSource[] javaSources;

    JavaDocBuilder builder = new JavaDocBuilder();

    getLogger().debug("Source directories: ");

    for (int it = 0; it < sourceDirectories.length; it++) {
      File sourceDirectory = sourceDirectories[it];

      if (!sourceDirectory.isDirectory()) {
        getLogger()
            .debug(
                "Specified source directory isn't a directory: "
                    + "'"
                    + sourceDirectory.getAbsolutePath()
                    + "'.");
      }

      getLogger().debug(" - " + sourceDirectory.getAbsolutePath());

      builder.addSourceTree(sourceDirectory);
    }

    // ----------------------------------------------------------------------
    // Scan the sources
    // ----------------------------------------------------------------------

    javaSources = builder.getSources();

    Map defaultsByRole = new HashMap();
    if (roleDefaults != null) {
      for (int i = 0; i < roleDefaults.length; i++) {
        // TODO: fail if role is null
        defaultsByRole.put(roleDefaults[i].getRole(), roleDefaults[i]);
      }
    }

    List componentDescriptors = new ArrayList();

    for (int i = 0; i < javaSources.length; i++) {
      JavaClass javaClass = getJavaClass(javaSources[i]);

      ComponentDescriptor componentDescriptor = gleaner.glean(builder, javaClass);

      if (componentDescriptor != null && !javaClass.isAbstract()) {
        // TODO: better merge, perhaps pass it into glean as the starting point instead
        if (defaultsByRole.containsKey(componentDescriptor.getRole())) {
          ComponentDescriptor desc =
              (ComponentDescriptor) defaultsByRole.get(componentDescriptor.getRole());

          if (componentDescriptor.getInstantiationStrategy() == null) {
            componentDescriptor.setInstantiationStrategy(desc.getInstantiationStrategy());
          }
        }
        componentDescriptors.add(componentDescriptor);
      }
    }

    ComponentSetDescriptor componentSetDescriptor = new ComponentSetDescriptor();

    componentSetDescriptor.setComponents(componentDescriptors);

    // ----------------------------------------------------------------------
    // Convert the Maven dependencies to Plexus component dependencies
    // ----------------------------------------------------------------------

    //        List componentDependencies = convertDependencies( mavenProject.getDependencies() );
    //
    //        componentSetDescriptor.setDependencies( componentDependencies );

    // TODO: for now
    componentSetDescriptor.setDependencies(Collections.EMPTY_LIST);

    // ----------------------------------------------------------------------
    //
    // ----------------------------------------------------------------------

    validateConfiguration(componentSetDescriptor);

    // ----------------------------------------------------------------------
    // Write out the component descriptor
    // ----------------------------------------------------------------------

    if (componentDescriptors.size() == 0 && componentSetDescriptor.getDependencies().size() == 0) {
      getLogger().debug("No components or dependencies found, not writing components.xml");

      return;
    }

    File parentFile = outputFile.getParentFile();
    if (!parentFile.exists()) {
      if (!parentFile.mkdirs()) {
        throw new ComponentDescriptorCreatorException(
            "Could not make parent directory: '" + parentFile.getAbsolutePath() + "'.");
      }
    }

    try {
      FileWriter writer = new FileWriter(outputFile);

      XMLWriter w = new PrettyPrintXMLWriter(writer);

      w.startElement(containerDescriptor ? "plexus" : "component-set");

      writeComponents(w, componentDescriptors);

      writeDependencies(w, componentSetDescriptor);

      w.endElement();

      writer.write(LS);

      writer.close();
    } catch (PlexusConfigurationException e) {
      throw new ComponentDescriptorCreatorException(
          "Internal error while writing out the configuration", e);
    } catch (IOException e) {
      throw new ComponentDescriptorCreatorException(
          "Error while writing the component descriptor to: "
              + "'"
              + outputFile.getAbsolutePath()
              + "'.",
          e);
    }
  }