public static void main(final String[] args) {
        
        //check useage
        if(args.length < 1) {
            System.out.println("UTF8 Validator version: " + VERSION);
            System.out.println("Useage: utf8validate [options] <file>");
            System.out.println("");
            System.out.println("\t-f | --fail-fast");
            System.out.println("\t\tStops on the first validation error rather than reporting all errors");
            System.out.println("");
            System.exit(ExitCode.INVALID_ARGS.getCode());
        }
        
        //parse args
        final boolean failFast;
        final File f;
        if(args[0].equals("-f") || args[0].equals("--fail-fast")) {
            failFast = true;
            f = new File(args[1]);
        } else {
            failFast = false;
            f = new File(args[0]);
        }
        if(!f.exists()) {
            System.out.println("File: " + f.getPath() + " does not exist!");
            System.exit(ExitCode.INVALID_ARGS.getCode());
        }
        
        final PrintingValidationHandler handler = new PrintingValidationHandler(failFast, System.out);
        
        ExitCode result = ExitCode.OK;
        final long start = System.currentTimeMillis();
        
        System.out.println("Validating: " + f.getPath());
        
        try {
            new Utf8Validator(handler).validate(f);
            
            if(!failFast && handler.isErrored()) {
                result = ExitCode.VALIDATION_ERROR;
            } else {
                System.out.println("Valid OK (took " + (System.currentTimeMillis() - start) + "ms)");
                result = ExitCode.OK;
            }
        } catch(final ValidationException ve) {
            System.out.println(ve.getMessage());
            result = ExitCode.VALIDATION_ERROR;
        } catch(final IOException ioe) {
            System.err.println("[ERROR]" + ioe.getMessage());
            result = ExitCode.IO_ERROR;
        }
        
        System.exit(result.getCode());
    }