private static void write(ContextFactory factory, SourceFile file) {
   try {
     RuntimeModel model = factory.create(file.getInputPath()).getModel();
     String source = generator.generate(file, model);
     Files.createDirectories(file.getOutputPath().getParent());
     Files.write(
         file.getOutputPath(),
         source.getBytes(Charset.forName("UTF-8")),
         StandardOpenOption.CREATE,
         StandardOpenOption.TRUNCATE_EXISTING);
   } catch (Throwable t) {
     throw new CodeGeneratorException(t);
   }
 }
 private CompilationUnit getCompilationUnit(SourceFile sourceFile) {
   CompilationUnit compilationUnit;
   if (Files.exists(sourceFile.getOutputPath())) {
     try {
       compilationUnit = JavaParser.parse(sourceFile.getOutputPath().toFile());
     } catch (Throwable t) {
       throw new RuntimeException(t);
     }
   } else {
     compilationUnit = new CompilationUnit();
     compilationUnit.setComment(
         new LineComment(" Generated by GraphWalker (http://www.graphwalker.org)"));
     if (!"".equals(sourceFile.getPackageName())) {
       compilationUnit.setPackage(createPackageDeclaration(sourceFile));
     }
     compilationUnit.setImports(
         Arrays.asList(
             new ImportDeclaration(
                 new NameExpr("org.graphwalker.java.annotation.Model"), false, false),
             new ImportDeclaration(
                 new NameExpr("org.graphwalker.java.annotation.Vertex"), false, false),
             new ImportDeclaration(
                 new NameExpr("org.graphwalker.java.annotation.Edge"), false, false)));
     ASTHelper.addTypeDeclaration(compilationUnit, getInterfaceName(sourceFile));
   }
   return compilationUnit;
 }
  public static void generate(final Path input, final Path output) {
    final SimpleCache cache = new SimpleCache(output);
    try {
      Files.walkFileTree(
          input,
          new SimpleFileVisitor<Path>() {
            @Override
            public FileVisitResult visitFile(Path file, BasicFileAttributes attributes)
                throws IOException {
              if (!cache.contains(file) || isModified(file)) {
                try {
                  SourceFile sourceFile = new SourceFile(file, input, output);
                  ContextFactory factory = ContextFactoryScanner.get(sourceFile.getInputPath());
                  write(factory, sourceFile);
                  cache.add(file, new CacheEntry(file.toFile().lastModified(), true));
                } catch (Throwable t) {
                  cache.add(file, new CacheEntry(file.toFile().lastModified(), false));
                }
              }
              return FileVisitResult.CONTINUE;
            }

            private boolean isModified(Path file) throws IOException {
              return !Files.getLastModifiedTime(file).equals(cache.get(file).getLastModifiedTime());
            }

            @Override
            public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
              cache.add(file, new CacheEntry(file.toFile().lastModified(), false));
              return FileVisitResult.CONTINUE;
            }
          });
    } catch (IOException e) {
      throw new CodeGeneratorException(e);
    }
  }