class ConnectCommand extends OfflineGfshCommand {

  ResultModel jmxConnect(Properties gfProperties, boolean useSsl,
      ConnectionEndpoint memberRmiHostPort,
      ConnectionEndpoint locatorTcpHostPort, boolean retry) {
    ConnectionEndpoint jmxHostPortToConnect = null;
    Gfsh gfsh = getGfsh();

    try {
      // trying to find the rmi host and port, if rmi host port exists, use that, otherwise, use
      // locator to find the rmi host port
      if (memberRmiHostPort != null) {
        jmxHostPortToConnect = memberRmiHostPort;
      } else {
        if (useSsl) {
          gfsh.logToFile(
              CliStrings.CONNECT__USE_SSL + " is set to true. Connecting to Locator via SSL.",
              null);
        }

        Gfsh.println(CliStrings.format(CliStrings.CONNECT__MSG__CONNECTING_TO_LOCATOR_AT_0,
            new Object[] {locatorTcpHostPort.toString(false)}));
        ConnectToLocatorResult connectToLocatorResult =
            connectToLocator(locatorTcpHostPort.getHost(), locatorTcpHostPort.getPort(),
                CONNECT_LOCATOR_TIMEOUT_MS, gfProperties);
        jmxHostPortToConnect = connectToLocatorResult.getMemberEndpoint();

        // when locator is configured to use SSL (ssl-enabled=true) but manager is not
        // (jmx-manager-ssl=false)
        if (useSsl && !connectToLocatorResult.isJmxManagerSslEnabled()) {
          gfsh.logInfo(
              CliStrings.CONNECT__USE_SSL
                  + " is set to true. But JMX Manager doesn't support SSL, connecting without SSL.",
              null);
          useSsl = false;
        }
      }

      if (useSsl) {
        gfsh.logToFile("Connecting to manager via SSL.", null);
      }

      // print out the connecting endpoint
      if (!retry) {
        Gfsh.println(CliStrings.format(CliStrings.CONNECT__MSG__CONNECTING_TO_MANAGER_AT_0,
            new Object[] {jmxHostPortToConnect.toString(false)}));
      }

      ResultModel result = new ResultModel();
      InfoResultModel infoResultModel = result.addInfo();
      JmxOperationInvoker operationInvoker = new JmxOperationInvoker(jmxHostPortToConnect.getHost(),
          jmxHostPortToConnect.getPort(), gfProperties);

      gfsh.setOperationInvoker(operationInvoker);
      infoResultModel.addLine(CliStrings.format(CliStrings.CONNECT__MSG__SUCCESS,
          jmxHostPortToConnect.toString(false)));
      LogWrapper.getInstance().info(CliStrings.format(CliStrings.CONNECT__MSG__SUCCESS,
          jmxHostPortToConnect.toString(false)));
      return result;
    } catch (SecurityException | AuthenticationFailedException e) {
      // if it's security exception, and we already sent in username and password, still returns the
      // connection error
      if (gfProperties.containsKey(ResourceConstants.USER_NAME)
          || gfProperties.containsKey(ResourceConstants.TOKEN)) {
        return handleException(e, jmxHostPortToConnect);
      }

      // otherwise, prompt for username and password and retry the connection
      gfProperties.setProperty(UserInputProperty.USERNAME.getKey(),
          UserInputProperty.USERNAME.promptForAcceptableValue(gfsh));
      gfProperties.setProperty(UserInputProperty.PASSWORD.getKey(),
          UserInputProperty.PASSWORD.promptForAcceptableValue(gfsh));
      return jmxConnect(gfProperties, useSsl, jmxHostPortToConnect, null, true);
    } catch (UnknownHostException e) {
      return handleException(e,
          "JMX manager can't be reached. Hostname or IP address could not be found.");
    } catch (Exception e) {
      // all other exceptions, just logs it and returns a connection error
      return handleException(e, jmxHostPortToConnect);
    }
  }

}