@Override
    public void run() {

      try {
        MBeanServerConnection mserver = connInfo.getMServer();
        ThreadMXBean bean = ThreadMXBeanEx.BeanHelper.connectThreadMXBean(mserver);

        sampler = new ThreadDumpSampler();
        sampler.setThreadFilter(threadFilter);

        sampler.connect(bean);

        if (limit == 0) {
          limit = Long.MAX_VALUE;
        }

        StackTraceWriter proxy = new StackWriterProxy();

        openWriter();
        long deadline = System.currentTimeMillis() + timeoutMS;
        long nextReport = 500;
        while (System.currentTimeMillis() < deadline && traceCounter < limit) {
          long nextsample = System.currentTimeMillis() + samplerIntervalMS;
          sampler.collect(proxy);
          if (traceCounter >= nextReport) {
            System.out.println("Collected " + traceCounter);
            while (traceCounter >= nextReport) {
              nextReport += 500;
            }
            checkRotate();
          }
          // delay
          while (nextsample > System.currentTimeMillis()) {
            long st = nextsample - System.currentTimeMillis();
            if (st > 0) {
              Thread.sleep(st);
            }
          }
        }

        writer.close();
        System.out.println("Trace dumped: " + traceCounter);

      } catch (Exception e) {
        host.fail("Unexpected error: " + e.toString(), e);
      }
    }
    @Override
    public void run() {

      try {

        for (String rule : maskingRules) {
          String[] parts = rule.split("[:]");
          if (parts.length != 2) {
            host.fail("Bad masking pattern [" + rule + "] should be int [match:replace] format");
          }
          masking.add(new MaskRule(parts[0], parts[1]));
        }

        AntPathMatcher matcher = new AntPathMatcher();
        matcher.setPathSeparator("/");

        List<String> inputs = new ArrayList<String>();

        System.out.println("Input files");

        for (String f : inputFiles) {
          f = f.replace('\\', '/');
          for (File ff : matcher.findFiles(new File("."), f)) {
            if (ff.isFile()) {
              inputs.add(ff.getPath());
              System.out.println("  " + ff.getPath());
            }
          }
        }
        System.out.println();

        if (inputs.isEmpty()) {
          host.fail("Input file list is empty");
        }

        openWriter();

        final StackTraceReader rawReader = StackTraceCodec.newReader(inputs.toArray(new String[0]));

        StackTraceReader reader =
            new StackTraceReader.StackTraceReaderDelegate() {

              @Override
              protected StackTraceReader getReader() {
                return rawReader;
              }

              @Override
              public boolean loadNext() throws IOException {
                try {
                  return super.loadNext();
                } catch (IOException e) {
                  System.err.println("Dump file read error: " + e.toString());
                  return false;
                }
              }
            };

        if (!reader.isLoaded()) {
          reader.loadNext();
        }

        ReaderProxy proxy =
            new ReaderProxy(reader) {

              @Override
              public StackFrameList stackTrace() {
                return mask(reader.getStackTrace());
              }
            };

        StackWriterProxy writerProxy = new StackWriterProxy();

        while (reader.isLoaded()) {
          writerProxy.write(proxy);
          reader.loadNext();
        }

        System.out.println(traceCounter + " traces written");
        writer.close();

      } catch (Exception e) {
        host.fail("Unexpected error: " + e.toString(), e);
      }
    }