gt:             if (this.isHelp()) {
context: /*
   * Copyright (C) 2015 Federico Tello Gentile <federicotg@gmail.com>
   *
   * This program is free software; you can redistribute it and/or
   * modify it under the terms of the GNU General Public License
   * as published by the Free Software Foundation; either version 2
   * of the License, or (at your option) any later version.
   *
   * This program is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   * GNU General Public License for more details.
   *
   * You should have received a copy of the GNU General Public License
   * along with this program; if not, write to the Free Software
   * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
   */
  package jonelo.jacksum.concurrent;
  
  import com.fasterxml.jackson.databind.ObjectMapper;
  import com.fasterxml.jackson.databind.SerializationFeature;
  import java.io.BufferedOutputStream;
  import java.io.File;
  import java.io.FileOutputStream;
  import java.io.IOException;
  import java.io.InputStream;
  import java.io.PrintStream;
  import java.nio.file.FileSystem;
  import java.nio.file.FileSystems;
  import java.nio.file.FileVisitOption;
  import java.nio.file.Files;
  import java.nio.file.Path;
  import java.security.NoSuchAlgorithmException;
  import java.util.ArrayList;
  import java.util.List;
  import java.util.Map;
  import java.util.ResourceBundle;
  import java.util.concurrent.ConcurrentHashMap;
  import java.util.concurrent.ExecutionException;
  import java.util.stream.Collectors;
  import jonelo.jacksum.algorithm.Algorithm;
  import org.kohsuke.args4j.Argument;
  import org.kohsuke.args4j.CmdLineException;
  import org.kohsuke.args4j.CmdLineParser;
  import org.kohsuke.args4j.Option;
  
  /**
   *
   * @author Federico Tello Gentile <federicotg@gmail.com>
   */
  public class Jacksum2Cli {
  
      private static final List<String> GENERIC_CRC_SPECS = new ArrayList<>();
  
      private static final int ERROR_STATUS = 2;
      private static final int OK = 0;
  
      public static void addCRCSpec(String spec) {
          GENERIC_CRC_SPECS.add(spec);
      }
  
      private PrintStream out = System.out;
      private PrintStream err = System.err;
  
      @Option(name = "-a", handler = AlgorithmHandler.class, metaVar = "algo")
      private List<Algorithm> algorithms;
  
      @Option(name = "-A")
      private boolean alternative = false;
  
      @Option(name = "-c", metaVar = "list")
      private File checkFile = null;
  
      @Option(name = "-d")
      private boolean ignoreSymbolicLinksToDirectories = false;
  
      @Option(name = "-e", metaVar = "seq")
      private String expectedHashValue = null;
  
      @Option(name = "-E", metaVar = "encoding", forbids = {"-x", "-X"})
      private Encoding encoding = Encoding.HEX;
  
      @Option(name = "-f")
      private boolean processFilesOnly = false;
  
      @Option(name = "-F", metaVar = "format", forbids = {"-m"})
      private String format = null;
  
      @Option(name = "-g", metaVar = "count")
      private int hexaGroupSize = -1;
  
      @Option(name = "-G", metaVar = "separatorChar", depends = {"-g"})
      private char hexaGroupSeparatorChar = ' ';
  
      @Option(name = "-h", forbids = {
          "-a", "-A", "-c", "-d",
          "-e", "-E", "-f", "-g", "-G", "-p", "-o", "-O",
          "-I", "-l", "-m", "-P", "-q", "-r", "-s", "-S",
          "-t", "-u", "-U", "-v", "-V", "-w", "-x", "-X"})
      private boolean help = false;
  
      @Option(name = "-p")
      private boolean fullPath = false;
  
      @Option(name = "-o", metaVar = "file", forbids = {"-O"})
      private String outputFile = null;
  
      @Option(name = "-O", metaVar = "file", forbids = {"-o"})
      private String overwriteOutputFile = null;
  
      @Option(name = "-I", metaVar = "string")
      private String prefixToIgnoreInFilenames = null;
  
      @Option(name = "-l", depends = {"-c"})
      private boolean onlyListModifiedFiles = false;
  
      @Option(name = "-m", forbids = {"-F"})
      private boolean printMetainfo;
  
      @Option(name = "-P", metaVar = "char")
      private char separator = File.separatorChar;
  
      @Option(name = "-q")
      private String quickSequence;
  
      @Option(name = "-r")
      private boolean recursive;
  
      @Option(name = "-s", metaVar = "sep")
      private String customSeparator = " ";
  
      @Option(name = "-S")
      private boolean summary;
  
      @Option(name = "-t", metaVar = "form")
      private String dateFormat = null;
  
      @Option(name = "-u", metaVar = "file", forbids = {"-U"})
      private String errorFileName;
  
      @Option(name = "-U", metaVar = "file", forbids = {"-u"})
      private String overwriteErrorFileName;
  
      @Option(name = "-v")
      private boolean showVersion;
  
      @Option(name = "-V", metaVar = "control")
      private String verbosity;
  
      @Option(name = "-w")
      private boolean fileParamIsDirAndWorkingDirectory;
  
      @Option(name = "-x", forbids = {"-E", "-X"})
      private boolean lowerHexaFormat = false;
  
      @Option(name = "-X", forbids = {"-E", "-x"})
      private boolean upperHexaFormat = false;
  
      @Argument
      private List<String> filenames = new ArrayList<>();
  
      public static void main(String[] args) {
          Jacksum2Cli app = new Jacksum2Cli();
          try {
              app.initArgs(args);
          } catch (CmdLineException ex) {
              System.err.println(ex.getMessage());
              System.exit(ERROR_STATUS);
          }
  
          int status = app.printResults();
          System.exit(status);
  
      }
  
      public void initArgs(String[] args) throws CmdLineException {
  
          CmdLineParser parser = new CmdLineParser(this);
  
          // parse the arguments.
          parser.parseArgument(args);
          // you can parse additional arguments if you want.
          // parser.parseArgument("more","args");
          // after parsing arguments, you should check
          // if enough arguments are given.
  
      }
  
      private void buildQuickReport(JacksumReport report, HashFormat simpleFormat) {
          final byte[] bytes = QuickSequenceType.decodeQuickSequence(this.quickSequence);
  
          final Map<Algorithm, byte[]> results = new ConcurrentHasher().hashBytes(
                  bytes,
                  this.algorithms,
                  this.alternative,
                  GENERIC_CRC_SPECS);
  
          report.addLine(
                  simpleFormat.format(
                          algorithms,
                          this.algorithms.stream().map(algo -> results.get(algo)).collect(Collectors.toList())),
                  bytes.length);
      }
  
      private void buildFilesReport(JacksumReport report, HashFormat simpleFormat) throws IOException, NoSuchAlgorithmException, InterruptedException, ExecutionException {
          final List<Path> allFiles = new ArrayList<>();
          final Map<Path, Long> fileSizes = new ConcurrentHashMap<>();
          final Map<Path, Long> fileLastModified = new ConcurrentHashMap<>();
          this.loadFilesToHash(allFiles, fileSizes, fileLastModified);
          final Map<Pair<Path, Algorithm>, byte[]> results = new ConcurrentHasher().hashFiles(allFiles,
                  this.algorithms,
                  this.alternative,
                  GENERIC_CRC_SPECS);
  
          for (Path fn : allFiles) {
              report.addLine(
                      fn.toString(),
                      simpleFormat.format(
                              algorithms,
                              this.algorithms.stream().map(algo -> results.get(new Pair<>(fn, algo))).collect(Collectors.toList())),
                      fileSizes.get(fn));
  
          }
      }
  
      public int printResults() {
          try {
  
  