You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by ji...@apache.org on 2016/12/06 16:43:26 UTC

[6/7] geode git commit: GEODE-1912: use Spring shell's parser and delete our own parsing code

http://git-wip-us.apache.org/repos/asf/geode/blob/ce9e138c/geode-core/src/main/java/org/apache/geode/management/internal/cli/GfshParser.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/GfshParser.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/GfshParser.java
index a1d03e4..4468b9c 100755
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/GfshParser.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/GfshParser.java
@@ -15,49 +15,24 @@
 package org.apache.geode.management.internal.cli;
 
 import org.apache.commons.lang.StringUtils;
-import org.apache.geode.management.cli.CommandProcessingException;
-import org.apache.geode.management.internal.cli.exceptions.CliCommandMultiModeOptionException;
-import org.apache.geode.management.internal.cli.exceptions.CliCommandOptionException;
-import org.apache.geode.management.internal.cli.exceptions.CliException;
-import org.apache.geode.management.internal.cli.exceptions.ExceptionHandler;
-import org.apache.geode.management.internal.cli.help.format.NewHelp;
+import org.apache.geode.management.internal.cli.help.format.HelpBlock;
 import org.apache.geode.management.internal.cli.help.utils.HelpUtils;
-import org.apache.geode.management.internal.cli.i18n.CliStrings;
-import org.apache.geode.management.internal.cli.modes.CommandModes;
-import org.apache.geode.management.internal.cli.modes.CommandModes.CommandMode;
-import org.apache.geode.management.internal.cli.parser.Argument;
-import org.apache.geode.management.internal.cli.parser.AvailabilityTarget;
-import org.apache.geode.management.internal.cli.parser.CommandTarget;
-import org.apache.geode.management.internal.cli.parser.GfshMethodTarget;
-import org.apache.geode.management.internal.cli.parser.MethodParameter;
-import org.apache.geode.management.internal.cli.parser.Option;
-import org.apache.geode.management.internal.cli.parser.OptionSet;
-import org.apache.geode.management.internal.cli.parser.Parameter;
-import org.apache.geode.management.internal.cli.parser.ParserUtils;
-import org.apache.geode.management.internal.cli.parser.SyntaxConstants;
-import org.apache.geode.management.internal.cli.parser.preprocessor.PreprocessorUtils;
-import org.apache.geode.management.internal.cli.parser.preprocessor.TrimmedInput;
-import org.apache.geode.management.internal.cli.shell.Gfsh;
-import org.apache.geode.management.internal.cli.util.CLIConsoleBufferUtil;
-import org.springframework.shell.core.AbstractShell;
+import org.springframework.shell.converters.ArrayConverter;
+import org.springframework.shell.core.CommandMarker;
 import org.springframework.shell.core.Completion;
 import org.springframework.shell.core.Converter;
-import org.springframework.shell.core.MethodTarget;
 import org.springframework.shell.core.Parser;
+import org.springframework.shell.core.SimpleParser;
+import org.springframework.shell.core.annotation.CliCommand;
 import org.springframework.shell.event.ParseResult;
 
-import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
 import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.LinkedHashMap;
+import java.util.HashSet;
 import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeMap;
-import java.util.TreeSet;
+import java.util.Properties;
 import java.util.logging.Logger;
+import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
 /**
@@ -65,1469 +40,246 @@ import java.util.regex.Pattern;
  *
  * @since GemFire 7.0
  */
