private @NotNull List<CommandDescriptor> includeScript(String scriptText, File scriptDir) {
    List<CommandDescriptor> commands = new ArrayList<>();
    final StringTokenizer tokens = new StringTokenizer(scriptText, "\n");
    int line = 0;
    while (tokens.hasMoreTokens()) {
      final String eachLine = tokens.nextToken();

      if (eachLine.startsWith(INCLUDE_CMD)) {
        File file = new PathMacro().setScriptDir(scriptDir).resolveFile(eachLine.substring(INCLUDE_CMD.length()).trim(), scriptDir);
        if (!file.exists()) {
          throw new RuntimeException("Cannot find file to include at line " + line + ": " + file.getAbsolutePath());
        }
        try {
          String include = FileUtil.loadFile(file, true);
          commands.add(new CommandDescriptor(PrintCommand.PREFIX + " " + eachLine, line, scriptDir));
          List<CommandDescriptor> includeCommands = includeScript(include, file.getParentFile());
          commands.addAll(includeCommands);
        }
        catch (IOException e) {
          throw new RuntimeException("Error reading file at line " + line + ": " + file.getAbsolutePath());
        }
      }
      else if (eachLine.startsWith(IMPORT_CALL_CMD)) {
        String className = eachLine.substring(IMPORT_CALL_CMD.length()).trim();
        try {
          Class<?> facadeClass = Class.forName(className);
          facadeClasses.add(facadeClass);
          commands.add(new CommandDescriptor(PrintCommand.PREFIX + " " + eachLine, line++, scriptDir));
        }
        catch (ClassNotFoundException e) {
          throw new RuntimeException("Cannot find class at line " + line + ": " + className);
        }
      }
      else {
        commands.add(new CommandDescriptor(eachLine, line++, scriptDir));
      }
    }
    return commands;
  }
private @NotNull List<CommandDescriptor> includeScript(String scriptText, File scriptDir)