@Override
    public void execute() throws Exception {
        try {
            parseOptions();

            if (options.isHelp()) {
                options.format(new HelpFormatter(), getIoStreams().getStdout());
                exit(ExitCodeImpl.OK);
            }

            if (options.isShowVersion()) {
                getIoStreams().println(String.format("Version: %s", version));
                exit(ExitCodeImpl.OK);
            }

            if (!options.hasSyntaxFile()) {
                getIoStreams().errorln("No syntax file given!");
                exit(ExitCodeImpl.NO_SYNTAX);
            }

            final String syntaxFileName = options.getSyntaxFile();
            final SyntaxNode ast = copenFileParseAndCreateAst(syntaxFileName);

            Application app;

            if (options.isIde()) {
                app = new GuiApplication(options, getIoStreams(), this);
                setExiter(new NullExiter()); // Do not exit on return.
            } else {
                app = new CliApplication(options, getIoStreams(), this);
            }

            app.setSyntax(ast);
            app.execute();
        } catch (EbnfException ex) {
            getIoStreams().errorln(ex.getMessage());

            if (options.isDebug()) {
                getIoStreams().printStackTrace(ex);
            }

            exit(ex.getCode());
        } catch (Exception ex) { // NOPMD Catch all exceptions!
            getIoStreams().errorln("Fatal error!");

            if (options.isDebug()) {
                getIoStreams().printStackTrace(ex);
            }

            exit(ExitCodeImpl.FATAL_ERROR);
        }
    }