@Override
 public boolean isAffected(Delta delta, IResourceDescription candidate)
     throws IllegalArgumentException {
   if (!hasChanges(delta, candidate)) return false;
   Set<QualifiedName> names = Sets.newHashSet();
   addExportedNames(names, delta.getOld());
   addExportedNames(names, delta.getNew());
   return !Collections.disjoint(names, getImportedNames(candidate));
 }
  @Override
  public void build(IBuildContext context, IProgressMonitor monitor) throws CoreException {
    if (!context.getBuiltProject().hasNature(KarelNature.NATURE_ID)) return;

    for (Delta delta : context.getDeltas()) {
      IResourceDescription newRes = delta.getNew();
      if (newRes == null) continue;

      try {
        IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
        URI uri = CommonPlugin.resolve(newRes.getURI());
        if (!uri.isFile()) continue;
        IPath path = new Path(uri.toFileString());
        IFile file = workspaceRoot.getFileForLocation(path);
        if (file == null) continue;
        generate(context.getBuiltProject(), file, monitor);
      } catch (Exception e) {
        IStatus status = new Status(IStatus.ERROR, Activator.PLUGIN_ID, e.getMessage(), e);
        Activator.getDefault().getLog().log(status);
      }
    }

    context.getResourceSet();
  }