code: package eu.fbk.dh.tint.runner;
  
  import com.google.common.base.Throwables;
  import eu.fbk.utils.core.CommandLine;
  import org.slf4j.Logger;
  import org.slf4j.LoggerFactory;
  
  import java.io.*;
  import java.lang.reflect.InvocationTargetException;
  import java.lang.reflect.Method;
  import java.lang.reflect.Modifier;
  import java.util.List;
  import java.util.Properties;
  
  /**
   * Created by alessio on 03/08/16.
   */
  
  public class TintRunner {
  
      private static final Logger LOGGER = LoggerFactory.getLogger(TintRunner.class);
  
      public static enum OutputFormat {
          READABLE, JSON, XML, CONLL, CONLLU, NAF, TEXTPRO, TOKEN, IOB
      }
  
      public static void main(String[] args) {
          try {
              final CommandLine cmd = CommandLine
                      .parser()
                      .withName("tint")
                      .withHeader("Run the Tint pipeline.")
                      .withOption("c", "config-file", "Configuration file", "FILE",
                              CommandLine.Type.FILE_EXISTING, true, false, false)
                      .withOption("i", "input-file", "Input text file (default stdin)", "FILE",
                              CommandLine.Type.FILE_EXISTING, true, false, false)
                      .withOption("o", "output-file", "Output processed file (default stdout)", "FILE",
                              CommandLine.Type.FILE_EXISTING, true, false, false)
                      .withOption("f", "output-format",
                              "Output format: textpro, json, xml, conll, conllu, readable (default conll), token",
                              "FORMAT",
                              CommandLine.Type.STRING, true, false, false)
                      .withOption(null, "properties", "Additional properties for Stanford CoreNLP", "PROPS",
                              CommandLine.Type.STRING, true, false, false)
                      .withLogger(LoggerFactory.getLogger("eu.fbk")).parse(args);
  
              final File inputPath = cmd.getOptionValue("i", File.class);
              final File outputPath = cmd.getOptionValue("o", File.class);
              final File configPath = cmd.getOptionValue("c", File.class);
  
              List<String> addProperties = cmd.getOptionValues("properties", String.class);
              Properties additionalProps = new Properties();
              for (String property : addProperties) {
                  try {
                      additionalProps.load(new StringReader(property));
                  } catch (Exception e) {
                      // continue
                  }
              }
  
              Console console = System.console();
              if (console == null) {
                  final String loggerClassName = LOGGER.getClass().getName();
                  if (loggerClassName.equals("ch.qos.logback.classic.Logger")) {
                      final Class<?> levelClass = Class.forName("ch.qos.logback.classic.Level");
                      final Object level = call(levelClass, "valueOf", "OFF");
                      call(LOGGER, "setLevel", level);
                  } else if (loggerClassName.equals("org.apache.log4j.Logger")) {
                      final Class<?> levelClass = Class.forName("org.apache.log4j.Level");
                      final Object level = call(levelClass, "valueOf", "OFF");
                      call(LOGGER, "setLevel", level);
                  } else if (loggerClassName.equals("org.apache.logging.slf4j.Log4jLogger")) {
  
                      // todo: check
                      final Class<?> managerClass = Class
                              .forName("org.apache.logging.log4j.LogManager");
                      final Object ctx = call(managerClass, "getContext", false);
                      final Object config = call(ctx, "getConfiguration");
                      final Object logConfig = call(config, "getLoggerConfig",
                              LOGGER.getName());
                      final Class<?> levelClass = Class
                              .forName("org.apache.logging.log4j.Level");
                      final Object level = call(levelClass, "valueOf", "OFF");
                      call(logConfig, "setLevel", level);
                      call(ctx, "updateLoggers");
                  }
  
  //            if (outputPath == null) {
                  // todo: disable logging at all
  //                ((ch.qos.logback.classic.Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME)).setLevel(Level.OFF);
  //                ((ch.qos.logback.classic.Logger) LoggerFactory.getLogger("eu.fbk")).setLevel(Level.OFF);
              }
  
              final String formatString = cmd.getOptionValue("f", String.class);
              OutputFormat format = getOutputFormat(formatString, OutputFormat.JSON);
  
              // Input
  
              InputStream inputStream;
  //            Reader reader;
  
              if (inputPath != null) {
                  inputStream = new FileInputStream(inputPath);
              } else {
                  inputStream = System.in;
              }
  
              // Text annotation
  
              TintPipeline pipeline = new TintPipeline();
              pipeline.loadDefaultProperties();
              pipeline.loadPropertiesFromFile(configPath);
              pipeline.addProperties(additionalProps);
              pipeline.load();
              System.err.println("Tint is ready");
  
              // Output
  
              OutputStream outputStream = System.out;
              if (outputPath != null) {
                  outputStream = new FileOutputStream(outputPath);
              }
  
              pipeline.run(inputStream, outputStream, format);
  
          } catch (Exception e) {
              CommandLine.fail(e);
          }
      }
  
      public static OutputFormat getOutputFormat(String formatString, OutputFormat outputFormat) {
          OutputFormat format = outputFormat;
          try {
              format = OutputFormat.valueOf(formatString.toUpperCase());
          } catch (Exception e) {
              LOGGER.error("Unrecognized format {}, using default ({})", formatString, outputFormat.toString());
              // continue
          }
          return format;
      }
  
      private static Object call(final Object object, final String methodName,
              final Object... args) {
          final boolean isStatic = object instanceof Class<?>;
          final Class<?> clazz = isStatic ? (Class<?>) object : object.getClass();
          for (final Method method : clazz.getMethods()) {
              if (method.getName().equals(methodName)
                      && isStatic == Modifier.isStatic(method.getModifiers())
                      && method.getParameterTypes().length == args.length) {
                  try {
                      return method.invoke(isStatic ? null : object, args);
                  } catch (final InvocationTargetException ex) {
                      Throwables.propagate(ex.getCause());
                  } catch (final IllegalAccessException ex) {
                      throw new IllegalArgumentException("Cannot invoke " + method, ex);
                  }
              }
          }
          throw new IllegalArgumentException("Cannot invoke " + methodName);
      }
  
  }
  