public void statistics(File directory, List archiveNames, boolean details, boolean nofilter,
      boolean persec, boolean persample, boolean prunezeros, boolean monitor, long startTime,
      long endTime, List cmdLineSpecs) {
    if (persec && nofilter) {
      throw new IllegalArgumentException(
          "The -nofilter and -persec options are mutually exclusive.");
    }
    if (persec && persample) {
      throw new IllegalArgumentException(
          "The -persample and -persec options are mutually exclusive.");
    }
    if (nofilter && persample) {
      throw new IllegalArgumentException(
          "The -persample and -nofilter options are mutually exclusive.");
    }
    StatSpec[] specs = createSpecs(cmdLineSpecs);
    if (directory != null) {
      throw new IllegalArgumentException(
          "The -archive= and -dir= options are mutually exclusive.");
    }
    StatArchiveReader reader = null;
    boolean interrupted = false;
    try {
      reader = new StatArchiveReader((File[]) archiveNames.toArray(new File[0]),
          specs, !monitor);
      // Runtime.getRuntime().gc(); System.out.println("DEBUG: heap size=" +
      // (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()));
      if (specs.length == 0) {
        if (details) {
          StatArchiveReader.StatArchiveFile[] archives = reader.getArchives();
          for (final StatArchiveReader.StatArchiveFile archive : archives) {
            System.out.println(archive.getArchiveInfo().toString());
          }
        }
      }
      do {
        if (specs.length == 0) {
          for (final Object o : reader.getResourceInstList()) {
            ResourceInst inst = (ResourceInst) o;
            StatValue[] values = inst.getStatValues();
            boolean firstTime = true;
            for (final StatValue value : values) {
              if (value != null && value.hasValueChanged()) {
                if (firstTime) {
                  firstTime = false;
                  System.out.println(inst);
                }
                printStatValue(value, startTime, endTime, nofilter, persec, persample,
                    prunezeros, details);
              }
            }
          }
        } else {
          Map<CombinedResources, List<StatValue>> allSpecsMap =
              new HashMap<>();
          for (final StatSpec spec : specs) {
            StatValue[] values = reader.matchSpec(spec);
            if (values.length == 0) {
              if (!quiet) {
                System.err.println(String.format("[warning] No stats matched %s.",
                    spec.cmdLineSpec));
              }
            } else {
              Map<CombinedResources, List<StatValue>> specMap =
                  new HashMap<>();
              for (StatValue v : values) {
                CombinedResources key = new CombinedResources(v);
                List<StatValue> list = specMap.get(key);
                if (list != null) {
                  list.add(v);
                } else {
                  specMap.put(key, new ArrayList<>(Collections.singletonList(v)));
                }
              }
              if (!quiet) {
                System.out.println(
                    String.format("[info] Found %s instances matching %s:",
                        specMap.size(), spec.cmdLineSpec));
              }
              for (Map.Entry<CombinedResources, List<StatValue>> me : specMap.entrySet()) {
                List<StatValue> list = allSpecsMap.get(me.getKey());
                if (list != null) {
                  list.addAll(me.getValue());
                } else {
                  allSpecsMap.put(me.getKey(), me.getValue());
                }
              }
            }
          }
          for (Map.Entry<CombinedResources, List<StatValue>> me : allSpecsMap.entrySet()) {
            System.out.println(me.getKey());
            for (StatValue v : me.getValue()) {
              printStatValue(v, startTime, endTime, nofilter, persec, persample, prunezeros,
                  details);
            }
          }
        }
        if (monitor) {
          while (!reader.update()) {
            try {
              Thread.sleep(1000);
            } catch (InterruptedException ignore) {
              interrupted = true;
            }
          }
        }
      } while (monitor && !interrupted);
    } catch (IOException ex) {
      throw new GemFireIOException(
          String.format("Failed reading %s", archiveOption), ex);
    } finally {
      if (reader != null) {
        try {
          reader.close();
        } catch (IOException ignore) {
        }
      }
      if (interrupted) {
        Thread.currentThread().interrupt();
      }
    }
  }
List the statistics of a running system.

@param directory the system directory of the system to list.
@param archiveNames the archive file(s) to read.
@param details if true the statistic descriptions will also be listed.
@param nofilter if true then printed stat values will all be raw unfiltered.
@param persec if true then printed stat values will all be the rate of change, per second, of
       the raw values.
@param persample if true then printed stat values will all be the rate of change, per sample,
       of the raw values.
@param prunezeros if true then stat values whose samples are all zero will not be printed.

@throws UncreatedSystemException if the system <code>sysDir</code> does not exist, is not a
        directory, or does not contain a configuration file.
@throws NoSystemException if the system is not running or could not be connected to.
@throws IllegalArgumentException if a statSpec does not match a resource and/or statistic.
@throws GemFireIOException if the archive could not be read
geode-core/src/main/java/org/apache/geode/internal/SystemAdmin.java