Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * Copyright (C) 2011 Tatsuhiro Tsujikawa
   *
   * Permission is hereby granted, free of charge, to any person
   * obtaining a copy of this software and associated documentation
   * files (the "Software"), to deal in the Software without
   * restriction, including without limitation the rights to use, copy,
   * modify, merge, publish, distribute, sublicense, and/or sell copies
   * of the Software, and to permit persons to whom the Software is
  * furnished to do so, subject to the following conditions:
  *
  * The above copyright notice and this permission notice shall be
  * included in all copies or substantial portions of the Software.
  *
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
 package net.sourceforge.argparse4j.internal;
 
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
The application code must not use this class directly.
 
 public final class ArgumentParserImpl implements ArgumentParser {
 
     private Map<StringArgumentImploptargIndex_ = new HashMap<StringArgumentImpl>();
     private List<ArgumentImploptargs_ = new ArrayList<ArgumentImpl>();
     private List<ArgumentImplposargs_ = new ArrayList<ArgumentImpl>();
     private Map<StringObjectdefaults_ = new HashMap<StringObject>();
     private SubparsersImpl subparsers_ = new SubparsersImpl(this);
     private ArgumentParserImpl mainParser_;
     private String command_;
     private String prog_;
     private String description_ = "";
     private String epilog_ = "";
     private String version_ = "";
     private PrefixPattern prefixPattern_;
     private boolean defaultHelp_ = false;
     private boolean negNumFlag_ = false;
     private static final Pattern NEG_NUM_PATTERN = Pattern.compile("-\\d+");
     private static final Pattern SHORT_OPTS_PATTERN = Pattern
             .compile("-[^-].*");
 
     public static final int FORMAT_WIDTH = 75;
     public static final String PREFIX_CHARS = "-";
 
     public ArgumentParserImpl(String prog) {
         this(progtruenullnew ASCIITextWidthCounter(), null,
                 null);
     }
 
     public ArgumentParserImpl(String progboolean addHelp) {
         this(progaddHelpnullnew ASCIITextWidthCounter(),
                 nullnull);
     }
 
     public ArgumentParserImpl(String progboolean addHelpString prefixChars) {
         this(progaddHelpprefixCharsnullnew ASCIITextWidthCounter(),
                 nullnull);
     }
    public ArgumentParserImpl(String progboolean addHelpString prefixChars,
            String fromFilePrefix) {
        this(progaddHelpprefixCharsfromFilePrefix,
                new ASCIITextWidthCounter(), nullnull);
    }
    public ArgumentParserImpl(String progboolean addHelpString prefixChars,
            String fromFilePrefixTextWidthCounter textWidthCounter) {
        this(progaddHelpprefixCharsfromFilePrefixtextWidthCounternullnull);
    }
    public ArgumentParserImpl(String progboolean addHelpString prefixChars,
            String fromFilePrefixTextWidthCounter textWidthCounter,
            String commandArgumentParserImpl mainParser) {
        this. = TextHelper.nonNull(prog);
        this. = command;
        this. = mainParser;
        this. = textWidthCounter;
        if (prefixChars == null || prefixChars.isEmpty()) {
            throw new IllegalArgumentException(
                    "prefixChars cannot be a null or empty");
        }
        this. = new PrefixPattern(prefixChars);
        if (fromFilePrefix != null) {
            this. = new PrefixPattern(fromFilePrefix);
        }
        if (addHelp) {
            String prefix = prefixChars.substring(0, 1);
            addArgument(prefix + "h"prefix + prefix + "help")
                    .action(Arguments.help())
                    .help("show this help message and exit")
                    .setDefault(.);
        }
    }
    @Override
    public ArgumentImpl addArgument(String... nameOrFlags) {
        return addArgument(nullnameOrFlags);
    }
    public ArgumentImpl addArgument(ArgumentGroup groupString... nameOrFlags) {
        ArgumentImpl arg = new ArgumentImpl(groupnameOrFlags);
        if (arg.isOptionalArgument()) {
            for (String flag : arg.getFlags()) {
                ArgumentImpl another = .get(flag);
                if (another != null) {
                    // TODO No conflict handler ATM
                    throw new IllegalArgumentException(String.format(
                            "argument %s: conflicting option string(s): %s",
                            flaganother.textualName()));
                }
            }
            for (String flag : arg.getFlags()) {
                if (.matcher(flag).matches()) {
                     = true;
                }
                .put(flagarg);
            }
            .add(arg);
        } else {
            for (ArgumentImpl another : ) {
                if (arg.getName().equals(another.getName())) {
                    // TODO No conflict handler ATM
                    throw new IllegalArgumentException(String.format(
                            "argument %s: conflicting option string(s): %s",
                            arg.getName(), another.textualName()));
                }
            }
            .add(arg);
        }
        return arg;
    }
    @Override
    public Subparsers addSubparsers() {
        return ;
    }
    @Override
    public ArgumentGroup addArgumentGroup(String title) {
        ArgumentGroupImpl group = new ArgumentGroupImpl(thistitle);
        .add(group);
        return group;
    }

    
Set text to display before the argument help.

Parameters:
description text to display before the argument help
Returns:
this
    @Override
    public ArgumentParserImpl description(String description) {
         = TextHelper.nonNull(description);
        return this;
    }
    @Override
    public ArgumentParserImpl epilog(String epilog) {
         = TextHelper.nonNull(epilog);
        return this;
    }
    @Override
    public ArgumentParserImpl version(String version) {
         = TextHelper.nonNull(version);
        return this;
    }
    @Override
    public ArgumentParserImpl defaultHelp(boolean defaultHelp) {
         = defaultHelp;
        return this;
    }
    public boolean isDefaultHelp() {
        return ;
    }
    private void printArgumentHelp(PrintWriter writerList<ArgumentImplargs) {
        for (ArgumentImpl arg : args) {
            if (arg.getArgumentGroup() == null) {
                arg.printHelp(writer,
                        );
            }
        }
    }
    @Override
    public void printHelp() {
        PrintWriter writer = new PrintWriter(.);
        printHelp(writer);
        writer.close();
    }
    @Override
    public void printHelp(PrintWriter writer) {
        printUsage(writer);
        if (!.isEmpty()) {
            writer.format("\n%s\n", TextHelper.wrap(,
                    , 0, """"));
        }
        boolean subparsersUntitled = .getTitle().isEmpty()
                && .getDescription().isEmpty();
        if (checkDefaultGroup()
                || (.hasSubCommand() && subparsersUntitled)) {
            writer.print("\npositional arguments:\n");
            printArgumentHelp(writer);
            if (.hasSubCommand() && subparsersUntitled) {
                .printSubparserHelp(writer);
            }
        }
        if (checkDefaultGroup()) {
            writer.print("\noptional arguments:\n");
            printArgumentHelp(writer);
        }
        if (.hasSubCommand() && !subparsersUntitled) {
            writer.format("\n%s:\n",
                    .getTitle().isEmpty() ? "subcommands"
                            : .getTitle());
            if (!.getDescription().isEmpty()) {
                writer.format("  %s\n\n", TextHelper
                        .wrap(.getDescription(),
                                , 2, """  "));
            }
            .printSubparserHelp(writer);
        }
        for (ArgumentGroupImpl group : ) {
            writer.print("\n");
            group.printHelp(writer);
        }
        if (!.isEmpty()) {
            writer.format("\n%s\n", TextHelper.wrap(,
                    , 0, """"));
        }
        writer.flush();
    }
    private boolean checkDefaultGroup(List<ArgumentImplargs) {
        if (args.isEmpty()) {
            return false;
        }
        for (ArgumentImpl arg : args) {
            if (arg.getArgumentGroup() == null) {
                return true;
            }
        }
        return false;
    }
    @Override
    public String formatHelp() {
        StringWriter writer = new StringWriter();
        printHelp(new PrintWriter(writer));
        return writer.toString();
    }
    private void printArgumentUsage(PrintWriter writerList<Stringopts,
            int offsetString firstIndentString subsequentIndent) {
        int currentWidth = offset + firstIndent.length();
        writer.print(firstIndent);
        boolean first = true;
        for (String syntax : opts) {
            if (!first && currentWidth + syntax.length() + 1 > ) {
                writer.print("\n");
                writer.print(subsequentIndent);
                writer.print(" ");
                writer.print(syntax);
                currentWidth = subsequentIndent.length() + 1 + syntax.length();
            } else {
                writer.print(" ");
                writer.print(syntax);
                currentWidth += 1 + syntax.length();
                first = false;
            }
        }
        writer.print("\n");
    }
    @Override
    public void printUsage() {
        printUsage(new PrintWriter(.));
    }
    @Override
    public void printUsage(PrintWriter writer) {
        String usageprog = String.format("usage: %s");
        writer.print(usageprog);
        int offset;
        String firstIndent;
        String subsequentIndent;
        String indent = "                              ";
        int usageprogWidth = .width(usageprog);
        if (usageprogWidth > indent.length()) {
            writer.print("\n");
            offset = 6;
            firstIndent = subsequentIndent = indent.substring(0, offset);
        } else {
            offset = usageprogWidth;
            firstIndent = "";
            subsequentIndent = indent.substring(0, offset);
        }
        List<Stringopts = new ArrayList<String>();
        addUpperParserUsage(opts);
        if ( != null) {
            opts.add();
        }
        for (ArgumentImpl arg : ) {
            opts.add(arg.formatShortSyntax());
        }
        for (ArgumentImpl arg : ) {
            opts.add(arg.formatShortSyntax());
        }
        if (.hasSubCommand()) {
            opts.add(.formatShortSyntax());
            opts.add("...");
        }
        printArgumentUsage(writeroptsoffsetfirstIndentsubsequentIndent);
    }

    
Appends command, required optional arguments and positional arguments in parser to opts recursively. Most upper parser stores first, just like post order traversal.

Parameters:
opts Command, required optional arguments and positional arguments.
parser The parser
    private void addUpperParserUsage(List<Stringopts,
            ArgumentParserImpl parser) {
        if (parser == null) {
            return;
        }
        addUpperParserUsage(optsparser.mainParser_);
        if (parser.command_ != null) {
            opts.add(parser.command_);
        }
        for (ArgumentImpl arg : parser.optargs_) {
            if (arg.isRequired()) {
                opts.add(arg.formatShortSyntax());
            }
        }
        for (ArgumentImpl arg : parser.posargs_) {
            opts.add(arg.formatShortSyntax());
        }
    }
    @Override
    public String formatUsage() {
        StringWriter writer = new StringWriter();
        printUsage(new PrintWriter(writer));
        return writer.toString();
    }
    @Override
    public ArgumentParserImpl setDefault(String destObject value) {
        .put(destvalue);
        return this;
    }
    @Override
    public ArgumentParser setDefaults(Map<StringObjectattrs) {
        .putAll(attrs);
        return this;
    }

    
Returns default value set by ArgumentImpl.setDefault(java.lang.Object) or setDefault(java.lang.String,java.lang.Object). Please note that while parser-level defaults always override argument-level defaults while parsing, this method examines argument-level defaults first. If no default value is found, then check parser-level defaults.

Parameters:
dest attribute name of default value to get.
Returns:
default value of given dest.
    @Override
    public Object getDefault(String dest) {
        for (ArgumentImpl arg : ) {
            if (dest.equals(arg.getDest()) && arg.getDefault() != null) {
                return arg.getDefault();
            }
        }
        for (ArgumentImpl arg : ) {
            if (dest.equals(arg.getDest()) && arg.getDefault() != null) {
                return arg.getDefault();
            }
        }
        return .get(dest);
    }
    @Override
    public Namespace parseArgs(String args[]) throws ArgumentParserException {
        Map<StringObjectattrs = new HashMap<StringObject>();
        parseArgs(argsattrs);
        return new Namespace(attrs);
    }
    @Override
    public void parseArgs(String[] argsMap<StringObjectattrs)
            throws ArgumentParserException {
        parseArgs(args, 0, attrs);
    }
    @Override
    public void parseArgs(String[] argsObject userData)
            throws ArgumentParserException {
        Map<StringObjectopts = new HashMap<StringObject>();
        parseArgs(argsoptsuserData);
    }
	public void parseArgs(String[] argsMap<StringObjectattrs,
			Object userDatathrows ArgumentParserException {
		parseArgs(args, 0, attrs);
		Class userClass = userData.getClass();
		while (userClass != null) {
			for (Field field : userClass.getDeclaredFields()) {
				Arg ann = field.getAnnotation(Arg.class);
				if (ann != null) {
					String argDest = ann.dest();
					if (argDest.isEmpty()) {
						argDest = field.getName();
					}
					if (!attrs.containsKey(argDest)) {
						continue;
					}
					Object val = attrs.get(argDest);
					try {
						field.setAccessible(true);
						field.set(userData,
								ReflectHelper.list2Array(field.getType(), val));
catch (RuntimeException e) {
						if (!ann.ignoreError()) {
							throw e;
						}
catch (Exception e) {
						if (!ann.ignoreError()) {
							throw new IllegalArgumentException(String.format(
									"Could not set %s to field %s"val,
									field.getName()), e);
						}
					}
				}
			}
			for (Method method : userClass.getDeclaredMethods()) {
				Arg ann = method.getAnnotation(Arg.class);
				if (ann != null) {
					String argDest = ann.dest();
					if (argDest.isEmpty()) {
						argDest = method.getName();
					}
					if (!attrs.containsKey(argDest)) {
						continue;
					}
					Object val = attrs.get(argDest);
					Class<?> fargs[] = method.getParameterTypes();
					if (fargs.length != 1) {
						throw new IllegalArgumentException(String.format(
								"Method %s must have one formal parameter",
								method.getName()));
					}
					try {
						method.setAccessible(true);
						method.invoke(userData,
								ReflectHelper.list2Array(fargs[0], val));
catch (RuntimeException e) {
						if (!ann.ignoreError()) {
							throw e;
						}
catch (Exception e) {
						if (!ann.ignoreError()) {
							throw new IllegalArgumentException(String.format(
									"Could not call method %s with %s",
									method.getName(), val), e);
						}
					}
				}
			}
			userClass = userClass.getSuperclass();
		}
	}
    public void parseArgs(String args[], int offsetMap<StringObjectattrs)
            throws ArgumentParserException {
        ParseState state = new ParseState(argsoffset);
        parseArgs(stateattrs);
    }
    public void parseArgs(ParseState stateMap<StringObjectattrs)
            throws ArgumentParserException {
        populateDefaults(attrs);
        Set<ArgumentImplused = new HashSet<ArgumentImpl>();
        int posargIndex = 0;
        int posargsLen = .size();
        while (state.isArgAvail()) {
            // We first evaluate flagFound(state) before comparing arg to "--"
            // in order to expand arguments from file.
            if (flagFound(state) && !"--".equals(state.getArg())) {
                String term = state.getArg();
                int p = term.indexOf("=");
                String flag;
                String embeddedValue;
                if (p == -1) {
                    flag = term;
                    embeddedValue = null;
                } else {
                    flag = term.substring(0, p);
                    embeddedValue = term.substring(p + 1);
                }
                ArgumentImpl arg = .get(flag);
                if (arg == null) {
                    boolean shortOptsFound = false;
                    if (.matcher(term).matches()
                            && .get(term) == null) {
                        shortOptsFound = true;
                        // Possible concatenated short options
                        for (int i = 1, termlen = term.length(); i < termlen; ++i) {
                            String shortFlag = "-" + term.substring(ii + 1);
                            arg = .get(shortFlag);
                            if (arg == null) {
                                shortOptsFound = false;
                                break;
                            }
                            if (arg.getAction().consumeArgument()) {
                                flag = shortFlag;
                                shortOptsFound = true;
                                embeddedValue = term.substring(i + 1);
                                break;
                            }
                            arg.run(thisattrsshortFlagnull);
                            used.add(arg);
                        }
                    }
                    if (!shortOptsFound) {
                        throw new UnrecognizedArgumentException(String.format(
                                "unrecognized arguments: %s"term), thisterm);
                    }
                }
                assert (arg.getAction() != null);
                ++state.index;
                processArg(attrsstateargflagembeddedValue);
                used.add(arg);
            } else if ("--".equals(state.getArg()) && !state.consumedSeparator) {
                state.consumedSeparator = true;
                state.negNumFlag = false;
                ++state.index;
            } else if (posargIndex < posargsLen) {
                ArgumentImpl arg = .get(posargIndex++);
                processArg(attrsstateargnullnull);
            } else if (!state.consumedSeparator && .hasSubCommand()) {
                checkRequiredArgument(usedposargIndex);
                .parseArg(stateattrs);
                return;
            } else {
                throw new ArgumentParserException(String.format(
                        "unrecognized arguments: %s",
                        TextHelper.concat(state.argsstate.index" ")), this);
            }
        }
        if (.hasSubCommand()) {
            throw new ArgumentParserException("too few arguments"this);
        }
        while (posargIndex < posargsLen) {
            ArgumentImpl arg = .get(posargIndex++);
            processArg(attrsstateargnullnull);
        }
        checkRequiredArgument(usedposargIndex);
    }

    

Parameters:
res
state state.offset points to the argument next to flag
arg
flag
embeddedValue If optional argument is given as "foo=bar" or "-fbar" (short option), embedded value is "bar". Otherwise null
Throws:
net.sourceforge.argparse4j.inf.ArgumentParserException
    private void processArg(Map<StringObjectresParseState state,
            ArgumentImpl argString flagString embeddedValue)
            throws ArgumentParserException {
        if (!arg.getAction().consumeArgument()) {
            if (embeddedValue == null) {
                arg.run(thisresflagnull);
                return;
            } else {
                throw new ArgumentParserException(String.format(
                        "ignore implicit argument '%s'"embeddedValue), this,
                        arg);
            }
        }
        if (arg.getMinNumArg() == -1
                || (arg.getMinNumArg() == 0 && arg.getMaxNumArg() == 1)) {
            String argval = null;
            if (embeddedValue == null) {
                if (state.isArgAvail() && !flagFound(state)) {
                    argval = state.getArg();
                    ++state.index;
                }
            } else {
                argval = embeddedValue;
            }
            if (argval == null) {
                if (arg.getMinNumArg() == -1) {
                    if (arg.isOptionalArgument()) {
                        throw new ArgumentParserException(
                                "expected one argument"thisarg);
                    } else {
                        throw new ArgumentParserException("too few arguments",
                                this);
                    }
                } else if (arg.isOptionalArgument()) {
                    arg.run(thisresflagarg.getConst());
                }
            } else {
                arg.run(thisresflagarg.convert(thisargval));
            }
        } else {
            List<Objectlist = new ArrayList<Object>();
            if (embeddedValue == null) {
                for (int i = 0; i < arg.getMaxNumArg() && state.isArgAvail(); ++i, ++state.index) {
                    if (flagFound(state)) {
                        break;
                    }
                    list.add(arg.convert(thisstate.getArg()));
                }
            } else {
                list.add(embeddedValue);
            }
            if (list.size() < arg.getMinNumArg()) {
                if (arg.isOptionalArgument()) {
                    throw new ArgumentParserException(String.format(
                            "expected %d argument(s)"arg.getMinNumArg()),
                            thisarg);
                } else {
                    throw new ArgumentParserException("too few arguments"this);
                }
            }
            if (!list.isEmpty()) {
                arg.run(thisresflaglist);
            }
        }
    }

    
Returns true if state.getArg() is flag. Note that if "--" is met and not consumed, this function returns true, because "--" is treated as special optional argument. If prefixFileChar is found in prefix of argument, read arguments from that file and expand arguments in state necessary.

    private boolean flagFound(ParseState statethrows ArgumentParserException {
        while (fromFileFound(state)) {
            state.resetArgs(extendArgs(
                    .removePrefix(state.getArg()),
                    state.argsstate.index + 1));
        }
        String term = state.getArg();
        if (state.consumedSeparator) {
            return false;
        } else if ("--".equals(term)) {
            return true;
        }
        return .match(term)
                && (state.negNumFlag || !.matcher(term)
                        .matches());
    }
    private boolean fromFileFound(ParseState state) {
        return  != null
                && .match(state.getArg());
    }

    
Extends arguments by reading additional arguments from file. The length of returned array is oldargs.length - offset + the number of arguments in the file. We discard [0,offset) in oldargs. So the returned array starts with oldargs[offset].

Parameters:
file File from which additional arguments are read.
oldargs Old arguments
offset Offset in old arguments. This is typically the argument next to fromFilePrefix argument.
Returns:
The extended new argument array.
Throws:
net.sourceforge.argparse4j.inf.ArgumentParserException
    private String[] extendArgs(String fileString oldargs[], int offset)
            throws ArgumentParserException {
        List<Stringlist = new ArrayList<String>();
        BufferedReader reader;
        try {
            reader = new BufferedReader(new InputStreamReader(
                    new FileInputStream(file), "utf-8"));
            String line;
            while ((line = reader.readLine()) != null) {
                list.add(line);
            }
        } catch (IOException e) {
            throw new ArgumentParserException(String.format(
                    "Could not read arguments from file '%s'"file), ethis);
        }
        String newargs[] = new String[list.size() + oldargs.length - offset];
        list.toArray(newargs);
        System.arraycopy(oldargsoffsetnewargslist.size(), oldargs.length
                - offset);
        return newargs;
    }
    private void checkRequiredArgument(Set<ArgumentImplusedint posargIndex)
            throws ArgumentParserException {
        for (ArgumentImpl arg : ) {
            if (arg.isRequired() && !used.contains(arg)) {
                throw new ArgumentParserException(String.format(
                        "argument %s is required"arg.textualName()), this);
            }
        }
        if (.size() > posargIndex) {
            throw new ArgumentParserException("too few arguments"this);
        }
    }
    private void populateDefaults(Map<StringObjectopts) {
        for (ArgumentImpl arg : ) {
            if (arg.getDefaultControl() != .) {
                opts.put(arg.getDest(), arg.getDefault());
            }
        }
        for (ArgumentImpl arg : ) {
            if (arg.getDefaultControl() != .) {
                opts.put(arg.getDest(), arg.getDefault());
            }
        }
        for (Map.Entry<StringObjectentry : .entrySet()) {
            opts.put(entry.getKey(), entry.getValue());
        }
    }
    public String getProg() {
        return ;
    }
    @Override
    public void printVersion() {
        printVersion(new PrintWriter(.));
    }
    @Override
    public void printVersion(PrintWriter writer) {
        writer.format("%s\n");
        writer.flush();
    }
    @Override
    public String formatVersion() {
        return ;
    }
    @Override
    public void handleError(ArgumentParserException e) {
        if (e.getParser() != this) {
            e.getParser().handleError(e);
            return;
        }
        PrintWriter writer = new PrintWriter(.);
        printUsage(writer);
        writer.format("%s: error: %s\n"e.getMessage());
        if (e instanceof UnrecognizedArgumentException) {
            String argument = ex.getArgument();
            if (.match(argument)) {
                String flagBody = .removePrefix(argument);
                if (flagBody.length() >= 2) {
                    printFlagCandidates(flagBodywriter);
                }
            }
        } else if (e instanceof UnrecognizedCommandException) {
            String command = ex.getCommand();
            printCommandCandidates(commandwriter);
        }
        writer.flush();
    }

    
Calculates Damerau–Levenshtein distance between string a and b with given costs.

Parameters:
a String
b String
swap Cost to swap 2 adjacent characters.
sub Cost to substitute character.
add Cost to add character.
del Cost to delete character.
Returns:
Damerau–Levenshtein distance between a and b
    private int levenshtein(String aString bint swapint subint add,
            int del) {
        int alen = a.length();
        int blen = b.length();
        int dp[][] = new int[3][blen + 1];
        for (int i = 0; i <= blen; ++i) {
            dp[1][i] = i;
        }
        for (int i = 1; i <= alen; ++i) {
            dp[0][0] = i;
            for (int j = 1; j <= blen; ++j) {
                dp[0][j] = dp[1][j - 1]
                        + (a.charAt(i - 1) == b.charAt(j - 1) ? 0 : sub);
                if (i >= 2 && j >= 2 && a.charAt(i - 1) != b.charAt(j - 1)
                        && a.charAt(i - 2) == b.charAt(j - 1)
                        && a.charAt(i - 1) == b.charAt(j - 2)) {
                    dp[0][j] = Math.min(dp[0][j], dp[2][j - 2] + swap);
                }
                dp[0][j] = Math.min(dp[0][j],
                        Math.min(dp[1][j] + deldp[0][j - 1] + add));
            }
            int temp[] = dp[2];
            dp[2] = dp[1];
            dp[1] = dp[0];
            dp[0] = temp;
        }
        return dp[1][blen];
    }
    private static class SubjectBody {
        public String subject;
        public String body;
        public SubjectBody(String subjectString body) {
            this. = subject;
            this. = body;
        }
    }
    private static class Candidate implements Comparable<Candidate> {
        public int similarity;
        public String subject;
        public Candidate(int similarityString subject) {
            this. = similarity;
            this. = subject;
        }
        @Override
        public int compareTo(Candidate rhs) {
            if ( < rhs.similarity) {
                return -1;
            } else if ( == rhs.similarity) {
                return .compareTo(rhs.subject);
            } else {
                return 1;
            }
        }
    }
    private void printFlagCandidates(String flagBodyPrintWriter writer) {
        List<SubjectBodysubjects = new ArrayList<SubjectBody>();
        for (ArgumentImpl arg : ) {
            String flags[] = arg.getFlags();
            for (int i = 0, len = flags.lengthi < len; ++i) {
                String body = .removePrefix(flags[i]);
                if (body.length() <= 1) {
                    continue;
                }
                subjects.add(new SubjectBody(flags[i], body));
            }
        }
        printCandidates(flagBodysubjectswriter);
    }
    private void printCommandCandidates(String commandPrintWriter writer) {
        List<SubjectBodysubjects = new ArrayList<SubjectBody>();
        for (String com : .getCommands()) {
            subjects.add(new SubjectBody(comcom));
        }
        printCandidates(commandsubjectswriter);
    }

    
Prints most similar subjects in subjects to body. Similarity is calculated between body and each ArgumentParserImpl.SubjectBody.body in subjects.

Parameters:
body String to compare.
subjects Target to be compared.
writer Output
    private void printCandidates(String bodyList<SubjectBodysubjects,
            PrintWriter writer) {
        List<Candidatecandidates = new ArrayList<Candidate>();
        for (SubjectBody sub : subjects) {
            if (sub.body.startsWith(body)) {
                candidates.add(new Candidate(0, sub.subject));
                continue;
            } else {
                // Cost values were borrowed from git, help.c
                candidates.add(new Candidate(levenshtein(bodysub.body, 0, 2,
                        1, 4), sub.subject));
            }
        }
        if (candidates.isEmpty()) {
            return;
        }
        Collections.sort(candidates);
        int threshold = candidates.get(0).;
        // Magic number 7 was borrowed from git, help.c
        if (threshold >= 7) {
            return;
        }
        writer.write("\nDid you mean:\n");
        for (Candidate cand : candidates) {
            if (cand.similarity > threshold) {
                break;
            }
            writer.format("\t%s\n"cand.subject);
        }
    }
    public String getCommand() {
        return ;
    }
        return ;
    }
    public String getPrefixChars() {
        return .getPrefixChars();
    }
    public String getFromFilePrefixChars() {
        return  == null ? null : 
                .getPrefixChars();
    }