public void run() {
        String inLine = null;
        for (;;) {
            String url = null;
            try {
                while ((inLine = in.readLine()) != null) {
                    parseErrors.clear();
                    validationErrors.clear();
                    documentMode = null;

                    Validator validator = setupValidator(schemas);
                    parser.setContentHandler(validator.getContentHandler());
                    
                    String md5;
                    String charset;
                    int firstTab = inLine.indexOf('\t');
                    int secondTab = inLine.indexOf('\t', firstTab + 1);
                    md5 = inLine.substring(0, firstTab);
                    url = inLine.substring(firstTab + 1, secondTab);
                    charset = inLine.substring(secondTab + 1, inLine.length());

                    InputSource is = new InputSource();

                    File top = new File(rootDir, md5.substring(0, 2));
                    File second = new File(top, md5.substring(2, 4));
                    File inFile = new File(second, md5 + ".gz");

                    is.setByteStream(new GZIPInputStream(new FileInputStream(
                            inFile)));
                    is.setSystemId(url);
                    if (!"null".equals(charset)) {
                        is.setEncoding(charset);
                    }
                    
                    parser.parse(is);

                    validator = null;
                    
                    StringBuilder sb = new StringBuilder();
                    boolean first = true;
                    
                    if (parseErrors.isEmpty() && validationErrors.isEmpty()) {
                        if (!first) {
                            sb.append('\n');
                        } else {
                            first = false;                                
                        }
                        sb.append(url + '\t' + documentMode + "\tP\t"
                                + "NEITHER ERRORS");                        
                    }
                    if (parseErrors.isEmpty()) {
                        if (!first) {
                            sb.append('\n');
                        } else {
                            first = false;                                
                        }
                        sb.append(url + '\t' + documentMode + "\tP\t"
                                + "NO PARSE ERRORS");
                    } else {
                        for (String error : parseErrors) {
                            if (!first) {
                                sb.append('\n');
                            } else {
                                first = false;                                
                            }
                            sb.append(url + '\t' + documentMode + "\tP\t"
                                    + sanitize(error));
                        }
                    }
                    if (validationErrors.isEmpty()) {
                        if (!first) {
                            sb.append('\n');
                        } else {
                            first = false;                                
                        }
                        sb.append(url + '\t' + documentMode + "\tV\t"
                                + "NO VALIDATION ERRORS");
                    } else {
                        for (String error : validationErrors) {
                            if (!first) {
                                sb.append('\n');
                            } else {
                                first = false;                                
                            }
                            sb.append(url + '\t' + documentMode + "\tV\t"
                                    + sanitize(error));
                        }
                    }
                    out.println(sb.toString());
                }
                return;
            } catch (Throwable t) {
                System.err.println(url);
                t.printStackTrace();
            }
        }
    }
@param in
@param out
@param rootDir
@param resolver
resources/examples/research-src/nu/validator/batchresearch/ValidationWorker.java