private void generateForm(Model model, MolgenisOptions options, UISchema schema)
      throws Exception {
    Template template = createTemplate("/" + getClass().getSimpleName() + ".java.ftl");
    Map<String, Object> templateArgs = createTemplateArguments(options);

    for (UISchema screen : schema.getChildren()) {
      if (screen.getClass() == Form.class) {

        templateArgs.put("form", screen);
        ((Entity) ((Form) screen).getRecord()).getAllFields().firstElement();

        UISchema parent = screen.getParent();
        while (parent != null && !parent.getClass().equals(Form.class))
          // gets the parent form
          parent = parent.getParent();
        templateArgs.put("parent_form", parent);
        templateArgs.put("model", model);
        templateArgs.put("package", getAppPackage() + ".ui");

        File targetDir = new File(this.getSourcePath(options) + getAppDir() + "/ui/");
        boolean created = targetDir.mkdirs();
        if (!created && !targetDir.exists()) {
          throw new IOException("could not create " + targetDir);
        }

        File targetFile =
            new File(
                targetDir
                    + "/"
                    + GeneratorHelper.getJavaName(screen.getClassName())
                    + "FormController.java");
        OutputStream targetOut = new FileOutputStream(targetFile);

        template.process(templateArgs, new OutputStreamWriter(targetOut, Charset.forName("UTF-8")));
        targetOut.close();

        logger.info("generated " + targetFile);
      }

      // get children
      generateForm(model, options, screen);
    }
  }
  private void generateForm(Model model, MolgenisOptions options, UISchema schema)
      throws Exception {
    Template template = createTemplate("/" + getClass().getSimpleName() + ".ftl.ftl");
    Map<String, Object> templateArgs = createTemplateArguments(options);

    for (UISchema screen : schema.getChildren()) {
      if (screen.getClass() == Plugin.class) {

        Plugin plugin = (Plugin) screen;

        String fullKlazzName = plugin.getPluginType();
        String packageName = fullKlazzName;
        if (fullKlazzName.contains("."))
          packageName = fullKlazzName.substring(0, fullKlazzName.lastIndexOf("."));

        String shortKlazzName = fullKlazzName;
        if (fullKlazzName.contains("."))
          shortKlazzName = fullKlazzName.substring(fullKlazzName.lastIndexOf(".") + 1);

        File targetFile =
            new File(
                this.getHandWrittenPath(options) + "/" + fullKlazzName.replace(".", "/") + ".ftl");
        // only generate if the file doesn't exist AND plugin not
        // already on classpath
        Class<?> c = null;
        try {
          c = Class.forName(fullKlazzName);
          // return;
        } catch (ClassNotFoundException e) {
          logger.error("skipped plugin " + plugin.getName() + " as it is on the classpath");
        }
        logger.error("tested classforname on " + fullKlazzName + ": " + c);

        if (!targetFile.exists() && c == null) {
          File targetDir =
              new File(this.getHandWrittenPath(options) + "/" + packageName.replace(".", "/"));
          boolean created = targetDir.mkdirs();
          if (!created && !targetDir.exists()) {
            throw new IOException("could not create " + targetDir);
          }

          templateArgs.put("screen", plugin);
          templateArgs.put("template", template.getName());
          templateArgs.put("clazzName", shortKlazzName);
          templateArgs.put("macroName", fullKlazzName.replace(".", "_"));
          templateArgs.put("templatePath", targetFile.toString().replace("\\", "/"));
          templateArgs.put("package", packageName);

          OutputStream targetOut = new FileOutputStream(targetFile);
          template.process(
              templateArgs, new OutputStreamWriter(targetOut, Charset.forName("UTF-8")));
          targetOut.close();

          logger.info(
              "generated "
                  + targetFile
                      .getAbsolutePath()
                      .substring(this.getHandWrittenPath(options).length()));
        } else {
          logger.warn("Skipped because exists: " + targetFile);
        }
      }

      // get children of this screen and generate those
      generateForm(model, options, screen);
    }
  }