code: package com.quui.tm2.doc;
  
  import java.io.File;
  import java.io.FileWriter;
  import java.io.IOException;
  import java.lang.reflect.InvocationTargetException;
  import java.net.MalformedURLException;
  import java.net.URISyntaxException;
  import java.net.URL;
  import java.util.ArrayList;
  import java.util.HashSet;
  import java.util.List;
  import java.util.Set;
  
  import com.quui.tm2.Agent;
  import com.quui.tm2.Analysis;
  import com.quui.tm2.Annotation;
  import com.quui.tm2.AnnotationReader;
  import com.quui.tm2.Experiment;
  import com.quui.tm2.util.DotDrawer;
  import com.quui.tm2.util.FileIO;
  import com.quui.tm2.util.Preferences;
  import com.quui.tm2.util.Preferences.Environment;
  
  /**
   * @author Fabian Steeg (fsteeg)
   */
  public final class ExportHelper {
      private static final String JAVA = ".java";
  
      private ExportHelper() {}
  
      private static final String DOT_DIR = Preferences.get(Environment.DOT_HOME);
      private static final String RENDER = Preferences.get(Environment.DOT_FORMAT);
      private static final String DOT = ".dot";
      private static final String VISUAL = "-visual";
  
      /**
       * @param metadata The attributes for rendering
       * @param experiment The experiment to render
       */
      public static void renderDot(final ExperimentInfo metadata, final Experiment experiment) {
          String outDot = experiment.getOutputRootName() + VISUAL + DOT;
          ExperimentDotTemplate dt = new ExperimentDotTemplate();
          String generatedDot = dt.generate(metadata);
          try {
              save(generatedDot, outDot);
              DotDrawer dd = new DotDrawer("", "", outDot, experiment.getOutputRootName() + VISUAL + "." + RENDER,
                      DOT_DIR);
              dd.renderImage(RENDER);
          } catch (InvocationTargetException e) {
              e.printStackTrace();
          } catch (InterruptedException e) {
              e.printStackTrace();
          } catch (IOException e) {
              e.printStackTrace();
          }
      }
  
      /**
       * @param x The experiment
       * @return The attributes to use when passing into {@link #renderDot(ExperimentInfo, Experiment)}
       */
      static ExperimentInfo createMetadata(final Experiment x) {
          ExperimentInfo experimentInfo = new ExperimentInfo();
          experimentInfo.corpusLocation = x.getCorpusLocation();
          experimentInfo.title = x.getTitle();
          experimentInfo.trains = x.syntheses();
          experimentInfo.resultAnnotationsLocation = x.getOutputAnnotationLocation();
          experimentInfo.evalAgent =(x.getEvaluation() != null ? x.getEvaluation().getClass().getSimpleName(): "No eval available");
          Class evalAgentClass = (x.getEvaluation() != null ? x.getEvaluation().getClass(): null);
          experimentInfo.evalResult = 
  				(x.getEvaluation() != null ? x.getEvaluation().getResultString() : "No eval available")
  				+ ";"
  				+ (x.getGoldStandard() != null ? x.getGoldStandard() : "No gold available");
          List<String> sources = new ArrayList<String>();
          String src = Preferences.get(Environment.SOURCES);
          String outputLocation = x.getOutputRootName();
          List<String> files = new ArrayList<String>();
          Set<Agent<?, ?>> agents = agentsInvolved(x.interactions());
          Set<AgentInfo> agentInfos = new HashSet<AgentInfo>();
          for (Agent<?, ?> agent : agents) {
              String a = agent.getClass().getName();
              String sourceFile = (src + a.replaceAll("\\.", "/")) + JAVA;
              String source = "No source available";
              try {
                  if (new File(new URL(sourceFile).toURI()).exists()) {
                      source = FileIO.read(sourceFile);
                  }
                  sources.add(sourceFile);
                  String name = agent.getClass().getName();
                  System.out.println(name);
                  try {
  					name = agent.getClass().getSimpleName();
  				} catch (Exception e) {
  					e.printStackTrace();
  				}
                  AgentInfo agentInfo = new AgentInfo(name, agent.toString(), source);
                  agentInfos.add(agentInfo);
                  files.add(draw(outputLocation + "/", agentInfo));
              } catch (MalformedURLException e) {
                  e.printStackTrace();
              } catch (URISyntaxException e) {
                  e.printStackTrace();
              }
          }
          files.add(0, outputLocation + VISUAL + "." + RENDER);
          experimentInfo.agentSources = sources;
          List<Analysis<?>> interactions = new ArrayList<Analysis<?>>();
          interactions.addAll(x.interactions());
          experimentInfo.flows = interactions;
          experimentInfo.agentNames = new ArrayList<AgentInfo>(agentInfos);
          String outputAnnotationLocation = x.getOutputAnnotationLocation();
          AnnotationReader reader = new AnnotationReader(outputAnnotationLocation);
          if (evalAgentClass != null) {
            List<Annotation<String>> annotations = reader.readAnnotations(evalAgentClass);
            if (annotations != null && annotations.size() > 0) {
              experimentInfo.evalResult = annotations.get(0).getValue();
            }
          }
          experimentInfo.referencedFiles = files;
          experimentInfo.took = x.getTime();
          return experimentInfo;
      }
  
      private static String configString(Agent<?, ?> agent) {
          return String.format("configuration: %s", agent.toString());
      }
  
      /**
       * @param agentInfo The agent info to draw with dot
       * @return The location of the viewable file generated with dot
       * @throws InterruptedException
       * @throws InvocationTargetException
       */
      private static String draw(String location, AgentInfo agent) {
          String dotText = new AgentDotTemplate().generate(agent);
          String dotLocation = location + agent.name + ".dot";
          File parent;
          String resultLocation = null;
          try {
              parent = new File(new URL(location).toURI());
              if (!parent.exists()) {
                  boolean mkdir = parent.mkdir();
                  if (!mkdir) {
                      throw new IllegalStateException("Could not create: " + parent);
                  }
              }
              FileWriter w = new FileWriter(new File(new URL(dotLocation).toURI()));
              w.write(dotText);
              w.close();
  
              resultLocation = location + agent.name + "." + RENDER;
              DotDrawer dd = new DotDrawer("", "", dotLocation, resultLocation, DOT_DIR);
              dd.renderImage(RENDER);
          } catch (MalformedURLException e1) {
              e1.printStackTrace();
          } catch (URISyntaxException e1) {
              e1.printStackTrace();
          } catch (IOException e) {
              e.printStackTrace();
          } catch (InvocationTargetException e) {
              e.printStackTrace();
          } catch (InterruptedException e) {
              e.printStackTrace();
          }
          return resultLocation;
      }
  
      private static Set<Agent<?, ?>> agentsInvolved(List<Analysis<?>> interactions) {
          Set<Class<? extends Agent<?, ?>>> set = new HashSet<Class<? extends Agent<?, ?>>>();
          Set<Agent<?, ?>> set2 = new HashSet<Agent<?, ?>>();
          for (Analysis<?> interaction : interactions) {
              for (Agent<?, ?> agent : interaction.sources()) {
                  Class<? extends Agent<?, ?>> c = (Class<? extends Agent<?, ?>>) agent.getClass();
                  if (!set.contains(c)) {
                      set2.add(agent);
                  }
                  set.add(c);
              }
              for (Agent<?, ?> agent : interaction.targets()) {
                  Class<? extends Agent<?, ?>> c = (Class<? extends Agent<?, ?>>) agent.getClass();
                  if (!set.contains(c)) {
                      set2.add(agent);
                  }
                  set.add(c);
              }
          }
          return set2;
      }
  
      private static void save(String content, String location) throws IOException {
          FileWriter fw;
          try {
              fw = new FileWriter(new File(new URL(location).toURI()));
              fw.write(content);
              fw.close();
          } catch (URISyntaxException e) {
              e.printStackTrace();
          }
      }
  }
  