private List<EmbedFontInfo> locateEmbedFontInfos() {
    List<EmbedFontInfo> infoList = new ArrayList<EmbedFontInfo>();
    if (componentRegistry.getEnvironment().getFontDirectories() != null) {
      FontCache fontCache =
          componentRegistry.getConfiguration().isUseFopFontCacheEnabled()
              ? FontCache.loadFrom(new File(getFopWorkDirectory(), FONT_CACHE_FILE))
              : new FontCache();
      FontResolver fontResolver = FontSetup.createMinimalFontResolver();
      FontInfoFinder fontInfoFinder = new FontInfoFinder();
      fontInfoFinder.setEventListener(
          new FontEventListener() {
            public void fontSubstituted(
                Object source, FontTriplet requested, FontTriplet effective) {
              log.info(
                  "FOP font substitution : "
                      + requested
                      + " -> "
                      + effective
                      + "; source="
                      + source);
            }

            public void fontLoadingErrorAtAutoDetection(
                Object source, String fontURL, Exception e) {
              log.info("FOP autodetect font loading error : " + fontURL + "; source=" + source, e);
            }

            public void glyphNotAvailable(Object source, char ch, String fontName) {
              log.trace(
                  "Glyph not available for character ["
                      + ch
                      + "] in font "
                      + fontName
                      + "; source="
                      + source);
            }
          });
      for (File fontDirectory : componentRegistry.getEnvironment().getFontDirectories()) {
        for (File fontFile : fontDirectory.listFiles()) {
          EmbedFontInfo[] infos = fontInfoFinder.find(toURL(fontFile), fontResolver, fontCache);
          if (infos == null || infos.length == 0) {
            continue;
          }
          for (EmbedFontInfo info : infos) {
            if (info.getEmbedFile() != null) {
              infoList.add(info);
            }
          }
        }
      }
    }

    return infoList;
  }
  @SuppressWarnings({"unchecked"})
  private DefaultConfiguration buildFontsConfig() {
    DefaultConfiguration fontsConfig = new DefaultConfiguration("fonts");

    // did not work for me :(
    //			if ( environment.getFontDirectories() != null ) {
    //				for ( File fontDirectory : environment.getFontDirectories() ) {
    //					DefaultConfiguration fontDirectoryElement = new DefaultConfiguration( "directory" );
    //					fontDirectoryElement.setValue( fontDirectory.getAbsolutePath() );
    //					fontsConfig.addChild( fontDirectoryElement );
    //				}
    //			}

    // this code is mostly copied from
    // http://dev.plutext.org/trac/docx4j/browser/trunk/docx4j/src/main/java/org/docx4j/convert/out/pdf/viaXSLFO/Conversion.java
    //
    // Thanks to Jason Harrop from the fop-user list (and who wrote that code) for pointing it out
    for (EmbedFontInfo embedFontInfo : locateEmbedFontInfos()) {
      DefaultConfiguration fontConfig = new DefaultConfiguration("font");
      fontsConfig.addChild(fontConfig);
      fontConfig.setAttribute("embed-url", embedFontInfo.getEmbedFile());
      if (embedFontInfo.getSubFontName() != null) {
        fontConfig.setAttribute("sub-font", embedFontInfo.getSubFontName());
      }

      FontTriplet triplet = (FontTriplet) embedFontInfo.getFontTriplets().get(0);

      fontConfig.addChild(
          generateFontTripletConfig(triplet.getName(), triplet.getStyle(), triplet.getWeight()));
      fontConfig.addChild(generateFontTripletConfig(triplet.getName(), "normal", "bold"));
      fontConfig.addChild(generateFontTripletConfig(triplet.getName(), "italic", "bold"));
      fontConfig.addChild(generateFontTripletConfig(triplet.getName(), "italic", "normal"));
    }

    if (componentRegistry.getConfiguration().isAutoDetectFontsEnabled()) {
      DefaultConfiguration autoDetect = new DefaultConfiguration("auto-detect");
      fontsConfig.addChild(autoDetect);
    }

    return fontsConfig;
  }