/**
   * {@inheritDoc}
   *
   * @see org.komodo.shell.BuiltInShellCommand#tabCompletion(java.lang.String, java.util.List)
   */
  @Override
  public TabCompletionModifier tabCompletion(
      final String lastArgument, final List<CharSequence> candidates) throws Exception {
    final Arguments args = getArguments();

    try {
      List<String> existingDatasourceNames =
          ServerUtils.getDatasourceNames(getWorkspaceTeiidInstance());
      Collections.sort(existingDatasourceNames);

      if (args.isEmpty()) {
        if (lastArgument == null) {
          candidates.addAll(existingDatasourceNames);
        } else {
          for (final String item : existingDatasourceNames) {
            if (item.startsWith(lastArgument)) {
              candidates.add(item);
            }
          }
        }
      }
    } catch (Exception ex) {
      print();
      print(MESSAGE_INDENT, I18n.bind(ServerCommandsI18n.connectionErrorWillDisconnect));
      WkspStatusServerManager.getInstance(getWorkspaceStatus()).disconnectDefaultServer();
    }

    return TabCompletionModifier.AUTO;
  }
  /**
   * {@inheritDoc}
   *
   * @see org.komodo.shell.BuiltInShellCommand#doExecute()
   */
  @Override
  protected CommandResult doExecute() {
    CommandResult result = null;

    try {
      String datasourceName =
          requiredArgument(0, I18n.bind(ServerCommandsI18n.missingDatasourceName));

      final String overwriteArg = optionalArgument(1, null);
      final boolean overwrite = !StringUtils.isBlank(overwriteArg);
      // make sure overwrite arg is valid
      if (overwrite && !VALID_OVERWRITE_ARGS.contains(overwriteArg)) {
        return new CommandResultImpl(
            false, I18n.bind(WorkspaceCommandsI18n.overwriteArgInvalid, overwriteArg), null);
      }

      // If datasource with same name is in workspace, make sure we can overwrite
      boolean hasDS =
          getWorkspaceManager(getTransaction())
              .hasChild(getTransaction(), datasourceName, DataVirtLexicon.Connection.NODE_TYPE);
      if (hasDS && !overwrite) {
        return new CommandResultImpl(
            false,
            I18n.bind(ServerCommandsI18n.datasourceOverwriteNotEnabled, datasourceName),
            null);
      }

      // Validates that a server is connected
      CommandResult validationResult = validateHasConnectedWorkspaceServer();
      if (!validationResult.isOk()) {
        return validationResult;
      }

      // Get the Data Source from the server
      TeiidDataSource serverDS = null;
      try {
        // Check the data source name to make sure its valid
        List<String> existingSourceNames =
            ServerUtils.getDatasourceNames(getWorkspaceTeiidInstance());
        if (!existingSourceNames.contains(datasourceName)) {
          return new CommandResultImpl(
              false, I18n.bind(ServerCommandsI18n.serverDatasourceNotFound, datasourceName), null);
        }
        // Get the data source
        serverDS = getWorkspaceTeiidInstance().getDataSource(datasourceName);
      } catch (Exception ex) {
        result =
            new CommandResultImpl(
                false, I18n.bind(ServerCommandsI18n.connectionErrorWillDisconnect), ex);
        WkspStatusServerManager.getInstance(getWorkspaceStatus()).disconnectDefaultServer();
        return result;
      }
      if (serverDS == null) {
        return new CommandResultImpl(
            false, I18n.bind(ServerCommandsI18n.serverDatasourceNotFound, datasourceName), null);
      }

      // If overwriting, delete existing first
      if (hasDS) {
        final KomodoObject datasourceToDelete =
            getWorkspaceManager(getTransaction())
                .getChild(getTransaction(), datasourceName, DataVirtLexicon.Connection.NODE_TYPE);
        getWorkspaceManager(getTransaction()).delete(getTransaction(), datasourceToDelete);
      }
      // Create the Data Source and set properties
      Datasource newDatasource =
          getWorkspaceManager(getTransaction())
              .createDatasource(getTransaction(), null, datasourceName);
      setRepoDatasourceProperties(newDatasource, serverDS.getProperties());

      print(MESSAGE_INDENT, I18n.bind(ServerCommandsI18n.datasourceCopyToRepoFinished));
      result = CommandResult.SUCCESS;
    } catch (final Exception e) {
      result = new CommandResultImpl(e);
    }

    return result;
  }