/** Executes the mojo. */
  public void execute() throws MojoExecutionException, MojoFailureException {
    try {
      Set<File> thriftFiles = findThriftFiles();

      final File outputDirectory = getOutputDirectory();
      ImmutableSet<File> outputFiles = findGeneratedFilesInDirectory(getOutputDirectory());

      Set<String> compileRoots = new HashSet<String>();
      compileRoots.add("scrooge");

      if (thriftFiles.isEmpty()) {
        getLog().info("No thrift files to compile.");
      } else if (checkStaleness
          && ((lastModified(thriftFiles) + staleMillis) < lastModified(outputFiles))) {
        getLog().info("Generated thrift files up to date, skipping compile.");
        attachFiles(compileRoots);
      } else {
        outputDirectory.mkdirs();

        // Quick fix to fix issues with two mvn installs in a row (ie no clean)
        cleanDirectory(outputDirectory);

        getLog().info(format("compiling thrift files %s with Scrooge", thriftFiles));
        synchronized (lock) {
          ScroogeRunner runner = new ScroogeRunner();
          Map<String, String> thriftNamespaceMap = new HashMap<String, String>();
          for (ThriftNamespaceMapping mapping : thriftNamespaceMappings) {
            thriftNamespaceMap.put(mapping.getFrom(), mapping.getTo());
          }

          // Include thrifts from resource as well.
          Set<File> includes = thriftIncludes;
          includes.add(getResourcesOutputDirectory());

          runner.compile(
              getLog(),
              new File(outputDirectory, "scrooge"),
              thriftFiles,
              includes,
              thriftNamespaceMap,
              language,
              thriftOpts);
        }
        attachFiles(compileRoots);
      }
    } catch (IOException e) {
      throw new MojoExecutionException("An IO error occured", e);
    }
  }
  /** Iterate through dependencies, find those specified in the whitelist */
  private Set<Artifact> findThriftDependencies(Set<String> whitelist) throws IOException {
    Set<Artifact> thriftDependencies = new HashSet<Artifact>();

    Set<Artifact> deps = new HashSet<Artifact>();
    deps.addAll(project.getArtifacts());
    deps.addAll(project.getDependencyArtifacts());

    Map<String, Artifact> depsMap = new HashMap<String, Artifact>();
    for (Artifact dep : deps) {
      depsMap.put(dep.getId(), dep);
    }

    for (Artifact artifact : deps) {
      // This artifact is on the whitelist directly.
      if (whitelist.contains(artifact.getArtifactId())) {
        thriftDependencies.add(artifact);

        // Check if this artifact is being pulled in by an idl jar that's been whitelisted
      } else {
        List<String> depTrail = artifact.getDependencyTrail();
        // depTrail can be null sometimes, which seems like a maven bug
        if (depTrail != null) {
          for (String name : depTrail) {
            Artifact dep = depsMap.get(name);
            if (dep != null
                && "idl".equals(dep.getClassifier())
                && whitelist.contains(dep.getArtifactId())) {
              thriftDependencies.add(artifact);
              break;
            }
          }
        }
      }
    }
    return thriftDependencies;
  }