-public class GfshParser implements Parser {
+public class GfshParser extends SimpleParser {
 
   public static final String LINE_SEPARATOR = System.getProperty("line.separator");
-
-  // Constants used while finding command targets for help
-  private final static Short EXACT_TARGET = (short) 0;
-  private final static Short MATCHING_TARGETS = (short) 1;
+  public static final String OPTION_VALUE_SPECIFIER = "=";
+  public static final String VALUE_SEPARATOR = ",";
+  public static final String ARGUMENT_SEPARATOR = "?";
+  public static final String OPTION_SEPARATOR = " ";
+  public static final String SHORT_OPTION_SPECIFIER = "-";
+  public static final String LONG_OPTION_SPECIFIER = "--";
+  public static final String COMMAND_DELIMITER = ";";
+  public static final String CONTINUATION_CHARACTER = "\\";
 
   // Make use of LogWrapper
   private static final LogWrapper logWrapper = LogWrapper.getInstance();
 
-  // private CliStringResourceBundle cliStringBundle;
-  private CommandManager commandManager;
-
+  // pattern used to split the user input with whitespaces except those in quotes (single or double)
+  private static Pattern PATTERN =
+      Pattern.compile("([^\\s\"]*)\"([^\"]*)\"|([^\\s']*)'([^']*)'|[^\\s]+");
   /**
    * Used for warning messages
    */
-  // TODO Investigating using GemFire logging.
-  private final Logger consoleLogger;
-
-  public GfshParser(CommandManager commandManager) {
-    // cliStringBundle = new
-    // CliStringResourceBundle("org/apache/geode/management/internal/cli/i18n/CliStringResourceBundle");
-    this.commandManager = commandManager;
-    if (CliUtil.isGfshVM()) {
-      consoleLogger = Logger.getLogger(this.getClass().getCanonicalName());
-    } else {
-      consoleLogger = logWrapper.getLogger();
-    }
-  }
-
-  // ///////////////// Parser interface Methods Start //////////////////////////
-  // ////////////////////// Implemented Methods ////////////////////////////////
-
-  /**
-   * Populates a list of completion candidates. See {@link Parser#complete(String, int, List)} for
-   * details.
-   *
-   * @param buffer
-   * @param cursor
-   * @param completionCandidates
-   *
-   * @return new cursor position
-   */
-  public int complete(String buffer, int cursor, List<String> completionCandidates) {
-    final List<Completion> candidates = new ArrayList<Completion>();
-    final int result = completeAdvanced(buffer, cursor, candidates);
-    for (final Completion completion : candidates) {
-      completionCandidates.add(completion.getValue());
-    }
-    return result;
-  }
-
-  /**
-   * Populates a list of completion candidates.
-   *
-   * @param buffer
-   * @param cursor
-   * @param completionCandidates
-   *
-   * @return new cursor position
-   */
-  public int completeAdvanced(String buffer, int cursor, List<Completion> completionCandidates) {
-    // Currently, support for auto-completion
-    // in between is not supported, only if the
-    // cursor is at the end
-
-    if (cursor <= buffer.length() - 1
-        && !PreprocessorUtils.containsOnlyWhiteSpaces(buffer.substring(cursor))
-        || (ParserUtils.contains(buffer, SyntaxConstants.COMMAND_DELIMITER))) {
-      return cursor;
-    }
-
-    int desiredCursorPosition = 0;
-
-    try {
-      TrimmedInput simpleTrim = PreprocessorUtils.simpleTrim(buffer);
-      desiredCursorPosition += simpleTrim.getNoOfSpacesRemoved();
-      List<CommandTarget> targets = locateTargets(simpleTrim.getString());
-      if (targets.size() > 1) {
-        String padding =
-            desiredCursorPosition != 0 ? ParserUtils.getPadding(desiredCursorPosition) : "";
-        // This means that what the user has entered matches
-        // the beginning of many commands
-        for (CommandTarget commandTarget : targets) {
-          completionCandidates
-              .add(new Completion(padding + commandTarget.getGfshMethodTarget().getKey()));
-        }
-      } else {
-        if (targets.size() == 1) {
-          CommandTarget commandTarget = targets.get(0);
-          // Only one command matches but we still have to check
-          // whether the user has properly entered it or not
-          if (simpleTrim.getString().length() >= commandTarget.getGfshMethodTarget().getKey()
-              .length()) {
-            /* int position = */
-            return completeParameters(commandTarget,
-                desiredCursorPosition + commandTarget.getGfshMethodTarget().getKey().length(),
-                commandTarget.getGfshMethodTarget().getRemainingBuffer(), cursor,
-                completionCandidates);
-            /*
-             * updateCompletionCandidates(completionCandidates, buffer, position); return 0;
-             */
-          } else {
-            String padding =
-                desiredCursorPosition != 0 ? ParserUtils.getPadding(desiredCursorPosition) : "";
-            // User has still not entered the command name properly,
-            // we need to populate the completionCandidates list
-            completionCandidates
-                .add(new Completion(padding + commandTarget.getGfshMethodTarget().getKey()));
-          }
-        }
-      }
-
-    } catch (IllegalArgumentException e) {
-      logWrapper.warning(CliUtil.stackTraceAsString(e));
-    } catch (IllegalAccessException e) {
-      logWrapper.warning(CliUtil.stackTraceAsString(e));
-    } catch (InvocationTargetException e) {
-      logWrapper.warning(CliUtil.stackTraceAsString(e));
-    } catch (RuntimeException e) {
-      logWrapper.warning(CliUtil.stackTraceAsString(e));
-    }
-    // Returning 0 for exceptions too. This will break the completors' loop in
-    // jline.ConsoleReader.complete() & will return false
-    return 0;
-  }
-
-  @SuppressWarnings("unused")
-  private void updateCompletionCandidates(List<Completion> completionCandidates, String buffer,
-      int position) {
-    List<Completion> temp = new ArrayList<Completion>();
-    while (completionCandidates.size() > 0) {
-      temp.add(completionCandidates.remove(0));
-    }
-    for (Completion completion : temp) {
-      completionCandidates.add(new Completion(buffer.substring(0, position) + completion.getValue(),
-          completion.getFormattedValue(), completion.getHeading(), completion.getOrder()));
-    }
-  }
-
-  private int completeParameters(CommandTarget commandTarget, int cursorStart,
-      String remainingBuffer, int cursor, List<Completion> completionCandidates) {
-    int desiredCursorPosition = cursorStart;
-    // Factor for remainingBuffer
-    boolean sizeReduced = false;
-    // We need to work modify the flow according to the CliException
-    // generated. For that we will need a reference to the Exception
-    // CliException reference
-    CliCommandOptionException coe = null;
-    OptionSet userOptionSet = null;
-    try {
-      // We need to remove the space which separates command from the
-      // parameters
-      if (remainingBuffer.length() > 0) {
-        remainingBuffer = remainingBuffer.substring(1);
-        sizeReduced = true;
-      }
-
-      userOptionSet = commandTarget.getOptionParser().parse(remainingBuffer);
-    } catch (CliException ce) {
-      if (ce instanceof CliCommandOptionException) {
-        coe = (CliCommandOptionException) ce;
-        coe.setCommandTarget(commandTarget);
-        userOptionSet = coe.getOptionSet();
-      }
-    }
-
-    // Contains mandatory options which have not been specified
-    List<Option> mandatoryOptions = new ArrayList<Option>();
-    // Contains non-mandatory options which have not been specified
-    List<Option> unspecifiedOptions = new ArrayList<Option>();
-    // First we need a list to create a list of all the options specified
-    Map<String, Option> optionsPresentMap = new LinkedHashMap<String, Option>();
-    if (userOptionSet != null) {
-
-      // Start with the arguments
-      String argumentSeparator = " ";
-      for (Argument argument : commandTarget.getOptionParser().getArguments()) {
-        if (completionCandidates.size() == 0) {
-          boolean warning = false;
-          if (userOptionSet.hasArgument(argument)) {
-            boolean incrementCursor = true;
-            // Here we need to get all the possible values for this
-            // argument
-            if (getAllPossibleValuesForParameter(completionCandidates, argument,
-                userOptionSet.getValue(argument), commandTarget.getGfshMethodTarget())) {
-              // Check whether the list of completionCandidates is
-              // not empty
-              if (completionCandidates.size() > 0) {
-                // First check whether the argument value
-                // matches with any
-                // of the completionCandidates
-                if (perfectMatch(completionCandidates, userOptionSet.getValue(argument))) {
-                  // Remove all the completionCandidates
-                  completionCandidates.clear();
-                } else {
-                  modifyCompletionCandidates(completionCandidates, argumentSeparator,
-                      userOptionSet.getValue(argument));
-                  // For this case also we should not
-                  // increment the
-                  // cursorPosition
-                  if (completionCandidates.size() > 0) {
-                    incrementCursor = false;
-                  }
-                }
-              }
-            } else {
-              // The completion candidates should be cleared if the Converter has
-              // populated it with some values
-              completionCandidates.clear();
-            }
-            if (incrementCursor) {
-              desiredCursorPosition +=
-                  userOptionSet.getValue(argument).length() + argumentSeparator.length();
-            }
-          } else {
-            if (argument.isRequired()) {
-              // Here the converter will come in handy
-              // to get suggestion for arguments
-              if (getAllPossibleValuesForParameter(completionCandidates, argument, null,
-                  commandTarget.getGfshMethodTarget())) {
-                if (completionCandidates.size() == 0) {
-                  // Enable warning if nothing is returned
-                  warning = true;
-                }
-              } else {
-                // The completion candidates should be cleared if the Converter has
-                // populated it with some values
-                completionCandidates.clear();
-                warning = true;
-              }
-            } else {
-              boolean checkForPossibleValues = true;
-              // This means that the argument is not mandatory
-              // Now here we need to check whether user wants to
-              // enter an option.
-              if (endsWithOptionSpecifiers(userOptionSet.getUserInput())
-                  || hasOptionSpecified(userOptionSet.getUserInput())) {
-                // This means options have started, and we
-                // cannot have arguments after options
-                // So, we just skip checking for possible
-                // values
-                checkForPossibleValues = false;
-              }
-              // Just try getting the PossibleValues without
-              // aiming
-              if (checkForPossibleValues) {
-                getAllPossibleValuesForParameter(completionCandidates, argument, null,
-                    commandTarget.getGfshMethodTarget());
-              }
-            }
-            if (completionCandidates.size() > 0) {
-              modifyCompletionCandidates(completionCandidates, argumentSeparator, (String[]) null);
-            }
-          }
-          if (warning) {
-            String argMessage = argument.getArgumentName()
-                + ((argument.getHelp() != null && !argument.getHelp().equals(""))
-                    ? ": " + argument.getHelp() : "");
-            logWarning(
-                CliStrings.format(CliStrings.GFSHPARSER__MSG__REQUIRED_ARGUMENT_0, argMessage));
-            return desiredCursorPosition + userOptionSet.getNoOfSpacesRemoved();
-          }
-        }
-        argumentSeparator = SyntaxConstants.ARGUMENT_SEPARATOR;
-      }
-      if (completionCandidates.size() > 0) {
-        return desiredCursorPosition + userOptionSet.getNoOfSpacesRemoved();
-      }
-
-      // Now process options
-
-      boolean warningValueRequired = false;
-      Option warningOption = null;
-
-
-
-      for (Option option : commandTarget.getOptionParser().getOptions()) {
-        if (userOptionSet.hasOption(option)) {
-          // We are supporting option synonyms,
-          // so we need to check that here
-          for (String string : userOptionSet.getSplit()) {
-            if (string.startsWith(SyntaxConstants.LONG_OPTION_SPECIFIER)) {
-              // Remove option prefix
-              string = StringUtils.removeStart(string, SyntaxConstants.LONG_OPTION_SPECIFIER);
-              // Remove value specifier
-              string = StringUtils.removeEnd(string, SyntaxConstants.OPTION_VALUE_SPECIFIER);
-              if (!string.equals("")) {
-                if (option.getLongOption().equals(string)) {
-                  // This means that user has entered the whole option and
-                  // Increment desiredCursorPostion by the length of the
-                  // option and the option specifier, including space
-                  desiredCursorPosition +=
-                      /* space */1 + SyntaxConstants.LONG_OPTION_SPECIFIER.length()
-                          + option.getLongOption().length();
-                  break;
-
-                } else {
-                  // This is only possible if the user has
-                  // entered one of the synonyms of the options
-                  // which wasn't displayed initially
-                  for (String optionSynonym : option.getSynonyms()) {
-                    if (optionSynonym.equals(string)) {
-                      // This means that what the user has
-                      // entered is actually a
-                      // synonym for the option
-                      desiredCursorPosition += /* space */1
-                          + SyntaxConstants.LONG_OPTION_SPECIFIER.length() + optionSynonym.length();
-                      break;
-                    }
-                  }
-                }
-              }
-            }
-          }
-
-          optionsPresentMap.put(option.getLongOption(), option);
-
-          // For option value
-
-          if (userOptionSet.hasValue(option)) {
-            String value = userOptionSet.getValue(option);
-            boolean valueActuallySpecified = false;
-
-            String valueSeparator = SyntaxConstants.VALUE_SEPARATOR;
-            if (option.getValueSeparator() != null) {
-              valueSeparator = option.getValueSeparator();
-            }
-
-            // JOpt doesn't maintain trailing comma (separator), hence reading it from buffer.
-            boolean bufferEndsWithValueSeparator = remainingBuffer.endsWith(valueSeparator);
-            // Check whether the value assigned to the option is
-            // actually part of the split array or has been
-            // assigned using the specifiedDefaultValue attribute
-
-            // userOptionElement can be option name or value of that option.
-            // E.g. "--opt=val" has elements "opt" & "val"
-            for (String userOptionElement : userOptionSet.getSplit()) {
-              if (userOptionElement.equals(value)
-                  || (userOptionElement).equals(value + valueSeparator)) {
-                valueActuallySpecified = true;
-              }
-            }
-            if (!valueActuallySpecified) {
-              continue;
-            }
-            boolean incrementCursor = true;
-            boolean considerLastValue = false;
-            int lengthToBeAdded = 0;
-            int lastIndexOf = 0;
-
-            // This should only be invoked if we don't have any
-            // completionCandidates beforeHand
-            if (completionCandidates.size() == 0) {
-              // Here also we might need to invoke converter to
-              // get values apt for the option
-              if (!endsWithOptionSpecifiers(userOptionSet.getUserInput())
-                  && getAllPossibleValuesForParameter(completionCandidates, option, value,
-                      commandTarget.getGfshMethodTarget())) {
-
-                // If the value returned by getAllPossibleValues
-                // is the same as that entered by the
-                // user we need to remove it from the
-                // completionCandidates and move forward
-
-                String prefix = "";
-                String[] split = ParserUtils.splitValues(value, valueSeparator);
-
-                if (completionCandidates.size() > 0) {
-                  if (PreprocessorUtils.isSyntaxValid(value) && bufferEndsWithValueSeparator) {
-                    // This means that the user wants to
-                    // enter more values,
-                    prefix = valueSeparator;
-                  } else if (perfectMatch(completionCandidates, split)) {
-                    // If the user does not want to enter
-                    // more values, and it matches one
-                    // of the values then we do not
-                    // need to suggest anything for
-                    // this option
-                    completionCandidates.clear();
-                    considerLastValue = true;
-                  } else if (ParserUtils.contains(value, valueSeparator)) {
-                    prefix = valueSeparator;
-                  } else {
-                    incrementCursor = false;
-                    if (value.startsWith(" ")) {
-                      prefix = "  ";
-                    } else if (value.startsWith("\n")) {
-                      prefix = "\n";
-                    } else {
-                      prefix = SyntaxConstants.OPTION_VALUE_SPECIFIER;
-                    }
-                  }
-                }
-                modifyCompletionCandidates(completionCandidates, prefix,
-                    bufferEndsWithValueSeparator, split);
-                if (completionCandidates.size() == 0) {
-                  incrementCursor = true;
-                  considerLastValue = true;
-                }
-              } else {
-                // The completion candidates should be cleared if the Converter has
-                // populated it with some values
-                completionCandidates.clear();
-                considerLastValue = true;
-              }
-            } else {
-              // Make everything true
-              considerLastValue = true;
-            }
-            // FIX for: 46265
-            // if bufferEndsWithValueSeparator, append a valueSeparator to get the real lastIndexOd
-            // e.g. Let's say remainingBuffer is: cmd --opt1=val1,val2,
-            // value would be: cmd --opt1=val1,val2 ---> not there's no comma in the end.
-            // This doesn't give us the real last index of valueSeparator, hence add extra
-            // valueSeparator.
-            lastIndexOf = ParserUtils.lastIndexOf(
-                bufferEndsWithValueSeparator ? value + valueSeparator : value, valueSeparator);
-            lengthToBeAdded =
-                value.substring(0, (lastIndexOf > 0 ? lastIndexOf : value.length())).length();
-            // Increment desiredCursorPosition
-            if (incrementCursor) {
-              desiredCursorPosition +=
-                  /* value specifier length */SyntaxConstants.OPTION_VALUE_SPECIFIER.length()
-                      + lengthToBeAdded
-                      + ((considerLastValue) ? value.length() - lengthToBeAdded : 0);
-              if (value.endsWith(" ") && considerLastValue) {
-                desiredCursorPosition--;
-              }
-            }
-            if (completionCandidates.size() == 0) {
-              if (!PreprocessorUtils.isSyntaxValid(value)) {
-                return desiredCursorPosition + userOptionSet.getNoOfSpacesRemoved();
-              } else {
-                // Check whether the value ends with
-                // VALUE_SEPARATOR,
-                // if yes then we need to return
-                if (value.endsWith(valueSeparator)) {
-                  return desiredCursorPosition + userOptionSet.getNoOfSpacesRemoved();
-                }
-              }
-            }
-          } else {
-            // Here the converter is useful to invoke
-            // auto-suggestion, get Values from Converter
-            if (completionCandidates.size() == 0) {
-              if (getAllPossibleValuesForParameter(completionCandidates, option, null,
-                  commandTarget.getGfshMethodTarget())) {
-                if (completionCandidates.size() == 0) {
-                  warningValueRequired = true;
-                } else {
-                  modifyCompletionCandidates(completionCandidates,
-                      SyntaxConstants.OPTION_VALUE_SPECIFIER, new String[] {null});
-                }
-              } else {
-                // The completion candidates should be cleared if the Converter
-                // has populated it with some values
-                completionCandidates.clear();
-                warningValueRequired = true;
-              }
-            }
-          }
-        } else {
-
-          // As we have reached here, the OptionParser was not able to
-          // detect anything which proves that the option is present
-          // So, we check with what the user provided and add only
-          // that to the list of options to prompt for
+  private Logger consoleLogger;
 
-          for (String userOptString : userOptionSet.getSplit()) {
-            // Now to determine whether what the user specified was
-            // an option, we need to check whether it starts
-            // with an option specifier
-            if (userOptString.startsWith(SyntaxConstants.LONG_OPTION_SPECIFIER)) {
-              // Now remove the option specifier part
-              userOptString =
-                  StringUtils.removeStart(userOptString, SyntaxConstants.LONG_OPTION_SPECIFIER);
-              if (option.getLongOption().startsWith(userOptString) && !userOptString.equals("")
-                  && !option.getLongOption().equals(userOptString)
-                  && !optionsPresentMap.containsKey(userOptString)) {
+  private static GfshParser INSTANCE = null;
+  private CommandManager commandManager = null;
 
-                completionCandidates.add(new Completion(
-                    " " + SyntaxConstants.LONG_OPTION_SPECIFIER + option.getLongOption(),
-                    option.getLongOption(), "", 0));
-              } else {
-                for (String optionSynonym : option.getSynonyms()) {
-                  if (optionSynonym.startsWith(userOptString) && !userOptString.equals("")
-                      && !optionSynonym.equals(userOptString)) {
-                    completionCandidates.add(
-                        new Completion(" " + SyntaxConstants.LONG_OPTION_SPECIFIER + optionSynonym,
-                            optionSynonym, "", 0));
-                    break;
-                  }
-                }
-              }
-            }
-          }
-
-          if (completionCandidates.size() == 0) {
-            if (option.isRequired()) {
-              mandatoryOptions.add(option);
-            } else {
-              unspecifiedOptions.add(option);
-            }
-          }
-        }
-        if (warningValueRequired/* || warningMultipleValuesNotSupported */) {
-          warningOption = option;
-          warningValueRequired = false;
-        }
-      }
-
-      // Display warning if something not specified
-      if (warningOption != null) {
-        String optionMsg = warningOption.getLongOption()
-            + ((warningOption.getHelp() != null && !warningOption.getHelp().equals(""))
-                ? ": " + warningOption.getHelp() : "");
-        logWarning(
-            CliStrings.format(CliStrings.GFSHPARSER__MSG__VALUE_REQUIRED_FOR_OPTION_0, optionMsg));
-
-        desiredCursorPosition += userOptionSet.getNoOfSpacesRemoved();
-        completionCandidates
-            .add(new Completion(SyntaxConstants.OPTION_VALUE_SPECIFIER, "", null, 0));
-        return desiredCursorPosition;
-      }
-
-    }
-
-    // Calculate the cursor position
-    int newCursor = desiredCursorPosition
-        + ((userOptionSet != null) ? userOptionSet.getNoOfSpacesRemoved() : 0);
-
-    String subString = remainingBuffer;
-    if (newCursor != cursorStart) {
-      int sizedReducedAdj = sizeReduced ? -1 : 0;
-      int begin = newCursor + sizedReducedAdj - cursorStart;
-      subString = remainingBuffer.substring(begin).trim();
-    }
-
-    // Exception handling
-    if (coe != null // hasException
-        && newCursor < cursor // newCursorIsEarlierThanCursor
-        && completionCandidates.size() == 0 // zeroCompletionCandidates
-        && !(PreprocessorUtils.containsOnlyWhiteSpaces(subString) // onlyHasWhiteSpaces
-            || ((subString.endsWith(SyntaxConstants.LONG_OPTION_SPECIFIER)
-                && subString.startsWith(SyntaxConstants.LONG_OPTION_SPECIFIER)) // isHypenHyphen
-                || (subString.startsWith(SyntaxConstants.SHORT_OPTION_SPECIFIER)
-                    && subString.endsWith(SyntaxConstants.SHORT_OPTION_SPECIFIER))))) { // isHyphen
-
-      ExceptionHandler.handleException(coe);
-      return cursor;
-    }
-
-    // If nothing has been specified for auto-completion then we need to suggest options
-    if (completionCandidates.size() == 0) {
-      if (mandatoryOptions.size() > 0) {
-
-        for (Option option : mandatoryOptions) {
-          completionCandidates.add(
-              new Completion(" " + SyntaxConstants.LONG_OPTION_SPECIFIER + option.getLongOption(),
-                  option.getLongOption(), "", 0));
-        }
-      } else {
-        // As all the mandatory options have been specified we can prompt the
-        // user for optional options.
-        unspecifiedOptions =
-            getUnspecifiedOptionsWithMode(unspecifiedOptions, commandTarget, optionsPresentMap);
-        for (Option option : unspecifiedOptions) {
-          completionCandidates.add(
-              new Completion(" " + SyntaxConstants.LONG_OPTION_SPECIFIER + option.getLongOption(),
-                  option.getLongOption(), "", 0));
-        }
-      }
-    }
-    return newCursor;
-  }
-
-  private List<Option> getUnspecifiedOptionsWithMode(List<Option> unspecifiedOptions,
-      CommandTarget commandTarget, Map<String, Option> optionsPresentMap) {
-
-    Collection<CommandMode> cmodes =
-        CommandModes.getInstance().getCommandModes(commandTarget.getCommandName());
-    if (cmodes != null) {
-      List<Option> filteredList = new ArrayList<Option>();
-
-      // Populate with default options
-      CommandMode defaultMode = CommandModes.getInstance()
-          .getCommandMode(commandTarget.getCommandName(), CommandModes.DEFAULT_MODE);
-      for (String opt : defaultMode.options) {
-        for (Option option : unspecifiedOptions) {
-          if (option.getLongOption().equals(opt)) {
-            filteredList.add(option);
-          }
-        }
-      }
-
-      // Now add options only for detected command mode
-      boolean leadOptionFound = false;
-      for (CommandMode cmd : cmodes) {
-        if (optionsPresentMap.containsKey(cmd.leadOption)) {
-          leadOptionFound = true;
-          for (String opt : cmd.options) {
-            if (!optionsPresentMap.containsKey(opt)) {
-              for (Option option : unspecifiedOptions) {
-                if (option.getLongOption().equals(opt)) {
-                  filteredList.add(option);
-                }
-              }
-            }
-          }
-          break;
-        }
-      }
-
-      if (leadOptionFound) {
-        return filteredList;
-      }
-
-      if (optionsPresentMap.isEmpty()) {
-        // Here return only lead-option of the command-modes
-        filteredList.clear();
-        for (CommandMode cmd2 : cmodes) {
-          for (Option option2 : unspecifiedOptions) {
-            if (option2.getLongOption().equals(cmd2.leadOption)) {
-              filteredList.add(option2);
-            }
-          }
-        }
-        return filteredList;
-      }
-      return unspecifiedOptions;
-    } else {
-      return unspecifiedOptions;
-    }
+  public static GfshParser getInstance() {
+    return getInstance(null);
   }
 
-  private void checkOptionSetForValidCommandModes(OptionSet userOptionSet,
-      CommandTarget commandTarget) throws CliCommandMultiModeOptionException {
-    CommandModes modes = CommandModes.getInstance();
-    Collection<CommandMode> cmodes = modes.getCommandModes(commandTarget.getCommandName());
-
-    if (cmodes != null) {
-      CommandMode defaultMode =
-          modes.getCommandMode(commandTarget.getCommandName(), CommandModes.DEFAULT_MODE);
-      Map<String, Option> userOptions = new HashMap<String, Option>();
-      Map<String, CommandMode> loToModeMap = new HashMap<String, CommandMode>();
-      for (Option option : commandTarget.getOptionParser().getOptions()) {
-        if (userOptionSet.hasOption(option)) {
-          userOptions.put(option.getLongOption(), option);
-        }
-      }
-
-      List<String> leadOptionList = new ArrayList<String>();
-      for (CommandMode cmd : cmodes) {
-        loToModeMap.put(cmd.leadOption, cmd);
-        if (userOptions.containsKey(cmd.leadOption)) {
-          leadOptionList.add(cmd.leadOption);
-        }
-
-        if (leadOptionList.size() > 1) {
-
-          StringBuilder sb = new StringBuilder();
-          for (String leadOption : leadOptionList) {
-            sb.append(loToModeMap.get(leadOption).name).append(",");
-          }
-          throw new CliCommandMultiModeOptionException(commandTarget,
-              userOptions.get(cmd.leadOption), sb.toString(),
-              CliCommandMultiModeOptionException.MULTIPLE_LEAD_OPTIONS);
-        }
-      }
-
-      if (leadOptionList.size() == 1) {
-        CommandMode modeDetected = loToModeMap.get(leadOptionList.get(0));
-        for (Option opt : userOptions.values()) {
-          // Check only for non-default options, default options are allowed with any other mode
-          if (!isDefaultOption(opt.getLongOption(), defaultMode)) {
-            boolean isOptionFromDetectedMode = false;
-            if (modeDetected.options.length > 0) {
-              for (String commandOpt : modeDetected.options) {
-                if (commandOpt.equals(opt.getLongOption())) {
-                  isOptionFromDetectedMode = true;
-                }
-              }
-              if (!isOptionFromDetectedMode) {
-                throw new CliCommandMultiModeOptionException(commandTarget, opt,
-                    opt.getLongOption(),
-                    CliCommandMultiModeOptionException.OPTIONS_FROM_MULTIPLE_MODES);
-              }
-            }
-          }
-        }
-      }
+  public static GfshParser getInstance(Properties cacheProperties) {
+    if (INSTANCE == null) {
+      INSTANCE = new GfshParser(CommandManager.getInstance(cacheProperties));
     }
+    return INSTANCE;
   }
 
-  private boolean isDefaultOption(String longOption, CommandMode commandMode) {
-    for (String str : commandMode.options) {
-      if (longOption.equals(str)) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  private boolean endsWithOptionSpecifiers(String userInput) {
-    userInput = userInput.trim();
-    if (userInput.endsWith(" " + SyntaxConstants.LONG_OPTION_SPECIFIER)
-        || userInput.endsWith(" " + SyntaxConstants.SHORT_OPTION_SPECIFIER)) {
-      return true;
-    } else {
-      return false;
-    }
-  }
-
-  /*
-   * Verifies whether the userInput has any one of the following: --some-opt --s --some-opt=some-val
-   * --something-else
-   */
-  private boolean hasOptionSpecified(String userInput) {
-    userInput = userInput.trim();
-    return Pattern.matches("^(.*)(-+)(\\w+)(.*)$", userInput);
-  }
-
-  private String getSystemProvidedValue(Parameter parameter) {
-    if (parameter.isSystemProvided()) {
-      // TODO fetch from system properties
-      // Assume value is null for now.
-      return null;
+  private GfshParser(CommandManager commandManager) {
+    if (CliUtil.isGfshVM()) {
+      consoleLogger = Logger.getLogger(this.getClass().getCanonicalName());
     } else {
-      return null;
-    }
-  }
-
-  private boolean perfectMatch(List<Completion> completionCandidates, String... argumentValue) {
-    // Here only the last value should match one of the
-    // completionCandidates
-    if (argumentValue.length > 0) {
-      for (Completion completion : completionCandidates) {
-        if (completion.getValue().equals(argumentValue[argumentValue.length - 1])) {
-          return true;
-        }
-      }
+      consoleLogger = logWrapper.getLogger();
     }
-    return false;
-  }
-
-  private void modifyCompletionCandidates(List<Completion> completionCandidates, String prefix,
-      String... existingData) {
-    modifyCompletionCandidates(completionCandidates, prefix, false, existingData);
-  }
 
-  private void modifyCompletionCandidates(List<Completion> completionCandidates, String prefix,
-      boolean endsWithValueSeparator, String... existingData) {
-    List<Completion> temp = new ArrayList<Completion>();
-    while (completionCandidates.size() > 0) {
-      temp.add(completionCandidates.remove(0));
-    }
-    for (Completion completion : temp) {
-      boolean includeCompletion = true;
-      String value = completion.getValue();
-      if (existingData != null) {
-        for (String string : existingData) {
-          if (string != null) {
-            // Check whether that value matches any of the
-            // existingData
-            // If it matches any one of existing data then we do not
-            // need to include it in the list of completion
-            // candidates
-            if (value.equals(string)) {
-              includeCompletion = false;
-            }
-          }
-        }
-        if (includeCompletion) {
-          if (existingData[existingData.length - 1] != null
-              && (!value.startsWith(existingData[existingData.length - 1])
-                  && !endsWithValueSeparator)) {
-            includeCompletion = false;
-          }
-        }
-      }
-      if (includeCompletion) {
-        // Also we only need to check with the last string of
-        // existingData
-        // whether the completion value starts with it.
-        completionCandidates
-            .add(new Completion(prefix + completion.getValue(), completion.getValue(), "", 0));
-      }
-    }
-  }
+    this.commandManager = commandManager;
 
-  @SuppressWarnings({"rawtypes", "unchecked"})
-  private boolean getAllPossibleValuesForParameter(List<Completion> completionCandidates,
-      Parameter parameter, String existingData, GfshMethodTarget gfshMethodTarget) {
-    Converter<?> converter = parameter.getConverter();
-    // Check if any new converter is available which
-    // satisfies the requirements for this argument
-    if (converter == null) {
-      parameter.setConverter(
-          commandManager.getConverter(parameter.getDataType(), parameter.getContext()));
-      converter = parameter.getConverter();
+    for (CommandMarker command : commandManager.getCommandMarkers()) {
+      add(command);
     }
-    // If still we do not have any matching converters, we return
-    if (converter == null) {
-      return false;
-    } else {
-      // Now pass the getAllPossibleValues function of Converter interface
-      // all the required parameters
 
-      // Check whether it is a MultipleValueConverter
-      String valueSeparator = SyntaxConstants.VALUE_SEPARATOR;
-      if (parameter instanceof Option && ((Option) parameter).getValueSeparator() != null) {
-        valueSeparator = ((Option) parameter).getValueSeparator();
-      }
-      if (converter instanceof MultipleValueConverter) {
-        ((MultipleValueConverter) converter).getAllPossibleValues(completionCandidates,
-            parameter.getDataType(), ParserUtils.splitValues(existingData, valueSeparator),
-            parameter.getContext(),
-            new MethodTarget(gfshMethodTarget.getMethod(), gfshMethodTarget.getTarget(),
-                gfshMethodTarget.getRemainingBuffer(), gfshMethodTarget.getKey()));
-      } else {
-        converter.getAllPossibleValues(completionCandidates, parameter.getDataType(), existingData,
-            parameter.getContext(),
-            new MethodTarget(gfshMethodTarget.getMethod(), gfshMethodTarget.getTarget(),
-                gfshMethodTarget.getRemainingBuffer(), gfshMethodTarget.getKey()));
+    List<Converter<?>> converters = commandManager.getConverters();
+    for (Converter<?> converter : converters) {
+      if (converter.getClass().isAssignableFrom(ArrayConverter.class)) {
+        ArrayConverter arrayConverter = (ArrayConverter) converter;
+        arrayConverter.setConverters(new HashSet<>(converters));
       }
-    }
-    if (completionCandidates.size() > 0) {
-      return true;
-    } else {
-      return false;
+      add(converter);
     }
   }
 
-  /**
-   *
-   */
-  public ParseResult parse(String userInput) {
-    GfshParseResult parseResult = null;
-    // First remove the trailing white spaces
-    userInput = StringUtils.stripEnd(userInput, null);
-    if ((ParserUtils.contains(userInput, SyntaxConstants.COMMAND_DELIMITER)
-        && StringUtils.endsWithIgnoreCase(userInput, SyntaxConstants.COMMAND_DELIMITER))) {
-      userInput = StringUtils.removeEnd(userInput, SyntaxConstants.COMMAND_DELIMITER);
-    }
-
-    try {
-      boolean error = false;
-      CliCommandOptionException coe = null;
-      List<CommandTarget> targets = locateTargets(ParserUtils.trimBeginning(userInput), false);
-      if (targets.size() > 1) {
-        if (userInput.length() > 0) {
-          handleCondition(
-              CliStrings.format(
-                  CliStrings.GFSHPARSER__MSG__AMBIGIOUS_COMMAND_0_FOR_ASSISTANCE_USE_1_OR_HINT_HELP,
-                  new Object[] {userInput, AbstractShell.completionKeys}),
-              CommandProcessingException.COMMAND_NAME_AMBIGUOUS, userInput);
-        }
-      } else {
-        if (targets.size() == 1) {
-          OptionSet parse = null;
-          List<MethodParameter> parameters = new ArrayList<MethodParameter>();
-          Map<String, String> paramValMap = new HashMap<String, String>();
-          CommandTarget commandTarget = targets.get(0);
-          GfshMethodTarget gfshMethodTarget = commandTarget.getGfshMethodTarget();
-          preConfigureConverters(commandTarget);
-
-          try {
-            parse = commandTarget.getOptionParser().parse(gfshMethodTarget.getRemainingBuffer());
-          } catch (CliException ce) {
-            if (ce instanceof CliCommandOptionException) {
-              coe = (CliCommandOptionException) ce;
-              coe.setCommandTarget(commandTarget);
-              parse = coe.getOptionSet();
-              error = true;
-            }
-          }
-
-          try {
-            checkOptionSetForValidCommandModes(parse, commandTarget);
-          } catch (CliCommandMultiModeOptionException ce) {
-            error = true;
-            coe = ce;
-          }
-
-          error = processArguments(parse, commandTarget, paramValMap, parameters, error);
-          // TODO: next call throws when space before closing "
-          error = processOptions(parse, commandTarget, paramValMap, parameters, error);
-
-          if (!error) {
-            Object[] methodParameters = new Object[parameters.size()];
-            for (MethodParameter parameter : parameters) {
-              methodParameters[parameter.getParameterNo()] = parameter.getParameter();
-            }
-            parseResult =
-                new GfshParseResult(gfshMethodTarget.getMethod(), gfshMethodTarget.getTarget(),
-                    methodParameters, userInput, commandTarget.getCommandName(), paramValMap);
-          } else {
-            if (coe != null) {
-              logWrapper.fine("Handling exception: " + coe.getMessage());
-              ExceptionHandler.handleException(coe); // TODO: this eats exception that would make it
-                                                     // easier to debug GemfireDataCommandsDUnitTest
-              // ExceptionHandler.handleException() only logs it on console.
-              // When on member, we need to handle this.
-              if (!CliUtil.isGfshVM()) {
-                handleCondition(CliStrings
-                    .format(CliStrings.GFSHPARSER__MSG__INVALID_COMMAND_STRING_0, userInput), coe,
-                    CommandProcessingException.COMMAND_INVALID, userInput);
-              }
-            }
-          }
-
-        } else {
-          String message =
-              CliStrings.format(CliStrings.GFSHPARSER__MSG__COMMAND_0_IS_NOT_VALID, userInput);
-          CommandTarget commandTarget = locateExactMatchingTarget(userInput);
-          if (commandTarget != null) {
-            String commandName = commandTarget.getCommandName();
-            AvailabilityTarget availabilityIndicator = commandTarget.getAvailabilityIndicator();
-            message = CliStrings.format(CliStrings.GFSHPARSER__MSG__0_IS_NOT_AVAILABLE_REASON_1,
-                new Object[] {commandName, availabilityIndicator.getAvailabilityDescription()});
-          }
-          handleCondition(message, CommandProcessingException.COMMAND_INVALID_OR_UNAVAILABLE,
-              userInput);
-        }
-      }
-    } catch (IllegalArgumentException e1) {
-      logWrapper.warning(CliUtil.stackTraceAsString(e1));
-    } catch (IllegalAccessException e1) {
-      logWrapper.warning(CliUtil.stackTraceAsString(e1));
-    } catch (InvocationTargetException e1) {
-      logWrapper.warning(CliUtil.stackTraceAsString(e1));
-    }
-    return parseResult;
+  public static String convertToSimpleParserInput(String userInput) {
+    List<String> inputTokens = splitUserInput(userInput);
+    return getSimpleParserInputFromTokens(inputTokens);
   }
 
-  // Pre-configure the converters so that we can test against them when parsing the command line
-  private void preConfigureConverters(CommandTarget commandTarget) {
-    for (Option option : commandTarget.getOptionParser().getOptions()) {
-      Converter<?> converter = option.getConverter();
-      if (converter == null) {
-        option.setConverter(commandManager.getConverter(option.getDataType(), option.getContext()));
-        converter = option.getConverter();
-      }
+  public static List<String> splitUserInput(String userInput) {
+    // first split with whitespaces except in quotes
+    List<String> splitWithWhiteSpaces = new ArrayList<>();
+    Matcher m = PATTERN.matcher(userInput);
+    while (m.find()) {
+      splitWithWhiteSpaces.add(m.group());
     }
 
-    for (Argument argument : commandTarget.getOptionParser().getArguments()) {
-      Converter<?> converter = argument.getConverter();
-      if (converter == null) {
-        argument.setConverter(
-            commandManager.getConverter(argument.getDataType(), argument.getContext()));
-        converter = argument.getConverter();
-      }
-    }
-  }
-
-  private boolean processOptions(OptionSet parse, CommandTarget commandTarget,
-      Map<String, String> paramValMap, List<MethodParameter> parameters, boolean errorState) {
-    boolean error = errorState;
-    for (Option option : commandTarget.getOptionParser().getOptions()) {
-      String value = null;
-      if (parse.hasOption(option)) {
-        if (parse.hasValue(option)) {
-          value = parse.getValue(option);
-        }
-        if (value == null) {
-          handleCondition(
-              CliStrings.format(CliStrings.GFSHPARSER__MSG__VALUE_REQUIRED_FOR_OPTION_0,
-                  option.getLongOption()),
-              CommandProcessingException.OPTION_VALUE_REQUIRED, option.getLongOption());
-          logWrapper.fine("Value required for Parameter " + option.getLongOption());
-          error = true;
-        }
+    List<String> furtherSplitWithEquals = new ArrayList<>();
+    for (String token : splitWithWhiteSpaces) {
+      // if this token has equal sign, split around the first occurrance of it
+      int indexOfFirstEqual = token.indexOf('=');
+      if (indexOfFirstEqual < 0) {
+        furtherSplitWithEquals.add(token);
       } else {
-        if (option.isRequired()) {
-          handleCondition(
-              CliStrings.format(CliStrings.GFSHPARSER__MSG__COMMAND_OPTION_0_IS_REQUIRED_USE_HELP,
-                  option.getLongOption()),
-              CommandProcessingException.REQUIRED_OPTION_MISSING, option.getLongOption());
-          logWrapper.fine("Required Parameter " + option.getLongOption());
-          error = true;
-        } else {
-          // Try to get the unspecifiedDefaultValue for the
-          // option
-          value = option.getUnspecifiedDefaultValue();
-          if (value == null) {
-            // Now try the system provide value
-            value = getSystemProvidedValue(option);
-          }
+        String left = token.substring(0, indexOfFirstEqual);
+        String right = token.substring(indexOfFirstEqual + 1);
+        if (left.length() > 0) {
+          furtherSplitWithEquals.add(left);
         }
-      }
-
-      String valueSeparator = SyntaxConstants.VALUE_SEPARATOR;
-      if (option.getValueSeparator() != null) {
-        valueSeparator = option.getValueSeparator();
-      }
-
-      Object object = getConversionObject(option.getConverter(), value, option.getDataType(),
-          option.getContext(), valueSeparator);
-      // Check if conversion fails
-      if (value != null && object == null) {
-        handleCondition(
-            CliStrings.format(CliStrings.GFSHPARSER__MSG__VALUE_0_IS_NOT_APPLICABLE_FOR_1,
-                new Object[] {value.trim(), option.getLongOption()}),
-            CommandProcessingException.OPTION_VALUE_INVALID, option.getLongOption() + "=" + value);
-        logWrapper
-            .fine("Value \"" + value.trim() + "\" is not applicable for " + option.getLongOption());
-        error = true;
-      }
-      parameters.add(new MethodParameter(object, option.getParameterNo()));
-      paramValMap.put(option.getLongOption(), value);
-    }
-    return error;
-  }
-
-  private boolean processArguments(OptionSet parse, CommandTarget commandTarget,
-      Map<String, String> paramValMap, List<MethodParameter> parameters, boolean errorState) {
-    boolean error = errorState;
-    for (Argument argument : commandTarget.getOptionParser().getArguments()) {
-      String value = null;
-
-      if (parse.hasArgument(argument)) {
-        value = parse.getValue(argument);
-      } else {
-        if (argument.isRequired()) {
-          handleCondition(
-              CliStrings.format(CliStrings.GFSHPARSER__MSG__COMMAND_ARGUMENT_0_IS_REQUIRED_USE_HELP,
-                  argument.getArgumentName()),
-              CommandProcessingException.REQUIRED_ARGUMENT_MISSING, argument.getArgumentName());
-          logWrapper.fine("Required Argument " + argument.getArgumentName());
-          error = true;
-        } else {
-          // try to get unspecifiedDefaultValue for
-          // the argument
-          value = argument.getUnspecifiedDefaultValue();
-          if (value == null) {
-            // Now try the system provided value
-            value = getSystemProvidedValue(argument);
-          }
+        if (right.length() > 0) {
+          furtherSplitWithEquals.add(right);
         }
-
-      }
-
-      Object conversionObject = getConversionObject(argument.getConverter(), value,
-          argument.getDataType(), argument.getContext(), SyntaxConstants.VALUE_SEPARATOR);
-      if (value != null && conversionObject == null) {
-        handleCondition(
-            CliStrings.format(CliStrings.GFSHPARSER__MSG__VALUE_0_IS_NOT_APPLICABLE_FOR_1,
-                new Object[] {value.trim(), argument.getArgumentName()}),
-            CommandProcessingException.ARGUMENT_INVALID, argument.getArgumentName() + "=" + value);
-        logWrapper.fine("Value '" + value.trim() + "' not applicable for argument: "
-            + argument.getArgumentName());
-        error = true;
-      } else {
-        parameters.add(new MethodParameter(conversionObject, argument.getParameterNo()));
-        paramValMap.put(argument.getArgumentName(), value);
       }
     }
-    return error;
+    return furtherSplitWithEquals;
   }
 
-  @SuppressWarnings({"rawtypes", "unchecked"})
-  private Object getConversionObject(Converter<?> converter, String string, Class<?> dataType,
-      String context, String valueSeparator) {
-
-    try {
-      if (converter != null && converter instanceof MultipleValueConverter) {
-        return ((MultipleValueConverter) converter).convertFromText(
-            ParserUtils.splitValues(((string != null) ? string.trim() : null), valueSeparator),
-            dataType, context);
-      }
-
-      // Remove outer single or double quotes if found
-      boolean hasDoubleQuotes = string.startsWith("\"") && string.endsWith("\"");
-      boolean hasSingleQuotes = string.startsWith("\'") && string.endsWith("\'");
+  private static String getSimpleParserInputFromTokens(List<String> tokens) {
+    // make a copy of the input since we need to do add/remove
+    List<String> inputTokens = new ArrayList<>();
 
-      while (string != null && (hasDoubleQuotes || hasSingleQuotes)) {
-        string = string.substring(1, string.length() - 1);
-        hasDoubleQuotes = string.startsWith("\"") && string.endsWith("\"");
-        hasSingleQuotes = string.startsWith("\'") && string.endsWith("\'");
-      }
-
-      if (converter != null) {
-        return converter.convertFromText((string != null) ? string.trim() : null, dataType,
-            context);
-      }
+    // get the --J arguments from the list of tokens
+    int firstJIndex = -1;
+    List<String> jArguments = new ArrayList<>();
 
-      // TODO consider multiple value case for primitives
-      if (string != null) {
-        if (String.class.isAssignableFrom(dataType)) {
-          return string.trim();
-        } else if (Byte.class.isAssignableFrom(dataType) || byte.class.isAssignableFrom(dataType)) {
-          return Integer.parseInt(string);
-        } else if (Short.class.isAssignableFrom(dataType)
-            || short.class.isAssignableFrom(dataType)) {
-          return Integer.parseInt(string);
-        } else if (Boolean.class.isAssignableFrom(dataType)
-            || boolean.class.isAssignableFrom(dataType)) {
-          return Integer.parseInt(string);
-        } else if (Integer.class.isAssignableFrom(dataType)
-            || int.class.isAssignableFrom(dataType)) {
-          return Integer.parseInt(string);
-        } else if (Long.class.isAssignableFrom(dataType) || long.class.isAssignableFrom(dataType)) {
-          return Long.parseLong(string);
-        } else if (Float.class.isAssignableFrom(dataType)
-            || float.class.isAssignableFrom(dataType)) {
-          return Float.parseFloat(string);
-        } else if (Double.class.isAssignableFrom(dataType)
-            || double.class.isAssignableFrom(dataType)) {
-          return Double.parseDouble(string);
-        } else if (Character.class.isAssignableFrom(dataType)
-            || char.class.isAssignableFrom(dataType)) {
-          if (string.length() == 1) {
-            string.charAt(0);
-          } else {
-            // FIXME Use a constant here
-            return '0';
-          }
+    for (int i = 0; i < tokens.size(); i++) {
+      String token = tokens.get(i);
+      if ("--J".equals(token)) {
+        if (firstJIndex < 1) {
+          firstJIndex = i;
         }
-      }
-    } catch (Exception e) {
-      // TODO add logging
-      // Do nothing, just return null
-    }
-    return null;
-  }
-
-  private List<CommandTarget> locateTargets(String userInput)
-      throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
-    return locateTargets(userInput, true);
-  }
-
+        i++;
 
-  private List<CommandTarget> locateTargets(String userInput, boolean matchIncomplete)
-      throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
-    List<CommandTarget> commandTargets = new ArrayList<CommandTarget>();
-    Map<String, CommandTarget> commands = commandManager.getCommands();
-    // Now we need to locate the CommandTargets from the entries in the map
-    for (String commandName : commands.keySet()) {
-      if (userInput.startsWith(commandName)) {
-        // This means that the user has entered the command
-        CommandTarget commandTarget = commands.get(commandName);
-        if (isAvailable(commandTarget, commandName)) {
-          String remainingBuffer = StringUtils.removeStart(userInput, commandName);
-          if (remainingBuffer.length() == 0 || remainingBuffer.startsWith(" ")
-              || remainingBuffer.startsWith(GfshParser.LINE_SEPARATOR)) {
-            // We need to duplicate with a new MethodTarget as this
-            // parser will be used in a concurrent execution environment
-            if (!commandTargets.contains(commandTarget)) {
-              // This test is necessary as the command may have similar
-              // synonyms or which are prefix for the command
-              commandTargets.add(commandTarget.duplicate(commandName, remainingBuffer));
-            }
+        if (i < tokens.size()) {
+          String jArg = tokens.get(i);
+          if (jArg.charAt(0) == '"' || jArg.charAt(0) == '\'') {
+            jArg = jArg.substring(1, jArg.length() - 1);
           }
-        }
-      } else if (matchIncomplete && commandName.startsWith(userInput)) {
-        // This means that the user is yet to enter the command properly
-        CommandTarget commandTarget = commands.get(commandName);
-        if (isAvailable(commandTarget, commandName)) {
-          // We need to duplicate with a new MethodTarget as this
-          // parser will be used in a concurrent execution environment
-          if (!commandTargets.contains(commandTarget)) {
-            // This test is necessary as the command may have similar
-            // synonyms or which are prefix for the command
-            commandTargets.add(commandTarget.duplicate(commandName));
+          if (jArg.length() > 0) {
+            jArguments.add(jArg);
           }
         }
+      } else {
+        inputTokens.add(token);
       }
     }
-    return commandTargets;
-  }
-
-  // TODO - Abhishek - create an inner CommandTargetLocater instead of multiple
-  // methods like these.
-  private CommandTarget locateExactMatchingTarget(final String userInput)// exact matching
-      throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
-    CommandTarget commandTarget = null;
-
-    Map<String, CommandTarget> commandTargetsMap = commandManager.getCommands();
-    // Reverse sort the command names because we should start from longer names
-    // E.g. Consider commands "A", "A B" & user input as "A B --opt1=val1"
-    // In this case, "A B" is the most probable match & should be matched first
-    // which can be achieved by reversing natural order of sorting.
-    Set<String> commandNamesReverseSorted = new TreeSet<String>(Collections.reverseOrder());
-    commandNamesReverseSorted.addAll(commandTargetsMap.keySet());
-
-    // Now we need to locate the CommandTargets from the entries in the map
-    for (final String commandName : commandNamesReverseSorted) {
-      if (userInput.startsWith(commandName) && commandWordsMatch(userInput, commandName)) {
-        // This means that the user has entered the command & name matches exactly
-        commandTarget = commandTargetsMap.get(commandName);
-        if (commandTarget != null) {
-          String remainingBuffer = StringUtils.removeStart(userInput, commandName);
-          commandTarget = commandTarget.duplicate(commandName, remainingBuffer);
-          break;
-        }
-      }
-    }
-    return commandTarget;
-  }
-
-  private static boolean commandWordsMatch(final String userInput, final String commandName) {
-    boolean commandWordsMatch = true;
-
-    String[] commandNameWords = commandName.split(" ");
-    String[] userInputWords = userInput.split(" ");
 
-    // commandName is fixed & hence should have less or same number of words as
-    // the user input. E.g. "create disk-store" should match with
-    // "create disk-store --name=xyz" but not with "create disk store"
-    if (commandNameWords.length <= userInputWords.length) {
-      // if both have length zero, words can be considered to be matching.
-      for (int i = 0; i < commandNameWords.length; i++) {
-        if (!commandNameWords[i].equals(userInputWords[i])) {
-          commandWordsMatch = false;
-          break;
+    // concatenate the remaining tokens with space
+    StringBuffer rawInput = new StringBuffer();
+    // firstJIndex must be less than or equal to the length of the inputToken
+    for (int i = 0; i <= inputTokens.size(); i++) {
+      // stick the --J arguments in the orginal first --J position
+      if (i == firstJIndex) {
+        rawInput.append("--J ");
+        if (jArguments.size() > 0) {
+          rawInput.append("\"").append(StringUtils.join(jArguments, ",")).append("\" ");
         }
       }
-    } else {
-      commandWordsMatch = false;
-    }
-
-    return commandWordsMatch;
-  }
-
-
-  private Map<String, CommandTarget> getRequiredCommandTargets(Set<String> requiredCommands) {
-    Map<String, CommandTarget> existingCommands = commandManager.getCommands();
-    Map<String, CommandTarget> requiredCommandsMap = existingCommands;
-
-    if (requiredCommands != null && !requiredCommands.isEmpty()) {
-      requiredCommandsMap = new TreeMap<String, CommandTarget>();
-      for (String commandName : requiredCommands) {
-        CommandTarget commandTarget = existingCommands.get(commandName);
-        if (commandTarget != null) {
-          requiredCommandsMap.put(commandName, commandTarget);
-        }
+      // then add the next inputToken
+      if (i < inputTokens.size()) {
+        rawInput.append(inputTokens.get(i)).append(" ");
       }
     }
 
-    return requiredCommandsMap;
+    return rawInput.toString().trim();
   }
 
-  private Map<Short, List<CommandTarget>> findMatchingCommands(String userSpecifiedCommand,
-      Set<String> requiredCommands)
-      throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
-
-    Map<String, CommandTarget> existingCommands = getRequiredCommandTargets(requiredCommands);
-    CommandTarget exactCommandTarget = existingCommands.get(userSpecifiedCommand);
+  @Override
+  public ParseResult parse(String userInput) {
+    String rawInput = convertToSimpleParserInput(userInput);
 
-    // 1. First find exactly matching commands.
-    List<CommandTarget> exactCommandTargets = Collections.emptyList();
-    if (exactCommandTarget != null) {
-      // This means that the user has entered the command
-      // NOTE: we are not skipping synonym here.
-      exactCommandTargets = Collections.singletonList(exactCommandTarget);
-    }
+    // User SimpleParser to parse the input
+    ParseResult result = super.parse(rawInput);
 
-    // 2. Now find command names that start with 'userSpecifiedCommand'
-    List<CommandTarget> possibleCommandTargets = new ArrayList<CommandTarget>();
-    // Now we need to locate the CommandTargets from the entries in the map
-    for (Map.Entry<String, CommandTarget> entry : existingCommands.entrySet()) {
-      CommandTarget commandTarget = entry.getValue();
-      String commandName = commandTarget.getCommandName();
-      // This check is done to remove commands that are synonyms as
-      // CommandTarget.getCommandName() will return name & not a synonym
-      if (entry.getKey().equals(commandName)) {
-        if (commandName.startsWith(userSpecifiedCommand)
-            && !commandTarget.equals(exactCommandTarget)) {
-          // This means that the user is yet to enter the command properly
-          possibleCommandTargets.add(commandTarget);
-        }
-      }
+    if (result != null) {
+      return new GfshParseResult(result.getMethod(), result.getInstance(), result.getArguments(),
+          userInput);
     }
 
-    Map<Short, List<CommandTarget>> commandTargetsArr = new HashMap<Short, List<CommandTarget>>();
-    commandTargetsArr.put(EXACT_TARGET, exactCommandTargets);
-    commandTargetsArr.put(MATCHING_TARGETS, possibleCommandTargets);
-    return commandTargetsArr;
+    return null;
   }
 
+  @Override
+  public int completeAdvanced(String userInput, int cursor, final List<Completion> candidates) {
+    cursor = userInput.length();
+    List<String> inputTokens = splitUserInput(userInput);
+    String lastToken = inputTokens.get(inputTokens.size() - 1);
 
-  private boolean isAvailable(CommandTarget commandTarget, String commandName)
-      throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
-    AvailabilityTarget availabilityIndicator = commandTarget.getAvailabilityIndicator();
-    if (availabilityIndicator == null) {
-      availabilityIndicator = commandManager.getAvailabilityIndicator(commandName);
-      commandTarget.setAvailabilityIndicator(availabilityIndicator);
+    // trying to get candidates using the converted input and the candidateBeginAt cursor position
+    String buffer = getSimpleParserInputFromTokens(inputTokens);
+    int candidateBeginAt = buffer.length() - lastToken.length();
+    List<Completion> potentials = getCandidates(buffer, candidateBeginAt);
+    if (potentials.size() == 0 && !lastToken.startsWith("--")) {
+      // if last token is not an option, add "--" to it and retry
+      candidateBeginAt = buffer.length() + 1;
+      potentials = getCandidates(buffer + " --", candidateBeginAt);
+    } else if (potentials.size() == 1 && potentials.get(0).getValue().equals(lastToken)) {
+      // if the candidate is exactly the same as the last token, add a space to it and retry
+      potentials = getCandidates(buffer + " ", candidateBeginAt);
     }
-    return commandTarget.isAvailable();
-  }
 
-  public List<String> obtainHelpCommandNames(String userInput) {
-    List<String> commandNames = new ArrayList<String>();
-
-    try {
-      if (userInput == null) {
-        userInput = "";
+    // If we have a candidate, need to determine what's the returned cursor should be
+    if (potentials.size() > 0) {
+      // usually we want to begin the cursor at candidateBeginCursor, but since we consolidated
+      // --J options into one, and added quotes around we need to consider the length difference
+      // between userInput and the converted input
+      cursor = candidateBeginAt + (userInput.trim().length() - buffer.length());
+      // our cursor can't be further than whatever user has typed in
+      if (cursor > userInput.length()) {
+        cursor = userInput.length();
       }
-
-      List<CommandTarget> commandTargets = new ArrayList<CommandTarget>();
-      Map<Short, List<CommandTarget>> matchingCommandsMap = findMatchingCommands(userInput, null);
-      commandTargets.addAll(matchingCommandsMap.get(EXACT_TARGET));
-      commandTargets.addAll(matchingCommandsMap.get(MATCHING_TARGETS));
-
-      for (CommandTarget commandTarget : commandTargets) {
-        commandNames.add(commandTarget.getCommandName());
-      }
-    } catch (IllegalArgumentException e) {
-      logWrapper.warning(CliUtil.stackTraceAsString(e));
-    } catch (IllegalAccessException e) {
-      logWrapper.warning(CliUtil.stackTraceAsString(e));
-    } catch (InvocationTargetException e) {
-      logWrapper.warning(CliUtil.stackTraceAsString(e));
     }
 
-    return commandNames;
+    candidates.addAll(potentials);
+    return cursor;
   }
 
-  public String obtainHelp(String userInput, Set<String> commandNames) {
-    final boolean withinShell = commandNames == null || commandNames.isEmpty();
-    final String appName = withinShell ? "" : HelpUtils.EXE_PREFIX_FOR_EXTERNAL_HELP;
-
-    StringBuilder helpText = new StringBuilder();
-    try {
-      if (userInput == null) {
-        userInput = "";
-      }
-
-      Map<Short, List<CommandTarget>> matchingCommandsMap =
-          findMatchingCommands(userInput, commandNames);
-      List<CommandTarget> exactCommandTargets = matchingCommandsMap.get(EXACT_TARGET);
-      List<CommandTarget> matchingCommandTargets = matchingCommandsMap.get(MATCHING_TARGETS);
-      matchingCommandsMap.clear();
-
-      if (exactCommandTargets.isEmpty() && matchingCommandTargets.isEmpty()) {
-        // No matching commands
-        helpText.append(CliStrings.GFSHPARSER__MSG__NO_MATCHING_COMMAND)
-            .append(GfshParser.LINE_SEPARATOR);
-      } else {
-        if (exactCommandTargets.size() == 1) {
-          helpText.append(obtainCommandSpecificHelp(exactCommandTargets.get(0), withinShell));
-          if (!matchingCommandTargets.isEmpty()) {
-            helpText.append(GfshParser.LINE_SEPARATOR);
-            helpText.append(CliStrings
-                .format(CliStrings.GFSHPARSER__MSG__OTHER_COMMANDS_STARTING_WITH_0_ARE, userInput));
-            for (int i = 0; i < matchingCommandTargets.size(); i++) {
-              CommandTarget commandTarget = matchingCommandTargets.get(i);
-              helpText.append(commandTarget.getCommandName());
-              if (i < matchingCommandTargets.size() - 1) {
-                helpText.append(", ");
-              }
-            }
-            helpText.append(GfshParser.LINE_SEPARATOR);
-          }
-        } else {
-          List<CommandTarget> commandTargets = new ArrayList<CommandTarget>();
-          commandTargets.addAll(exactCommandTargets);
-          commandTargets.addAll(matchingCommandTargets);
-          for (CommandTarget commandTarget : commandTargets) {
-            String availability = commandTarget.isAvailable() ? HelpUtils.HELP__COMMAND_AVAILABLE
-                : HelpUtils.HELP__COMMAND_NOTAVAILABLE;
-            // Many matching commands, provide one line description
-            helpText.append(commandTarget.getCommandName());
-            if (withinShell) {
-              helpText.append(" (").append(availability).append(")");
-            }
-            helpText.append(GfshParser.LINE_SEPARATOR);
-            helpText.append(Gfsh.wrapText(commandTarget.getCommandHelp(), 1))
-                .append(GfshParser.LINE_SEPARATOR);
-          }
-          helpText.append(GfshParser.LINE_SEPARATOR);
-
-          if (withinShell) {
-            helpText
-                .append(Gfsh.wrapText(
-                    CliStrings.format(
-                        CliStrings.GFSHPARSER__MSG__USE_0_HELP_COMMAND_TODISPLAY_DETAILS, appName),
-                    0))
-                .append(GfshParser.LINE_SEPARATOR);
-            helpText.append(Gfsh.wrapText(
-                CliStrings.format(CliStrings.GFSHPARSER__MSG__HELP_CAN_ALSO_BE_OBTAINED_BY_0_KEY,
-                    AbstractShell.completionKeys),
-                0));
-          }
-        }
-      }
-    } catch (IllegalArgumentException e) {
-      logWrapper.warning(CliUtil.stackTraceAsString(e));
-    } catch (IllegalAccessException e) {
-      logWrapper.warning(CliUtil.stackTraceAsString(e));
-    } catch (InvocationTargetException e) {
-      logWrapper.warning(CliUtil.stackTraceAsString(e));
-    }
-    return helpText.toString();
-  }
+  /**
+   * @param buffer use the buffer to find the completion candidates
+   * @param candidateBeginAt strip the found candidates from this position
+   *
+   *        Note the cursor maynot be the size the buffer
+   */
+  public List<Completion> getCandidates(String buffer, int candidateBeginAt) {
+    List<Completion> candidates = new ArrayList<>();
 
-  private String obtainCommandSpecificHelp(CommandTarget commandTarget, boolean withinShell) {
-    NewHelp newHelp = HelpUtils.getNewHelp(commandTarget, withinShell);
-    return newHelp.toString();
-  }
+    // always pass the buffer length as the cursor position for simplicity purpose
+    super.completeAdvanced(buffer, buffer.length(), candidates);
 
-  public List<String> getCommandNames(String string) {
-    List<String> commandNames = new ArrayList<String>();
-    try {
-      if (string == null) {
-        string = "";
-      }
-      List<CommandTarget> locateTargets = locateTargets(string);
-      for (CommandTarget commandTarget : locateTargets) {
-        String key = commandTarget.getGfshMethodTarget().getKey();
-        if (key.startsWith(string)) {
-          commandNames.add(key);
-        }
+    // stripp off the beginning part of the candidates from the cursor point
+    // starting from the end, since we need to remove and add
+    for (int i = candidates.size() - 1; i >= 0; i--) {
+      Completion candidate = candidates.remove(i);
+      // we only need the part after the current cursor
+      String suggest = candidate.getValue().substring(candidateBeginAt);
+      // this suggested value usually ends with a space because it's assuming it's using
+      // "--option argment" format. trim the ending space so that we can easily add the "="sign
+      if (suggest.endsWith(" ")) {
+        suggest = suggest.substring(0, suggest.length() - 1);
       }
-    } catch (IllegalArgumentException e) {
-      logWrapper.warning(CliUtil.stackTraceAsString(e));
-    } catch (IllegalAccessException e) {
-      logWrapper.warning(CliUtil.stackTraceAsString(e));
-    } catch (InvocationTargetException e) {
-      logWrapper.warning(CliUtil.stackTraceAsString(e));
+      candidates.add(new Completion(suggest));
     }
-    return commandNames;
+    return candidates;
   }
 
-  // ///////////////// Parser interface Methods End //////////////////////////
-
-  private void handleCondition(String message, int errorType, Object errorData) {
-    this.handleCondition(message, null, errorType, errorData);
+  @Override
+  public void obtainHelp(String buffer) {
+    consoleLogger.info(getHelp(buffer));
   }
 
-  private void handleCondition(String message, Throwable th, int errorType, Object errorData) {
-    if (CliUtil.isGfshVM()) {
-      logWarning(message); // TODO - Abhishek add throwable if debug is ON
-    } else {
-      if (th != null) {
-        throw new CommandProcessingException(message + ": " + th.getMessage(), errorType,
-            errorData);
+  public String getHelp(String buffer) {
+    HelpBlock help = new HelpBlock();
+    if (StringUtils.isBlank(buffer)) {
+      for (String command : commandManager.getCommands()) {
+        Method method = commandManager.getCommandMethod(command);
+        CliCommand cliCommand = method.getDeclaredAnnotation(CliCommand.class);
+        HelpBlock commandBlock = new HelpBlock(command);
+        commandBlock.addChild(new HelpBlock(cliCommand.help()));
+        help.addChild(commandBlock);
       }
-      throw new CommandProcessingException(message, errorType, errorData);
-    }
-  }
-
-  private void logWarning(String message) {
-    if (canLogToConsole()) {
-      consoleLogger
-          .warning(CLIConsoleBufferUtil.processMessegeForExtraCharactersFromConsoleBuffer(message));
     } else {
-      Gfsh.println(message);
+      Method method = commandManager.getCommandMethod(buffer);
+      help = HelpUtils.getHelp(method);
     }
+    return help.toString();
   }
-
-  private boolean canLogToConsole() {
-    Gfsh gfsh = Gfsh.getCurrentInstance();
-    return gfsh != null && !gfsh.isHeadlessMode() && consoleLogger != null;
-  }
-
-  // private void logInfo(String message) {
-  // if (consoleLogger != null) {
-  // consoleLogger.info(message);
-  // } else {
-  // Gfsh.println(message);
-  // }
-  // }
 }

http://git-wip-us.apache.org/repos/asf/geode/blob/ce9e138c/geode-core/src/main/java/org/apache/geode/management/internal/cli/Launcher.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/Launcher.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/Launcher.java
index fc0427e..7dd42c4 100755
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/Launcher.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/Launcher.java
@@ -14,22 +14,19 @@
  */
 package org.apache.geode.management.internal.cli;
 
-import java.io.IOException;
-import java.io.PrintStream;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
 import org.apache.geode.internal.GemFireVersion;
 import org.apache.geode.internal.PureJavaMode;
 import org.apache.geode.management.internal.cli.i18n.CliStrings;
-import org.apache.geode.management.internal.cli.parser.SyntaxConstants;
 import org.apache.geode.management.internal.cli.shell.Gfsh;
 import org.apache.geode.management.internal.cli.shell.GfshConfig;
 import org.apache.geode.management.internal.cli.shell.jline.GfshHistory;
-
 import org.springframework.shell.core.ExitShellRequest;
 
+import java.io.IOException;
+import java.io.PrintStream;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
 import joptsimple.OptionException;
 import joptsimple.OptionParser;
 import joptsimple.OptionSet;
@@ -84,28 +81,14 @@ public final class Launcher {
   private static final String MSG_INVALID_COMMAND_OR_OPTION = "Invalid command or option : {0}."
       + GfshParser.LINE_SEPARATOR + "Use 'gfsh help' to display additional information.";
 
-  private final Set<String> allowedCommandLineCommands;
-  private final OptionParser commandLineParser;
-  private StartupTimeLogHelper startupTimeLogHelper;
-
   static {
     // See 47325
     System.setProperty(PureJavaMode.PURE_MODE_PROPERTY, "true");
   }
 
-  public static void main(final String[] args) {
-    // first check whether required dependencies exist in the classpath
-    // should we start without tomcat/servlet jars?
-    String nonExistingDependency = CliUtil.cliDependenciesExist(true);
-    if (nonExistingDependency != null) {
-      System.err.println("Required (" + nonExistingDependency
-          + ") libraries not found in the classpath. gfsh can't start.");
-      return;
-    }
-
-    Launcher launcher = new Launcher();
-    System.exit(launcher.parseCommandLine(args));
-  }
+  private final Set<String> allowedCommandLineCommands;
+  private final OptionParser commandLineParser;
+  private StartupTimeLogHelper startupTimeLogHelper;
 
   protected Launcher() {
     this.startupTimeLogHelper = new StartupTimeLogHelper();
@@ -138,6 +121,20 @@ public final class Launcher {
     this.commandLineParser.posixlyCorrect(false);
   }
 
+  public static void main(final String[] args) {
+    // first check whether required dependencies exist in the classpath
+    // should we start without tomcat/servlet jars?
+    String nonExistingDependency = CliUtil.cliDependenciesExist(true);
+    if (nonExistingDependency != null) {
+      System.err.println("Required (" + nonExistingDependency
+          + ") libraries not found in the classpath. gfsh can't start.");
+      return;
+    }
+
+    Launcher launcher = new Launcher();
+    System.exit(launcher.parseCommandLine(args));
+  }
+
   private int parseCommandLineCommand(final String... args) {
     Gfsh gfsh = null;
     try {
@@ -253,7 +250,7 @@ public final class Launcher {
   }
 
   private int parseCommandLine(final String... args) {
-    if (args.length > 0 && !args[0].startsWith(SyntaxConstants.SHORT_OPTION_SPECIFIER)) {
+    if (args.length > 0 && !args[0].startsWith(GfshParser.SHORT_OPTION_SPECIFIER)) {
       return parseCommandLineCommand(args);
     }
 
@@ -290,8 +287,6 @@ public final class Launcher {
         "Commands may be any that are available from the interactive gfsh prompt.  "
             + "For commands that require a Manager to complete, the first command in the list must be \"connect\".",
         1));
-    stream.println(GfshParser.LINE_SEPARATOR + "AVAILABLE COMMANDS");
-    stream.print(gfsh.obtainHelp("", this.allowedCommandLineCommands));
     stream.println("EXAMPLES");
     stream.println("gfsh");
     stream.println(Gfsh.wrapText("Start GFSH in interactive mode.", 1));

http://git-wip-us.apache.org/repos/asf/geode/blob/ce9e138c/geode-core/src/main/java/org/apache/geode/management/internal/cli/annotation/CliArgument.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/annotation/CliArgument.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/annotation/CliArgument.java
deleted file mode 100644
index e20e731..0000000
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/annotation/CliArgument.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
- * agreements. See the NOTICE file distributed with this work for additional information regarding
- * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance with the License. You may obtain a
- * copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-package org.apache.geode.management.internal.cli.annotation;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-import org.springframework.shell.core.Converter;
-import org.springframework.shell.core.annotation.CliCommand;
-
-/**
- * Annotation for Argument of a Command
- * 
- * @since GemFire 7.0
- */
-@Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.PARAMETER)
-public @interface CliArgument {
-
-  /**
-   * @return name of the argument, useful during help and warning messages
-   */
-  String name();
-
-  /**
-   * @return a help message for this option (the default is a blank String, which means there is no
-   *         help)
-   */
-  String help() default "";
-
-  /**
-   * @return true if this argument must be specified one way or the other by the user (defaults to
-   *         false)
-   */
-  boolean mandatory() default false;
-
-  /**
-   * Returns a string providing context-specific information (e.g. a comma-delimited set of
-   * keywords) to the {@link Converter} that handles the annotated parameter's type.
-   * <p>
-   * For example, if a method parameter "thing" of type "Thing" is annotated as follows:
-   * 
-   * <pre>
-   * <code>@CliArgument(..., argumentContext = "foo,bar", ...) Thing thing</code>
-   * </pre>
-   * 
-   * ... then the {@link Converter} that converts the text entered by the user into an instance of
-   * Thing will be passed "foo,bar" as the value of the <code>optionContext</code> parameter in its
-   * public methods. This allows the behaviour of that Converter to be individually customised for
-   * each {@link CliArgument} of each {@link CliCommand}.
-   * 
-   * @return a non-<code>null</code> string (can be empty)
-   */
-  String argumentContext() default "";
-
-  /**
-   * @return if true, the user cannot specify this option and it is provided by the shell
-   *         infrastructure (defaults to false)
-   */
-  boolean systemProvided() default false;
-
-  /**
-   * @return the default value to use if this argument is unspecified by the user (defaults to
-   *         __NULL__, which causes null to be presented to any non-primitive parameter)
-   */
-  String unspecifiedDefaultValue() default "__NULL__";
-}

http://git-wip-us.apache.org/repos/asf/geode/blob/ce9e138c/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/GfshHelpCommands.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/GfshHelpCommands.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/GfshHelpCommands.java
index 1d1b28e..a5849d3 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/GfshHelpCommands.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/GfshHelpCommands.java
@@ -15,86 +15,21 @@
 package org.apache.geode.management.internal.cli.commands;
 
 import org.apache.geode.management.cli.CliMetaData;
-import org.apache.geode.management.cli.ConverterHint;
-import org.apache.geode.management.cli.Result;
-import org.apache.geode.management.internal.cli.CommandManager;
 import org.apache.geode.management.internal.cli.GfshParser;
-import org.apache.geode.management.internal.cli.annotation.CliArgument;
-import org.apache.geode.management.internal.cli.help.CliTopic;
 import org.apache.geode.management.internal.cli.i18n.CliStrings;
-import org.apache.geode.management.internal.cli.result.CompositeResultData;
-import org.apache.geode.management.internal.cli.result.CompositeResultData.SectionResultData;
-import org.apache.geode.management.internal.cli.result.ResultBuilder;
-import org.apache.geode.management.internal.cli.shell.Gfsh;
 import org.springframework.shell.core.CommandMarker;
 import org.springframework.shell.core.annotation.CliCommand;
-
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
+import org.springframework.shell.core.annotation.CliOption;
 
 /**
- * 
- * 
  * @since GemFire 7.0
  */
 public class GfshHelpCommands implements CommandMarker {
-
-  private Gfsh getGfsh() {
-    return Gfsh.getCurrentInstance();
-  }
-
   @CliCommand(value = CliStrings.HELP, help = CliStrings.HELP__HELP)
   @CliMetaData(shellOnly = true, relatedTopic = {CliStrings.TOPIC_GEODE_HELP})
-  public Result obtainHelp(
-      @CliArgument(name = CliStrings.HELP__COMMAND, argumentContext = CliStrings.PARAM_CONTEXT_HELP,
-          help = CliStrings.HELP__COMMAND__HELP) String commandString) {
-    return ResultBuilder.createInfoResult(getGfsh().obtainHelp(commandString, null));
-  }
-
-
-
-  @CliCommand(value = CliStrings.HINT, help = CliStrings.HINT__HELP)
-  @CliMetaData(shellOnly = true, relatedTopic = {CliStrings.TOPIC_GEODE_HELP})
-  public Result hint(
-      @CliArgument(name = CliStrings.HINT__TOPICNAME, argumentContext = ConverterHint.HINTTOPIC,
-          help = CliStrings.HINT__TOPICNAME) String topicName) {
-    Result result = null;
-    CommandManager commandManager = CommandManager.getExisting();
-    if (commandManager == null) {
-      result =
-          ResultBuilder.createShellClientErrorResult(CliStrings.HINT__MSG__SHELL_NOT_INITIALIZED);
-    } else {
-      StringBuilder builder = new StringBuilder();
-      if (topicName == null) {
-        builder.append(CliStrings.HINT__MSG__TOPICS_AVAILABLE).append(GfshParser.LINE_SEPARATOR);
-        Set<String> topicNameSet = commandManager.getTopicNames();
-        for (String topic : topicNameSet) {
-          builder.append(topic).append(GfshParser.LINE_SEPARATOR);
-        }
-        result = ResultBuilder.createInfoResult(builder.toString());
-      } else {
-        CliTopic topic = commandManager.getTopic(topicName);
-        if (topic == null) {
-          result = ResultBuilder
-              .createInfoResult(CliStrings.format(CliStrings.HINT__MSG__UNKNOWN_TOPIC, topicName));
-        } else {
-          CompositeResultData compositeResultData = ResultBuilder.createCompositeResultData();
-          SectionResultData commandHelpSection =
-              compositeResultData.addSection("Commands And Help");
-          compositeResultData.setHeader(topic.getOneLinerDescription());
-          Map<String, String> commandsNameHelp = topic.getCommandsNameHelp();
-          Set<Entry<String, String>> entries = commandsNameHelp.entrySet();
-
-          for (Entry<String, String> entry : entries) {
-            commandHelpSection.addData(entry.getKey(), entry.getValue());
-          }
-
-          result = ResultBuilder.buildResult(compositeResultData);
-        }
-      }
-    }
-
-    return result;
+  public void obtainHelp(@CliOption(key = {"", CliStrings.SH__COMMAND},
+      optionContext = "disable-string-converter availableCommands",
+      help = "Command name to provide help for") String buffer) {
+    GfshParser.getInstance().obtainHelp(buffer);
   }
 }