void emitApplication(ProcessingContext env, ApplicationMetaModel application)
      throws ProcessingException {
    PackageElement elt = env.get(application.getHandle());
    FQN fqn = new FQN(application.getName(), "Application");

    //
    Writer writer = null;
    try {
      JavaFileObject applicationFile = env.createSourceFile(fqn, elt);
      writer = applicationFile.openWriter();

      writer.append("package ").append(fqn.getPackageName()).append(";\n");

      // Imports
      writer.append("import ").append(Tools.getImport(ApplicationDescriptor.class)).append(";\n");

      // Open class
      writer.append("public class ").append(fqn.getSimpleName()).append(" {\n");

      // Field
      writer.append("private final ").append(APPLICATION_DESCRIPTOR).append(" descriptor;\n");

      // Constructor
      writer.append("public ").append(fqn.getSimpleName()).append("() throws Exception {\n");
      writer
          .append("this.descriptor = ")
          .append(APPLICATION_DESCRIPTOR)
          .append(".create(getClass());\n");
      writer.append("}\n");

      // Getter
      writer.append("public ").append(APPLICATION_DESCRIPTOR).append(" getDescriptor() {\n");
      writer.append("return descriptor;\n");
      writer.append("}\n");

      // Close class
      writer.append("}\n");

      //
      env.log("Generated application " + fqn.getName() + " as " + applicationFile.toUri());
    } catch (IOException e) {
      throw TemplateMetaModel.CANNOT_WRITE_APPLICATION.failure(e, elt, application.getName());
    } finally {
      Tools.safeClose(writer);
    }
  }
  private void emitConfig(ModuleMetaModel metaModel) {
    JSON descriptor = new JSON();

    // Application configs
    for (ApplicationMetaModel application : metaModel.getChildren(ApplicationMetaModel.class)) {

      //
      metaModel.processingContext.log(
          "Emitting application " + application.getHandle() + " config");

      // Recycle
      descriptor.clear();

      // Emit config
      for (ApplicationMetaModelPlugin plugin : context.getPlugins()) {
        JSON pluginDescriptor = plugin.getDescriptor(application);
        if (pluginDescriptor != null) {
          descriptor.set(plugin.getName(), pluginDescriptor);
        }
      }

      //
      Writer writer = null;
      try {
        FileObject fo =
            metaModel.processingContext.createResource(
                StandardLocation.CLASS_OUTPUT, application.getName(), "config.json");
        writer = fo.openWriter();
        descriptor.toString(writer, 2);
      } catch (IOException e) {
        throw ApplicationMetaModel.CANNOT_WRITE_APPLICATION_CONFIG.failure(
            e, metaModel.processingContext.get(application.getHandle()), application.getName());
      } finally {
        Tools.safeClose(writer);
      }
    }
  }