You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by ni...@apache.org on 2023/06/13 10:22:01 UTC

[ignite] branch master updated: IGNITE-15629 Management API introduced (#10675)

This is an automated email from the ASF dual-hosted git repository.

nizhikov pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ignite.git


The following commit(s) were added to refs/heads/master by this push:
     new 46d865d63dd  IGNITE-15629 Management API introduced (#10675)
46d865d63dd is described below

commit 46d865d63dd43bf879278d530af27f25715b0189
Author: Nikolay <ni...@apache.org>
AuthorDate: Tue Jun 13 13:21:53 2023 +0300

     IGNITE-15629 Management API introduced (#10675)
---
 modules/control-utility/pom.xml                    |   7 +
 .../internal/commandline/AbstractCommand.java      |  70 --
 .../internal/commandline/ActivateCommand.java      |  75 ---
 .../internal/commandline/ArgumentParser.java       | 508 +++++++++++++++
 .../internal/commandline/BaselineCommand.java      | 316 ---------
 .../commandline/ClusterChangeTagCommand.java       | 115 ----
 .../commandline/ClusterStateChangeCommand.java     | 130 ----
 .../ignite/internal/commandline/Command.java       | 281 --------
 .../internal/commandline/CommandArgIterator.java   | 216 -------
 .../internal/commandline/CommandHandler.java       | 400 +++++++++---
 .../internal/commandline/CommandInvoker.java       | 316 +++++++++
 .../ignite/internal/commandline/CommandList.java   | 167 -----
 .../ignite/internal/commandline/CommandLogger.java |  99 ---
 .../internal/commandline/CommandsProvider.java     |   5 +-
 .../internal/commandline/CommonArgParser.java      | 402 ------------
 .../commandline/ConnectionAndSslParameters.java    | 186 +++---
 .../internal/commandline/DeactivateCommand.java    | 108 ----
 .../commandline/DefragmentationCommand.java        | 248 -------
 .../ignite/internal/commandline/OutputFormat.java  |  66 --
 .../internal/commandline/PersistenceCommand.java   | 288 ---------
 .../commandline/ShutdownPolicyCommand.java         | 106 ---
 .../ignite/internal/commandline/StateCommand.java  |  97 ---
 .../commandline/StringBuilderOutputStream.java     |  69 --
 .../ignite/internal/commandline/TaskExecutor.java  | 198 ------
 .../commandline/TracingConfigurationCommand.java   | 334 ----------
 .../ignite/internal/commandline/TxCommandArg.java  |  78 ---
 .../ignite/internal/commandline/TxCommands.java    | 558 ----------------
 .../ignite/internal/commandline/WalCommands.java   | 270 --------
 .../ignite/internal/commandline/WarmUpCommand.java | 127 ----
 .../internal/commandline/argument/CommandArg.java  |  28 -
 .../commandline/argument/CommandArgUtils.java      |  46 --
 .../commandline/argument/parser/CLIArgument.java   |  38 +-
 .../argument/parser/CLIArgumentParser.java         | 121 ++--
 .../commandline/baseline/BaselineArguments.java    | 173 -----
 .../commandline/baseline/BaselineSubcommands.java  | 116 ----
 .../internal/commandline/cache/CacheClear.java     | 117 ----
 .../internal/commandline/cache/CacheCommands.java  | 148 -----
 .../commandline/cache/CacheContention.java         | 146 -----
 .../internal/commandline/cache/CacheCreate.java    | 124 ----
 .../internal/commandline/cache/CacheDestroy.java   | 162 -----
 .../commandline/cache/CacheDistribution.java       | 169 -----
 .../cache/CacheIndexesForceRebuild.java            | 263 --------
 .../commandline/cache/CacheIndexesList.java        | 264 --------
 .../cache/CacheIndexesRebuildStatus.java           | 172 -----
 .../internal/commandline/cache/CacheMetrics.java   | 133 ----
 .../internal/commandline/cache/CacheScan.java      | 128 ----
 .../cache/CacheScheduleIndexesRebuild.java         | 334 ----------
 .../commandline/cache/CacheSubcommands.java        | 201 ------
 .../commandline/cache/CacheValidateIndexes.java    | 337 ----------
 .../commandline/cache/FindAndDeleteGarbage.java    | 192 ------
 .../internal/commandline/cache/IdleVerify.java     | 411 ------------
 .../commandline/cache/ResetLostPartitions.java     |  79 ---
 .../cache/argument/DistributionCommandArg.java     |  47 --
 .../cache/argument/FindAndDeleteGarbageArg.java    |  51 --
 .../cache/argument/IdleVerifyCommandArg.java       |  59 --
 .../cache/argument/IndexRebuildCommandArg.java     |  55 --
 .../commandline/cache/argument/ListCommandArg.java |  56 --
 .../cache/argument/ValidateIndexesCommandArg.java  |  56 --
 .../internal/commandline/cdc/CdcCommand.java       |  69 --
 .../internal/commandline/cdc/CdcSubcommands.java   |  66 --
 .../cdc/DeleteLostSegmentLinksCommand.java         | 135 ----
 .../internal/commandline/cdc/ResendCommand.java    | 115 ----
 .../consistency/ConsistencyCommand.java            | 264 --------
 .../consistency/ConsistencySubCommand.java         |  77 ---
 .../defragmentation/DefragmentationArguments.java  |  63 --
 .../DefragmentationSubcommands.java                |  68 --
 .../commandline/diagnostic/DiagnosticCommand.java  | 123 ----
 .../diagnostic/DiagnosticSubCommand.java           |  77 ---
 .../commandline/diagnostic/PageLocksCommand.java   | 249 -------
 .../encryption/CacheGroupEncryptionCommand.java    | 264 --------
 .../encryption/ChangeCacheGroupKeyCommand.java     |  95 ---
 .../encryption/ChangeMasterKeyCommand.java         |  88 ---
 .../commandline/encryption/EncryptionCommands.java |  70 --
 .../encryption/EncryptionSubcommands.java          |  99 ---
 .../encryption/GetMasterKeyNameCommand.java        |  73 ---
 .../encryption/ReencryptionRateCommand.java        | 137 ----
 .../commandline/indexreader/IgniteIndexReader.java |  12 +-
 .../internal/commandline/meta/MetadataCommand.java | 152 -----
 .../commandline/meta/MetadataSubCommandsList.java  |  78 ---
 .../subcommands/MetadataAbstractSubCommand.java    | 124 ----
 .../meta/subcommands/MetadataHelpCommand.java      |  49 --
 .../meta/subcommands/MetadataListCommand.java      |  55 --
 .../meta/subcommands/MetadataRemoveCommand.java    | 115 ----
 .../meta/subcommands/MetadataUpdateCommand.java    |  87 ---
 .../internal/commandline/metric/MetricCommand.java | 188 ------
 .../commandline/metric/MetricCommandArg.java       |  50 --
 .../PerformanceStatisticsCommand.java              | 107 ---
 .../PerformanceStatisticsSubCommand.java           |  80 ---
 .../persistence/CleanAndBackupSubcommandArg.java   |  45 --
 .../persistence/PersistenceArguments.java          | 100 ---
 .../persistence/PersistenceSubcommands.java        |  73 ---
 .../commandline/property/PropertyCommand.java      | 100 ---
 .../property/PropertySubCommandsList.java          |  73 ---
 .../subcommands/PropertyAbstractSubCommand.java    | 106 ---
 .../property/subcommands/PropertyGetCommand.java   |  62 --
 .../property/subcommands/PropertyHelpCommand.java  |  49 --
 .../property/subcommands/PropertyListCommand.java  |  49 --
 .../property/subcommands/PropertySetCommand.java   |  71 --
 .../internal/commandline/query/KillCommand.java    | 287 --------
 .../internal/commandline/query/KillSubcommand.java |  65 --
 .../shutdown/ShutdownPolicyArgument.java           |  72 ---
 .../snapshot/SnapshotCancelCommand.java            |  84 ---
 .../snapshot/SnapshotCancelCommandOption.java      |  71 --
 .../commandline/snapshot/SnapshotCheckCommand.java | 101 ---
 .../snapshot/SnapshotCheckCommandOption.java       |  73 ---
 .../commandline/snapshot/SnapshotCommand.java      |  71 --
 .../snapshot/SnapshotCreateCommand.java            |  99 ---
 .../snapshot/SnapshotCreateCommandOption.java      |  78 ---
 .../snapshot/SnapshotRestoreCommand.java           | 209 ------
 .../snapshot/SnapshotRestoreCommandOption.java     |  84 ---
 .../commandline/snapshot/SnapshotSubcommand.java   | 105 ---
 .../commandline/snapshot/SnapshotSubcommands.java  |  79 ---
 .../commandline/systemview/SystemViewCommand.java  | 278 --------
 .../systemview/SystemViewCommandArg.java           |  55 --
 .../TracingConfigurationArguments.java             | 180 ------
 .../TracingConfigurationCommandArg.java            |  79 ---
 .../TracingConfigurationSubcommand.java            | 104 ---
 .../commandline/CommandHandlerParsingTest.java     | 719 +++++++++++----------
 .../GridCommandHandlerSslWithSecurityTest.java     |   3 +-
 .../testsuites/IgniteControlUtilityTestSuite.java  |   2 +-
 .../ignite/util/CacheMetricsCommandTest.java       |  43 +-
 .../org/apache/ignite/util/CdcCommandTest.java     |  62 +-
 .../apache/ignite/util/CdcResendCommandTest.java   |   8 +-
 .../util/GridCommandHandlerAbstractTest.java       |   9 +-
 .../util/GridCommandHandlerBrokenIndexTest.java    |   3 +-
 ...CommandHandlerCheckIncrementalSnapshotTest.java |  10 +-
 .../util/GridCommandHandlerClusterByClassTest.java | 412 +++++++-----
 .../GridCommandHandlerConsistencyCountersTest.java |  22 +-
 ...sistencyRepairCorrectnessTransactionalTest.java |  21 +-
 .../util/GridCommandHandlerConsistencyTest.java    |  22 +-
 .../GridCommandHandlerIndexForceRebuildTest.java   |   2 +-
 .../util/GridCommandHandlerIndexListTest.java      |   6 +-
 .../GridCommandHandlerIndexingCheckSizeTest.java   |  31 +-
 ...idCommandHandlerIndexingClusterByClassTest.java |   2 +-
 .../util/GridCommandHandlerMetadataTest.java       |   6 +-
 ...GridCommandHandlerScheduleIndexRebuildTest.java |   2 +-
 .../apache/ignite/util/GridCommandHandlerTest.java | 193 +++---
 ...GridCommandHandlerTracingConfigurationTest.java |   2 +-
 .../ignite/util/KillCommandsControlShTest.java     |  21 +-
 .../org/apache/ignite/util/MetricCommandTest.java  |  82 +--
 .../util/PerformanceStatisticsCommandTest.java     |  47 +-
 .../apache/ignite/util/SystemViewCommandTest.java  |  73 ++-
 .../ignite/internal/TransactionsMXBeanImpl.java    |  54 +-
 .../CheckIndexInlineSizesTask.java                 |  11 +-
 .../cache/distribution/CacheDistributionTask.java  |  19 +-
 .../distribution/CacheDistributionTaskArg.java     |  94 ---
 .../distribution/CacheDistributionTaskResult.java  |  50 +-
 .../CacheResetLostPartitionsTask.java              |  49 +-
 .../CacheResetLostPartitionsTaskArg.java           |  72 ---
 .../CacheResetLostPartitionsTaskResult.java        |   8 +-
 .../commandline/meta/tasks/MetadataInfoTask.java   |  35 +-
 .../commandline/meta/tasks/MetadataRemoveTask.java |  15 +-
 .../commandline/meta/tasks/MetadataTypeArgs.java   | 101 ---
 .../commandline/meta/tasks/MetadataUpdateTask.java |  14 +-
 .../commandline/property/PropertyArgs.java         | 117 ----
 .../property/tasks/PropertiesListTask.java         |  11 +-
 .../commandline/property/tasks/PropertyTask.java   |  50 +-
 .../internal/management/ActivateCommand.java       |  55 ++
 .../internal/management/ChangeTagCommand.java      |  58 ++
 .../ChangeTagCommandArg.java}                      |  49 +-
 .../internal/management/DeactivateCommand.java     |  70 ++
 .../DeactivateCommandArg.java}                     |  64 +-
 .../internal/management/IgniteCommandRegistry.java |  82 +++
 .../internal/management/SetStateCommand.java       |  59 ++
 .../internal/management/SetStateCommandArg.java    | 104 +++
 .../internal/management/ShutdownPolicyCommand.java |  50 ++
 .../ShutdownPolicyCommandArg.java}                 |  52 +-
 .../ignite/internal/management/StateCommand.java   |  74 +++
 .../internal/management/SystemViewCommand.java     | 161 +++++
 .../internal/management/SystemViewCommandArg.java  | 117 ++++
 .../WarmUpCommand.java}                            |  29 +-
 .../internal/management/WarmUpStopCommand.java}    |  42 +-
 .../ignite/internal/management/api/Argument.java   |  55 ++
 .../internal/management/api/ArgumentGroup.java     |  43 ++
 .../api/BeforeNodeStartCommand.java}               |  29 +-
 .../api/CliConfirmArgument.java}                   |  19 +-
 .../api/CliSubcommandsWithPrefix.java}             |  34 +-
 .../ignite/internal/management/api/Command.java    |  64 ++
 .../management/api/CommandRegistryImpl.java        |  88 +++
 .../internal/management/api/CommandUtils.java      | 558 ++++++++++++++++
 .../internal/management/api/CommandsRegistry.java} |  41 +-
 .../internal/management/api/ComputeCommand.java    |  55 ++
 .../api/EnumDescription.java}                      |  22 +-
 .../api/HelpCommand.java}                          |  14 +-
 .../api/LocalCommand.java}                         |  29 +-
 .../ignite/internal/management/api/NoArg.java}     |  32 +-
 .../api/Positional.java}                           |  36 +-
 .../api/PreparableCommand.java}                    |  36 +-
 .../baseline/AbstractBaselineCommand.java          | 169 +++++
 .../management/baseline/BaselineAddCommand.java}   |  31 +-
 .../baseline/BaselineAddCommandArg.java}           |  56 +-
 .../baseline/BaselineAutoAdjustCommand.java}       |  31 +-
 .../baseline/BaselineAutoAdjustCommandArg.java     |  90 +++
 .../management/baseline/BaselineCommand.java       | 111 ++++
 .../baseline/BaselineCommandArg.java}              |  16 +-
 .../baseline/BaselineRemoveCommand.java}           |  31 +-
 .../baseline/BaselineRemoveCommandArg.java}        |  17 +-
 .../management/baseline/BaselineSetCommand.java}   |  31 +-
 .../baseline/BaselineSetCommandArg.java}           |  17 +-
 .../baseline/BaselineVersionCommand.java}          |  31 +-
 .../baseline/BaselineVersionCommandArg.java}       |  62 +-
 .../cache/CacheCheckIndexInlineSizesCommand.java}  | 108 ++--
 .../management/cache/CacheClearCommand.java        |  66 ++
 .../cache/CacheClearCommandArg.java}               |  40 +-
 .../internal/management/cache/CacheCommand.java    |  57 ++
 .../management/cache/CacheContentionCommand.java   |  61 ++
 .../cache/CacheContentionCommandArg.java}          |  68 +-
 .../management/cache/CacheCreateCommand.java}      |  43 +-
 .../management/cache/CacheCreateCommandArg.java    |  90 +++
 .../management/cache/CacheDestroyCommand.java      |  91 +++
 .../cache/CacheDestroyCommandArg.java}             |  71 +-
 .../management/cache/CacheDistributionCommand.java |  62 ++
 .../cache/CacheDistributionCommandArg.java         | 115 ++++
 .../management/cache/CacheFindGarbageCommand.java  |  82 +++
 .../cache/CacheFindGarbageCommandArg.java          | 140 ++++
 .../management/cache/CacheIdleVerifyCommand.java   | 109 ++++
 .../cache/CacheIdleVerifyCommandArg.java           | 143 ++++
 .../cache/CacheIdleVerifyDumpCommand.java          |  47 ++
 .../cache/CacheIdleVerifyDumpCommandArg.java}      |  14 +-
 .../cache/CacheIndexesForceRebuildCommand.java     | 110 ++++
 .../cache/CacheIndexesForceRebuildCommandArg.java} |  66 +-
 .../management/cache/CacheIndexesListCommand.java  |  75 +++
 .../cache/CacheIndexesListCommandArg.java          | 136 ++++
 .../cache/CacheIndexesRebuildStatusCommand.java    |  86 +++
 .../CacheIndexesRebuildStatusCommandArg.java}      |  39 +-
 .../management/cache/CacheListCommand.java}        | 399 +++++-------
 .../management/cache/CacheListCommandArg.java      | 143 ++++
 .../management/cache/CacheMetricsCommand.java      |  62 ++
 .../management/cache/CacheMetricsCommandArg.java   |  93 +++
 .../cache/CacheResetLostPartitionsCommand.java     |  51 ++
 .../cache/CacheResetLostPartitionsCommandArg.java} |  42 +-
 .../management/cache/CacheScanCommand.java         |  56 ++
 .../cache/CacheScanCommandArg.java}                |  76 +--
 .../cache/CacheScheduleIndexesRebuildCommand.java  | 135 ++++
 .../CacheScheduleIndexesRebuildCommandArg.java     | 161 +++++
 .../cache/CacheValidateIndexesCommand.java         | 131 ++++
 .../cache/CacheValidateIndexesCommandArg.java      | 198 ++++++
 .../cdc/CdcCommand.java}                           |  21 +-
 .../cdc/CdcDeleteLostSegmentLinksCommand.java      |  74 +++
 .../cdc/CdcDeleteLostSegmentLinksCommandArg.java}  |  39 +-
 .../internal/management/cdc/CdcResendCommand.java  |  51 ++
 .../cdc/CdcResendCommandArg.java}                  |  43 +-
 .../consistency/ConsistencyCommand.java}           |  22 +-
 .../consistency/ConsistencyFinalizeCommand.java}   |  43 +-
 .../consistency/ConsistencyRepairCommand.java      | 120 ++++
 .../consistency/ConsistencyRepairCommandArg.java   | 115 ++++
 .../consistency/ConsistencyStatusCommand.java      |  69 ++
 .../DefragmentationCancelCommand.java              |  53 ++
 .../defragmentation/DefragmentationCommand.java    |  58 ++
 .../DefragmentationScheduleCommand.java            |  77 +++
 .../DefragmentationScheduleCommandArg.java}        |  64 +-
 .../DefragmentationStatusCommand.java              |  52 ++
 .../management/diagnostic/DiagnosticCommand.java   |  52 ++
 .../diagnostic/DiagnosticConnectivityCommand.java} | 120 ++--
 .../DiagnosticConnectivityCommandArg.java}         |  43 +-
 .../diagnostic/DiagnosticPagelocksCommand.java     |  77 +++
 .../diagnostic/DiagnosticPagelocksCommandArg.java  | 133 ++++
 .../encryption/CacheGroupEncryptionCommand.java    |  70 ++
 .../encryption/EncryptionCacheGroupArg.java}       |  51 +-
 .../encryption/EncryptionCacheKeyIdsCommand.java   |  66 ++
 .../EncryptionChangeCacheKeyCommand.java           |  51 ++
 .../EncryptionChangeMasterKeyCommand.java          |  51 ++
 .../EncryptionChangeMasterKeyCommandArg.java}      |  51 +-
 .../encryption/EncryptionCommand.java}             |  36 +-
 .../EncryptionGetMasterKeyNameCommand.java}        |  40 +-
 .../EncryptionReencryptionRateLimitCommand.java    |  94 +++
 ...EncryptionReencryptionRateLimitCommandArg.java} |  53 +-
 .../EncryptionReencryptionStatusCommand.java       |  50 ++
 .../EncryptionReencryptionStatusCommandArg.java}   |  49 +-
 .../EncryptionResumeReencryptionCommand.java       |  46 ++
 .../EncryptionSuspendReencryptionCommand.java      |  46 ++
 .../management/kill/KillClientCommand.java         |  52 ++
 .../kill/KillClientCommandArg.java}                |  73 +--
 .../kill/KillCommand.java}                         |  35 +-
 .../management/kill/KillComputeCommand.java}       |  41 +-
 .../kill/KillComputeCommandArg.java}               |  53 +-
 .../management/kill/KillConsistencyCommand.java    |  49 ++
 .../management/kill/KillContinuousCommand.java}    |  32 +-
 .../kill/KillContinuousCommandArg.java}            |  80 +--
 .../internal/management/kill/KillScanCommand.java} |  32 +-
 .../kill/KillScanCommandArg.java}                  |  99 ++-
 .../management/kill/KillServiceCommand.java}       |  36 +-
 .../kill/KillServiceCommandArg.java}               |  51 +-
 .../management/kill/KillSnapshotCommand.java}      |  42 +-
 .../kill/KillSnapshotCommandArg.java}              |  60 +-
 .../internal/management/kill/KillSqlCommand.java}  |  32 +-
 .../kill/KillSqlCommandArg.java}                   |  86 ++-
 .../management/kill/KillTransactionCommand.java    |  51 ++
 .../kill/KillTransactionCommandArg.java}           |  51 +-
 .../internal/management/meta/MetaCommand.java}     |  53 +-
 .../management/meta/MetaDetailsCommand.java}       |  63 +-
 .../meta/MetaDetailsCommandArg.java}               |  77 +--
 .../internal/management/meta/MetaListCommand.java  |  65 ++
 .../management/meta/MetaRemoveCommand.java         |  84 +++
 .../meta/MetaRemoveCommandArg.java}                |  76 ++-
 .../management/meta/MetaUpdateCommand.java         |  62 ++
 .../meta/MetaUpdateCommandArg.java}                |  70 +-
 .../internal/management/metric/MetricCommand.java  |  82 +++
 .../metric/MetricCommandArg.java}                  |  55 +-
 .../metric/MetricConfigureHistogramCommand.java    |  50 ++
 .../MetricConfigureHistogramCommandArg.java}       |  57 +-
 .../metric/MetricConfigureHitrateCommand.java      |  50 ++
 .../metric/MetricConfigureHitrateCommandArg.java}  |  57 +-
 .../PerformanceStatisticsCommand.java              |  70 ++
 .../PerformanceStatisticsRotateCommand.java        |  41 ++
 .../PerformanceStatisticsStartCommand.java         |  41 ++
 .../PerformanceStatisticsStatusCommand.java        |  41 ++
 .../PerformanceStatisticsStopCommand.java          |  41 ++
 .../persistence/PersistenceAbstractCommand.java    | 122 ++++
 .../persistence/PersistenceBackupAllCommand.java}  |  23 +-
 .../PersistenceBackupCachesCommand.java}           |  21 +-
 .../PersistenceBackupCachesTaskArg.java}           |  53 +-
 .../persistence/PersistenceBackupCommand.java}     |  27 +-
 .../PersistenceBackupCorruptedCommand.java}        |  23 +-
 .../persistence/PersistenceCleanAllCommand.java}   |  23 +-
 .../PersistenceCleanCachesCommand.java}            |  21 +-
 .../PersistenceCleanCachesTaskArg.java}            |  53 +-
 .../persistence/PersistenceCleanCommand.java}      |  22 +-
 .../PersistenceCleanCorruptedCommand.java}         |  23 +-
 .../management/persistence/PersistenceCommand.java | 108 ++++
 .../persistence/PersistenceInfoCommand.java}       |  23 +-
 .../management/property/PropertyCommand.java}      |  41 +-
 .../management/property/PropertyGetCommand.java    |  46 ++
 .../property/PropertyGetCommandArg.java}           |  49 +-
 .../management/property/PropertyListCommand.java   |  48 ++
 .../management/property/PropertySetCommand.java}   |  36 +-
 .../property/PropertySetCommandArg.java}           |  54 +-
 .../snapshot/AbstractSnapshotCommand.java}         |  44 +-
 .../snapshot/SnapshotCancelCommand.java}           |  32 +-
 .../snapshot/SnapshotCancelCommandArg.java}        |  72 ++-
 .../management/snapshot/SnapshotCheckCommand.java  |  52 ++
 .../snapshot/SnapshotCheckCommandArg.java          |  94 +++
 .../snapshot/SnapshotCommand.java}                 |  24 +-
 .../snapshot/SnapshotCreateCommand.java}           |  31 +-
 .../snapshot/SnapshotCreateCommandArg.java         | 111 ++++
 .../snapshot/SnapshotRestoreCommand.java           |  58 ++
 .../snapshot/SnapshotRestoreCommandArg.java        | 211 ++++++
 .../snapshot/SnapshotStatusCommand.java            |  76 +--
 .../AbstractTracingConfigurationCommand.java       |  53 ++
 .../tracing/TracingConfigurationCommand.java       | 109 ++++
 .../TracingConfigurationGetAllCommand.java}        |  24 +-
 .../TracingConfigurationGetAllCommandArg.java}     |  56 +-
 .../tracing/TracingConfigurationGetCommand.java}   |  24 +-
 .../TracingConfigurationGetCommandArg.java}        |  59 +-
 .../TracingConfigurationResetAllCommand.java       |  39 ++
 .../tracing/TracingConfigurationResetCommand.java} |  43 +-
 .../tracing/TracingConfigurationSetCommand.java}   |  37 +-
 .../tracing/TracingConfigurationSetCommandArg.java |  82 +++
 .../ignite/internal/management/tx/TxCommand.java   | 105 +++
 .../internal/management/tx/TxCommandArg.java       | 222 +++++++
 .../internal/management/tx/TxInfoCommand.java      | 287 ++++++++
 .../internal/management/tx/TxInfoCommandArg.java   | 131 ++++
 .../wal/WalCommand.java}                           |  23 +-
 .../internal/management/wal/WalDeleteCommand.java  |  82 +++
 .../wal/WalDeleteCommandArg.java}                  |  53 +-
 .../internal/management/wal/WalPrintCommand.java   |  87 +++
 .../internal/processors/cache/ClearCachesTask.java |  11 +-
 .../verify/VerifyBackupPartitionsDumpTask.java     |  18 +-
 .../cache/verify/VerifyBackupPartitionsTask.java   | 364 -----------
 .../cache/verify/VerifyBackupPartitionsTaskV2.java |  14 +-
 .../apache/ignite/internal/util/IgniteUtils.java   |  53 ++
 .../visor/baseline/VisorBaselineOperation.java     |  51 --
 .../internal/visor/baseline/VisorBaselineTask.java |  47 +-
 .../visor/baseline/VisorBaselineTaskArg.java       | 126 ----
 .../internal/visor/cache/VisorCacheCreateTask.java |  18 +-
 .../internal/visor/cache/VisorCacheScanTask.java   |  19 +-
 .../internal/visor/cache/VisorCacheStopTask.java   |  18 +-
 .../visor/cache/VisorCacheStopTaskArg.java         |  99 ---
 ...orFindAndDeleteGarbageInPersistenceClosure.java |   4 +-
 ...VisorFindAndDeleteGarbageInPersistenceTask.java |  23 +-
 ...orFindAndDeleteGarbageInPersistenceTaskArg.java | 101 ---
 .../visor/cache/index/IndexForceRebuildTask.java   |  16 +-
 .../internal/visor/cache/index/IndexListTask.java  |  19 +-
 .../visor/cache/index/IndexListTaskArg.java        |  94 ---
 .../visor/cache/index/IndexRebuildStatusTask.java  |  13 +-
 .../cache/index/ScheduleIndexRebuildTask.java      |  19 +-
 .../cache/index/ScheduleIndexRebuildTaskArg.java   |  84 ---
 .../visor/cache/metrics/VisorCacheMetricsTask.java |  15 +-
 .../cache/metrics/VisorCacheMetricsTaskArg.java    |  84 ---
 .../visor/cdc/VisorCdcCacheDataResendTask.java     |  13 +-
 .../visor/cdc/VisorCdcDeleteLostSegmentsTask.java  |  12 +-
 .../client/VisorClientConnectionDropTask.java      |  18 +-
 .../compute/VisorComputeCancelSessionTask.java     |  13 +-
 .../compute/VisorComputeCancelSessionTaskArg.java  |  73 ---
 .../consistency/VisorConsistencyCancelTask.java    |  11 +-
 .../VisorConsistencyCountersFinalizationTask.java  |  11 +-
 .../consistency/VisorConsistencyRepairTask.java    |  21 +-
 .../consistency/VisorConsistencyRepairTaskArg.java |  97 ---
 .../consistency/VisorConsistencyStatusTask.java    |  11 +-
 .../defragmentation/VisorDefragmentationTask.java  |  43 +-
 .../internal/visor/diagnostic/Operation.java       |   2 +-
 .../visor/diagnostic/VisorPageLocksTask.java       |  40 +-
 .../availability/VisorConnectivityArgs.java        |  68 --
 .../availability/VisorConnectivityTask.java        |  21 +-
 .../encryption/VisorCacheGroupEncryptionTask.java  |  13 +-
 .../VisorCacheGroupEncryptionTaskArg.java          |  68 --
 .../encryption/VisorChangeCacheGroupKeyTask.java   |  13 +-
 .../visor/encryption/VisorChangeMasterKeyTask.java |  13 +-
 .../encryption/VisorEncryptionKeyIdsTask.java      |   7 +-
 .../encryption/VisorGetMasterKeyNameTask.java      |  11 +-
 .../encryption/VisorReencryptionRateTask.java      |  17 +-
 .../encryption/VisorReencryptionRateTaskArg.java   |  74 ---
 .../encryption/VisorReencryptionResumeTask.java    |   7 +-
 .../encryption/VisorReencryptionStatusTask.java    |   7 +-
 .../encryption/VisorReencryptionSuspendTask.java   |   7 +-
 .../internal/visor/metric/VisorMetricTask.java     |  22 +-
 .../internal/visor/metric/VisorMetricTaskArg.java  |  94 ---
 .../visor/misc/VisorClusterChangeTagTask.java      |  16 +-
 .../ignite/internal/visor/misc/VisorWalTask.java   |  34 +-
 .../internal/visor/misc/VisorWalTaskArg.java       |  98 ---
 .../VisorPerformanceStatisticsTask.java            |  49 +-
 .../VisorPerformanceStatisticsTaskArg.java         |  64 --
 .../visor/persistence/PersistenceTask.java         |  75 +--
 .../visor/persistence/PersistenceTaskArg.java      |  82 ---
 .../query/VisorContinuousQueryCancelTask.java      |  18 +-
 .../query/VisorQueryCancelOnInitiatorTask.java     |  13 +-
 .../visor/query/VisorScanQueryCancelTask.java      |  14 +-
 .../visor/service/VisorCancelServiceTask.java      |  13 +-
 .../visor/shutdown/VisorShutdownPolicyTask.java    |  17 +-
 .../visor/shutdown/VisorShutdownPolicyTaskArg.java |  76 ---
 .../visor/snapshot/VisorSnapshotCancelTask.java    |  21 +-
 .../visor/snapshot/VisorSnapshotCancelTaskArg.java |  85 ---
 .../visor/snapshot/VisorSnapshotCheckTask.java     |  13 +-
 .../visor/snapshot/VisorSnapshotCheckTaskArg.java  |  92 ---
 .../visor/snapshot/VisorSnapshotCreateTask.java    |  15 +-
 .../visor/snapshot/VisorSnapshotCreateTaskArg.java | 115 ----
 .../visor/snapshot/VisorSnapshotRestoreTask.java   |  53 +-
 .../snapshot/VisorSnapshotRestoreTaskAction.java   |  46 --
 .../snapshot/VisorSnapshotRestoreTaskArg.java      | 120 ----
 .../visor/snapshot/VisorSnapshotStatusTask.java    |  13 +-
 .../visor/systemview/VisorSystemViewTask.java      |  14 +-
 .../VisorTracingConfigurationOperation.java        |  56 --
 .../VisorTracingConfigurationTask.java             |  58 +-
 .../VisorTracingConfigurationTaskArg.java          | 103 ---
 .../internal/visor/tx/FetchNearXidVersionTask.java |  13 +-
 .../internal/visor/tx/KillTransactionTask.java     |  71 ++
 .../ignite/internal/visor/tx/VisorTxTask.java      | 128 ++--
 .../ignite/internal/visor/tx/VisorTxTaskArg.java   | 244 -------
 .../internal/visor/verify/VisorContentionTask.java |  11 +-
 .../visor/verify/VisorContentionTaskArg.java       |  84 ---
 .../visor/verify/VisorIdleVerifyDumpTask.java      |   5 +-
 .../visor/verify/VisorIdleVerifyDumpTaskArg.java   | 124 ----
 .../internal/visor/verify/VisorIdleVerifyJob.java  |  12 +-
 .../internal/visor/verify/VisorIdleVerifyTask.java | 111 ----
 .../visor/verify/VisorIdleVerifyTaskArg.java       | 220 -------
 .../visor/verify/VisorIdleVerifyTaskResult.java    |  76 ---
 .../visor/verify/VisorIdleVerifyTaskV2.java        |   5 +-
 .../visor/verify/VisorValidateIndexesTask.java     |  29 +-
 .../visor/verify/VisorValidateIndexesTaskArg.java  | 158 -----
 .../internal/visor/verify/VisorViewCacheTask.java  |  22 +-
 .../visor/verify/VisorViewCacheTaskArg.java        |  85 ---
 .../org/apache/ignite/lang/IgniteExperimental.java |   3 +
 .../main/resources/META-INF/classnames.properties  | 207 +++---
 ...inaryConfigurationCustomSerializerSelfTest.java |   8 +-
 .../management/api/CommandUtilsSelfTest.java       |  67 ++
 .../MaintenancePersistenceTaskTest.java            |  23 +-
 .../snapshot/IgniteClusterSnapshotCheckTest.java   |  18 +-
 .../IncrementalSnapshotRestoreTest.java            |  12 +-
 .../cache/transactions/TxRollbackAsyncTest.java    |   9 +-
 .../junits/common/GridCommonAbstractTest.java      |   6 +-
 .../ignite/testsuites/IgniteUtilSelfTestSuite.java |   4 +-
 .../GridInternalTaskUnusedWalSegmentsTest.java     |  12 +-
 ...mandHandlerClusterByClassTest_cache_help.output | 113 ++--
 ...ridCommandHandlerClusterByClassTest_help.output | 159 +++--
 ...dlerClusterByClassWithSSLTest_cache_help.output | 113 ++--
 ...andHandlerClusterByClassWithSSLTest_help.output | 159 +++--
 .../commandline/CommandsProviderExtImpl.java       |  81 ++-
 .../commandline/ExtendedControlUtilityTest.java    |  38 +-
 .../db/IgniteCacheGroupsWithRestartsTest.java      |  11 +-
 .../db/LongDestroyDurableBackgroundTaskTest.java   |  16 +-
 .../processors/query/h2/GridIndexRebuildTest.java  |  22 +-
 471 files changed, 14844 insertions(+), 23512 deletions(-)

diff --git a/modules/control-utility/pom.xml b/modules/control-utility/pom.xml
index 636a58590f2..56964c5a55a 100644
--- a/modules/control-utility/pom.xml
+++ b/modules/control-utility/pom.xml
@@ -128,6 +128,13 @@
             <version>1.3</version>
             <scope>test</scope>
         </dependency>
+
+        <dependency>
+            <groupId>io.github.java-diff-utils</groupId>
+            <artifactId>java-diff-utils</artifactId>
+            <version>4.12</version>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 
     <build>
diff --git a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/AbstractCommand.java b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/AbstractCommand.java
deleted file mode 100644
index d30526f0720..00000000000
--- a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/AbstractCommand.java
+++ /dev/null
@@ -1,70 +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.ignite.internal.commandline;
-
-import java.util.Map;
-import org.apache.ignite.IgniteLogger;
-import org.apache.ignite.internal.client.GridClientConfiguration;
-import org.apache.ignite.internal.commandline.cache.CacheSubcommands;
-import org.apache.ignite.internal.util.typedef.F;
-
-import static org.apache.ignite.internal.commandline.CommandList.CACHE;
-import static org.apache.ignite.internal.commandline.CommandLogger.DOUBLE_INDENT;
-import static org.apache.ignite.internal.commandline.CommandLogger.INDENT;
-
-/**
- * Abstract class for control.sh commands, that support verbose mode.
- */
-public abstract class AbstractCommand<T> implements Command<T> {
-    /** Use verbose mode or not. */
-    protected boolean verbose;
-
-    /** {@inheritDoc} */
-    @Override public Object execute(GridClientConfiguration clientCfg, IgniteLogger log, boolean verbose) throws Exception {
-        this.verbose = verbose;
-        return execute(clientCfg, log);
-    }
-
-    /**
-     * Print cache command usage with default indention.
-     *
-     * @param logger Logger to use.
-     * @param cmd Cache command.
-     * @param description Command description.
-     * @param paramsDesc Parameter desciptors.
-     * @param args Cache command arguments.
-     */
-    protected void usageCache(
-        IgniteLogger logger,
-        CacheSubcommands cmd,
-        String description,
-        Map<String, String> paramsDesc,
-        String... args
-    ) {
-        logger.info("");
-        logger.info(INDENT + CommandLogger.join(" ", CACHE, cmd, CommandLogger.join(" ", args)));
-        logger.info(DOUBLE_INDENT + description);
-
-        if (!F.isEmpty(paramsDesc)) {
-            logger.info("");
-            logger.info(DOUBLE_INDENT + "Parameters:");
-
-            usageParams(paramsDesc, DOUBLE_INDENT + INDENT, logger);
-        }
-    }
-}
diff --git a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/ActivateCommand.java b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/ActivateCommand.java
deleted file mode 100644
index 2e3e0dee74d..00000000000
--- a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/ActivateCommand.java
+++ /dev/null
@@ -1,75 +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.ignite.internal.commandline;
-
-import org.apache.ignite.IgniteLogger;
-import org.apache.ignite.internal.client.GridClient;
-import org.apache.ignite.internal.client.GridClientClusterState;
-import org.apache.ignite.internal.client.GridClientConfiguration;
-import org.apache.ignite.internal.client.GridClientException;
-
-import static org.apache.ignite.cluster.ClusterState.ACTIVE;
-import static org.apache.ignite.internal.commandline.CommandList.ACTIVATE;
-import static org.apache.ignite.internal.commandline.CommandList.SET_STATE;
-
-/**
- * Activate cluster command.
- * @deprecated Use {@link ClusterStateChangeCommand} instead.
- */
-@Deprecated
-public class ActivateCommand extends AbstractCommand<Void> {
-    /** {@inheritDoc} */
-    @Override public void printUsage(IgniteLogger logger) {
-        usage(logger, "Activate cluster (deprecated. Use " + SET_STATE.toString() + " instead):", ACTIVATE);
-    }
-
-    /**
-     * Activate cluster.
-     *
-     * @param cfg Client configuration.
-     * @throws GridClientException If failed to activate.
-     */
-    @Override public Object execute(GridClientConfiguration cfg, IgniteLogger logger) throws Exception {
-        logger.warning("Command deprecated. Use " + SET_STATE.toString() + " instead.");
-
-        try (GridClient client = Command.startClient(cfg)) {
-            GridClientClusterState state = client.state();
-
-            state.state(ACTIVE, false);
-
-            logger.info("Cluster activated");
-        }
-        catch (Throwable e) {
-            logger.error("Failed to activate cluster.");
-
-            throw e;
-        }
-
-        return null;
-    }
-
-    /** {@inheritDoc} */
-    @Override public Void arg() {
-        return null;
-    }
-
-    /** {@inheritDoc} */
-    @Override public String name() {
-        return ACTIVATE.toCommandName();
-    }
-}
diff --git a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/ArgumentParser.java b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/ArgumentParser.java
new file mode 100644
index 00000000000..885f70deee6
--- /dev/null
+++ b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/ArgumentParser.java
@@ -0,0 +1,508 @@
+/*
+ * 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.ignite.internal.commandline;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.function.BiConsumer;
+import java.util.function.BiFunction;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import org.apache.ignite.IgniteException;
+import org.apache.ignite.IgniteLogger;
+import org.apache.ignite.IgniteSystemProperties;
+import org.apache.ignite.internal.client.GridClientConfiguration;
+import org.apache.ignite.internal.commandline.argument.parser.CLIArgument;
+import org.apache.ignite.internal.commandline.argument.parser.CLIArgumentParser;
+import org.apache.ignite.internal.dto.IgniteDataTransferObject;
+import org.apache.ignite.internal.management.IgniteCommandRegistry;
+import org.apache.ignite.internal.management.api.Argument;
+import org.apache.ignite.internal.management.api.ArgumentGroup;
+import org.apache.ignite.internal.management.api.BeforeNodeStartCommand;
+import org.apache.ignite.internal.management.api.CliSubcommandsWithPrefix;
+import org.apache.ignite.internal.management.api.Command;
+import org.apache.ignite.internal.management.api.CommandsRegistry;
+import org.apache.ignite.internal.management.api.ComputeCommand;
+import org.apache.ignite.internal.management.api.HelpCommand;
+import org.apache.ignite.internal.management.api.LocalCommand;
+import org.apache.ignite.internal.management.api.Positional;
+import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.lang.IgniteExperimental;
+import org.apache.ignite.ssl.SslContextFactory;
+
+import static org.apache.ignite.IgniteSystemProperties.IGNITE_ENABLE_EXPERIMENTAL_COMMAND;
+import static org.apache.ignite.internal.client.GridClientConfiguration.DFLT_PING_INTERVAL;
+import static org.apache.ignite.internal.client.GridClientConfiguration.DFLT_PING_TIMEOUT;
+import static org.apache.ignite.internal.commandline.CommandHandler.DFLT_HOST;
+import static org.apache.ignite.internal.commandline.CommandHandler.DFLT_PORT;
+import static org.apache.ignite.internal.commandline.CommandHandler.UTILITY_NAME;
+import static org.apache.ignite.internal.commandline.argument.parser.CLIArgument.optionalArg;
+import static org.apache.ignite.internal.management.api.CommandUtils.CMD_WORDS_DELIM;
+import static org.apache.ignite.internal.management.api.CommandUtils.NAME_PREFIX;
+import static org.apache.ignite.internal.management.api.CommandUtils.PARAM_WORDS_DELIM;
+import static org.apache.ignite.internal.management.api.CommandUtils.asOptional;
+import static org.apache.ignite.internal.management.api.CommandUtils.fromFormattedCommandName;
+import static org.apache.ignite.internal.management.api.CommandUtils.isBoolean;
+import static org.apache.ignite.internal.management.api.CommandUtils.parameterExample;
+import static org.apache.ignite.internal.management.api.CommandUtils.toFormattedCommandName;
+import static org.apache.ignite.internal.management.api.CommandUtils.toFormattedFieldName;
+import static org.apache.ignite.internal.management.api.CommandUtils.toFormattedNames;
+import static org.apache.ignite.internal.management.api.CommandUtils.visitCommandParams;
+import static org.apache.ignite.ssl.SslContextFactory.DFLT_SSL_PROTOCOL;
+
+/**
+ * Argument parser.
+ * Also would parse high-level command and delegate parsing for its argument to the command.
+ */
+public class ArgumentParser {
+    /** */
+    private final IgniteLogger log;
+
+    /** */
+    private final IgniteCommandRegistry registry;
+
+    /** */
+    Command<?, ?> root;
+
+    /** */
+    Command<?, ?> cmd;
+
+    /** */
+    static final String CMD_HOST = "--host";
+
+    /** */
+    static final String CMD_PORT = "--port";
+
+    /** */
+    static final String CMD_PASSWORD = "--password";
+
+    /** */
+    static final String CMD_USER = "--user";
+
+    /** Option is used for auto confirmation. */
+    public static final String CMD_AUTO_CONFIRMATION = "--yes";
+
+    /** Ping interval for grid client. See {@link GridClientConfiguration#getPingInterval()}. */
+    static final String CMD_PING_INTERVAL = "--ping-interval";
+
+    /** Ping timeout for grid client. See {@link GridClientConfiguration#getPingTimeout()}. */
+    static final String CMD_PING_TIMEOUT = "--ping-timeout";
+
+    /** Verbose mode. */
+    public static final String CMD_VERBOSE = "--verbose";
+
+    // SSL configuration section
+
+    /** */
+    static final String CMD_SSL_PROTOCOL = "--ssl-protocol";
+
+    /** */
+    static final String CMD_SSL_KEY_ALGORITHM = "--ssl-key-algorithm";
+
+    /** */
+    static final String CMD_SSL_CIPHER_SUITES = "--ssl-cipher-suites";
+
+    /** */
+    static final String CMD_KEYSTORE = "--keystore";
+
+    /** */
+    static final String CMD_KEYSTORE_PASSWORD = "--keystore-password";
+
+    /** */
+    static final String CMD_KEYSTORE_TYPE = "--keystore-type";
+
+    /** */
+    static final String CMD_TRUSTSTORE = "--truststore";
+
+    /** */
+    static final String CMD_TRUSTSTORE_PASSWORD = "--truststore-password";
+
+    /** */
+    static final String CMD_TRUSTSTORE_TYPE = "--truststore-type";
+
+    /** */
+    static final String CMD_ENABLE_EXPERIMENTAL = "--enable-experimental";
+
+    /** */
+    static final String CMD_SSL_FACTORY = "--ssl-factory";
+
+    /** Set of sensitive arguments */
+    private static final Set<String> SENSITIVE_ARGUMENTS = new HashSet<>();
+
+    /** */
+    private static final BiConsumer<String, Integer> PORT_VALIDATOR = (name, val) -> {
+        if (val <= 0 || val > 65535)
+            throw new IllegalArgumentException("Invalid value for " + name + ": " + val);
+    };
+
+    /** */
+    private static final BiConsumer<String, Long> POSITIVE_LONG = (name, val) -> {
+        if (val <= 0)
+            throw new IllegalArgumentException("Invalid value for " + name + ": " + val);
+    };
+
+    /** */
+    private final List<CLIArgument<?>> common = new ArrayList<>();
+
+    static {
+        SENSITIVE_ARGUMENTS.add(CMD_PASSWORD);
+        SENSITIVE_ARGUMENTS.add(CMD_KEYSTORE_PASSWORD);
+        SENSITIVE_ARGUMENTS.add(CMD_TRUSTSTORE_PASSWORD);
+    }
+
+    /**
+     * @param arg To check.
+     * @return True if provided argument is among sensitive one and not should be displayed.
+     */
+    public static boolean isSensitiveArgument(String arg) {
+        return SENSITIVE_ARGUMENTS.contains(arg);
+    }
+
+    /**
+     * @param log Logger.
+     * @param registry Supported commands.
+     */
+    public ArgumentParser(IgniteLogger log, IgniteCommandRegistry registry) {
+        this.log = log;
+        this.registry = registry;
+
+        BiConsumer<String, ?> securityWarn = (name, val) -> log.info(String.format("Warning: %s is insecure. " +
+                "Whenever possible, use interactive prompt for password (just discard %s option).", name, name));
+
+        arg(CMD_HOST, "HOST_OR_IP", String.class, DFLT_HOST);
+        arg(CMD_PORT, "PORT", Integer.class, DFLT_PORT, PORT_VALIDATOR);
+        arg(CMD_USER, "USER", String.class, null);
+        arg(CMD_PASSWORD, "PASSWORD", String.class, null, (BiConsumer<String, String>)securityWarn);
+        arg(CMD_PING_INTERVAL, "PING_INTERVAL", Long.class, DFLT_PING_INTERVAL, POSITIVE_LONG);
+        arg(CMD_PING_TIMEOUT, "PING_TIMEOUT", Long.class, DFLT_PING_TIMEOUT, POSITIVE_LONG);
+        arg(CMD_VERBOSE, CMD_VERBOSE, boolean.class, false);
+        arg(CMD_SSL_PROTOCOL, "SSL_PROTOCOL[, SSL_PROTOCOL_2, ..., SSL_PROTOCOL_N]", String[].class, new String[] {DFLT_SSL_PROTOCOL});
+        arg(CMD_SSL_CIPHER_SUITES, "SSL_CIPHER_1[, SSL_CIPHER_2, ..., SSL_CIPHER_N]", String[].class, null);
+        arg(CMD_SSL_KEY_ALGORITHM, "SSL_KEY_ALGORITHM", String.class, SslContextFactory.DFLT_KEY_ALGORITHM);
+        arg(CMD_SSL_FACTORY, "SSL_FACTORY_PATH", String.class, null);
+        arg(CMD_KEYSTORE_TYPE, "KEYSTORE_TYPE", String.class, SslContextFactory.DFLT_STORE_TYPE);
+        arg(CMD_KEYSTORE, "KEYSTORE_PATH", String.class, null);
+        arg(CMD_KEYSTORE_PASSWORD, "KEYSTORE_PASSWORD", char[].class, null, (BiConsumer<String, char[]>)securityWarn);
+        arg(CMD_TRUSTSTORE_TYPE, "TRUSTSTORE_TYPE", String.class, SslContextFactory.DFLT_STORE_TYPE);
+        arg(CMD_TRUSTSTORE, "TRUSTSTORE_PATH", String.class, null);
+        arg(CMD_TRUSTSTORE_PASSWORD, "TRUSTSTORE_PASSWORD", char[].class, null, (BiConsumer<String, char[]>)securityWarn);
+        arg(CMD_AUTO_CONFIRMATION, CMD_AUTO_CONFIRMATION, boolean.class, false);
+        arg(
+            CMD_ENABLE_EXPERIMENTAL,
+            CMD_ENABLE_EXPERIMENTAL, Boolean.class,
+            IgniteSystemProperties.getBoolean(IGNITE_ENABLE_EXPERIMENTAL_COMMAND)
+        );
+    }
+
+    /** */
+    private <T> void arg(String name, String usage, Class<T> type, T dflt, BiConsumer<String, T> validator) {
+        common.add(optionalArg(name, usage, type, t -> dflt, validator));
+    }
+
+    /** */
+    private <T> void arg(String name, String usage, Class<T> type, T dflt) {
+        common.add(optionalArg(name, usage, type, () -> dflt));
+    }
+
+    /**
+     * Creates list of common utility options.
+     *
+     * @return Array of common utility options.
+     */
+    public String[] getCommonOptions() {
+        List<String> list = new ArrayList<>();
+
+        for (CLIArgument<?> arg : common) {
+            if (arg.name().equals(CMD_AUTO_CONFIRMATION))
+                continue;
+
+            if (isBoolean(arg.type()))
+                list.add(asOptional(arg.name(), true));
+            else
+                list.add(asOptional(arg.name() + " " + arg.usage(), true));
+        }
+
+        return list.toArray(U.EMPTY_STRS);
+    }
+
+    /**
+     * Parses and validates arguments.
+     *
+     * @param raw Raw arguments.
+     * @return Arguments bean.
+     * @throws IllegalArgumentException In case arguments aren't valid.
+     */
+    <A extends IgniteDataTransferObject> ConnectionAndSslParameters<A> parseAndValidate(List<String> raw) {
+        List<String> args = new ArrayList<>(raw);
+
+        findCommand(args.iterator());
+
+        CLIArgumentParser parser = createArgumentParser();
+
+        parser.parse(args.iterator());
+
+        A arg = (A)argument(
+            cmd.argClass(),
+            (fld, pos) -> parser.get(pos),
+            fld -> parser.get(toFormattedFieldName(fld).toLowerCase())
+        );
+
+        if (!parser.<Boolean>get(CMD_ENABLE_EXPERIMENTAL) && cmd.getClass().isAnnotationPresent(IgniteExperimental.class)) {
+            log.warning(
+                String.format("To use experimental command add " + CMD_ENABLE_EXPERIMENTAL + " parameter for %s",
+                    UTILITY_NAME)
+            );
+
+            throw new IllegalArgumentException("Experimental commands disabled");
+        }
+
+        return new ConnectionAndSslParameters<>((Command<A, ?>)cmd, root, arg, parser);
+    }
+
+    /**
+     * Searches command from hierarchical root.
+     *
+     * @param iter Iterator of CLI arguments.
+     */
+    protected void findCommand(Iterator<String> iter) {
+        assert cmd == null && root == null;
+
+        while (iter.hasNext() && cmd == null) {
+            String cmdName = iter.next();
+
+            if (!cmdName.startsWith(NAME_PREFIX))
+                continue;
+
+            cmd = registry.command(fromFormattedCommandName(cmdName.substring(NAME_PREFIX.length()), CMD_WORDS_DELIM));
+        }
+
+        if (cmd == null)
+            throw new IllegalArgumentException("No action was specified");
+
+        // Remove command name parameter to exclude it from ongoing parsing.
+        iter.remove();
+
+        while (cmd instanceof CommandsRegistry && iter.hasNext()) {
+            String name = iter.next();
+
+            char delim = PARAM_WORDS_DELIM;
+
+            if (cmd.getClass().isAnnotationPresent(CliSubcommandsWithPrefix.class)) {
+                if (!name.startsWith(NAME_PREFIX))
+                    break;
+
+                name = name.substring(NAME_PREFIX.length());
+
+                delim = CMD_WORDS_DELIM;
+            }
+
+            Command<?, ?> cmd1 = ((CommandsRegistry<?, ?>)cmd).command(fromFormattedCommandName(name, delim));
+
+            if (cmd1 == null)
+                break;
+
+            root = cmd;
+            cmd = cmd1;
+
+            // Remove command name parameter to exclude it from ongoing parsing.
+            iter.remove();
+        }
+
+        if (!(cmd instanceof ComputeCommand)
+            && !(cmd instanceof LocalCommand)
+            && !(cmd instanceof BeforeNodeStartCommand)
+            && !(cmd instanceof HelpCommand)) {
+            throw new IllegalArgumentException(
+                "Command " + toFormattedCommandName(cmd.getClass()) + " can't be executed"
+            );
+        }
+    }
+
+    /** */
+    private CLIArgumentParser createArgumentParser() {
+        assert cmd != null;
+
+        List<CLIArgument<?>> positionalArgs = new ArrayList<>();
+        List<CLIArgument<?>> namedArgs = new ArrayList<>();
+
+        BiFunction<Field, Boolean, CLIArgument<?>> toArg = (fld, optional) -> new CLIArgument<>(
+            toFormattedFieldName(fld).toLowerCase(),
+            null,
+            optional,
+            fld.getType(),
+            null,
+            (name, val) -> {}
+        );
+
+        ArgumentGroup argGrp = cmd.argClass().getAnnotation(ArgumentGroup.class);
+        Set<String> grpdFlds = argGrp == null
+            ? Collections.emptySet()
+            : new HashSet<>(Arrays.asList(argGrp.value()));
+
+        Consumer<Field> namedArgCb = fld -> namedArgs.add(
+            toArg.apply(fld, grpdFlds.contains(fld.getName()) || fld.getAnnotation(Argument.class).optional())
+        );
+
+        Consumer<Field> positionalArgCb = fld -> positionalArgs.add(new CLIArgument<>(
+            fld.getName().toLowerCase(),
+            null,
+            fld.getAnnotation(Argument.class).optional(),
+            fld.getType(),
+            null,
+            (name, val) -> {}
+        ));
+
+        BiConsumer<ArgumentGroup, List<Field>> argGrpCb = (argGrp0, flds) -> flds.forEach(fld -> {
+            if (fld.isAnnotationPresent(Positional.class))
+                positionalArgCb.accept(fld);
+            else
+                namedArgCb.accept(fld);
+        });
+
+        visitCommandParams(cmd.argClass(), positionalArgCb, namedArgCb, argGrpCb);
+
+        namedArgs.addAll(common);
+
+        return new CLIArgumentParser(positionalArgs, namedArgs);
+    }
+
+    /**
+     * Fill and vaildate command argument.
+     *
+     * @param argCls Argument class.
+     * @param positionalParamProvider Provider of positional parameters.
+     * @param paramProvider Provider of named parameters.
+     * @return Argument filled with parameters.
+     * @param <A> Argument type.
+     */
+    private static <A extends IgniteDataTransferObject> A argument(
+        Class<A> argCls,
+        BiFunction<Field, Integer, Object> positionalParamProvider,
+        Function<Field, Object> paramProvider
+    ) {
+        try {
+            ArgumentState<A> arg = new ArgumentState<>(argCls);
+
+            visitCommandParams(
+                argCls,
+                fld -> arg.accept(fld, positionalParamProvider.apply(fld, arg.nextIdx())),
+                fld -> arg.accept(fld, paramProvider.apply(fld)),
+                (argGrp, flds) -> flds.forEach(fld -> {
+                    if (fld.isAnnotationPresent(Positional.class))
+                        arg.accept(fld, positionalParamProvider.apply(fld, arg.nextIdx()));
+                    else
+                        arg.accept(fld, paramProvider.apply(fld));
+                })
+            );
+
+            if (arg.argGrp != null && (!arg.grpOptional() && !arg.grpFldExists))
+                throw new IllegalArgumentException("One of " + toFormattedNames(argCls, arg.grpdFlds) + " required");
+
+            return arg.res;
+        }
+        catch (InstantiationException | IllegalAccessException e) {
+            throw new IgniteException(e);
+        }
+    }
+
+    /** */
+    private static class ArgumentState<A extends IgniteDataTransferObject> implements BiConsumer<Field, Object> {
+        /** */
+        final A res;
+
+        /** */
+        final ArgumentGroup argGrp;
+
+        /** */
+        boolean grpFldExists;
+
+        /** */
+        int idx;
+
+        /** */
+        final Set<String> grpdFlds;
+
+        /** */
+        public ArgumentState(Class<A> argCls) throws InstantiationException, IllegalAccessException {
+            res = argCls.newInstance();
+            argGrp = argCls.getAnnotation(ArgumentGroup.class);
+            grpdFlds = argGrp == null
+                ? Collections.emptySet()
+                : new HashSet<>(Arrays.asList(argGrp.value()));
+        }
+
+        /** */
+        public boolean grpOptional() {
+            return argGrp == null || argGrp.optional();
+        }
+
+        /** */
+        private int nextIdx() {
+            int idx0 = idx;
+
+            idx++;
+
+            return idx0;
+        }
+
+        /** {@inheritDoc} */
+        @Override public void accept(Field fld, Object val) {
+            boolean grpdFld = grpdFlds.contains(fld.getName());
+
+            if (val == null) {
+                if (grpdFld || fld.getAnnotation(Argument.class).optional())
+                    return;
+
+                String name = fld.isAnnotationPresent(Positional.class)
+                    ? parameterExample(fld, false)
+                    : toFormattedFieldName(fld);
+
+                throw new IllegalArgumentException("Argument " + name + " required.");
+            }
+
+            if (grpdFld) {
+                if (grpFldExists && (argGrp != null && argGrp.onlyOneOf())) {
+                    throw new IllegalArgumentException(
+                        "Only one of " + toFormattedNames(res.getClass(), grpdFlds) + " allowed"
+                    );
+                }
+
+                grpFldExists = true;
+            }
+
+            try {
+                res.getClass().getMethod(fld.getName(), fld.getType()).invoke(res, val);
+            }
+            catch (NoSuchMethodException | IllegalAccessException e) {
+                throw new IgniteException(e);
+            }
+            catch (InvocationTargetException e) {
+                if (e.getTargetException() != null && e.getTargetException() instanceof RuntimeException)
+                    throw (RuntimeException)e.getTargetException();
+            }
+        }
+    }
+}
diff --git a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/BaselineCommand.java b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/BaselineCommand.java
deleted file mode 100644
index ceac31aaba7..00000000000
--- a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/BaselineCommand.java
+++ /dev/null
@@ -1,316 +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.ignite.internal.commandline;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.Set;
-import java.util.UUID;
-import java.util.function.Function;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-import org.apache.ignite.IgniteLogger;
-import org.apache.ignite.internal.client.GridClient;
-import org.apache.ignite.internal.client.GridClientConfiguration;
-import org.apache.ignite.internal.client.GridClientNode;
-import org.apache.ignite.internal.commandline.argument.CommandArgUtils;
-import org.apache.ignite.internal.commandline.baseline.AutoAdjustCommandArg;
-import org.apache.ignite.internal.commandline.baseline.BaselineArguments;
-import org.apache.ignite.internal.commandline.baseline.BaselineSubcommands;
-import org.apache.ignite.internal.util.typedef.F;
-import org.apache.ignite.internal.visor.baseline.VisorBaselineAutoAdjustSettings;
-import org.apache.ignite.internal.visor.baseline.VisorBaselineNode;
-import org.apache.ignite.internal.visor.baseline.VisorBaselineTask;
-import org.apache.ignite.internal.visor.baseline.VisorBaselineTaskArg;
-import org.apache.ignite.internal.visor.baseline.VisorBaselineTaskResult;
-import org.apache.ignite.internal.visor.util.VisorTaskUtils;
-
-import static java.lang.Boolean.TRUE;
-import static java.util.Collections.singletonMap;
-import static org.apache.ignite.internal.commandline.CommandHandler.DELIM;
-import static org.apache.ignite.internal.commandline.CommandList.BASELINE;
-import static org.apache.ignite.internal.commandline.CommandLogger.DOUBLE_INDENT;
-import static org.apache.ignite.internal.commandline.CommandLogger.optional;
-import static org.apache.ignite.internal.commandline.CommonArgParser.CMD_AUTO_CONFIRMATION;
-import static org.apache.ignite.internal.commandline.TaskExecutor.executeTaskByNameOnNode;
-import static org.apache.ignite.internal.commandline.baseline.BaselineSubcommands.of;
-
-/**
- * Commands associated with baseline functionality.
- */
-public class BaselineCommand extends AbstractCommand<BaselineArguments> {
-    /** Arguments. */
-    private BaselineArguments baselineArgs;
-
-    /** {@inheritDoc} */
-    @Override public void printUsage(IgniteLogger logger) {
-        final String constistIds = "consistentId1[,consistentId2,....,consistentIdN]";
-
-        usage(logger, "Print cluster baseline topology:", BASELINE,
-            singletonMap("verbose", "Show the full list of node ips."), optional("--verbose"));
-        usage(logger, "Add nodes into baseline topology:", BASELINE, BaselineSubcommands.ADD.text(),
-            constistIds, optional(CMD_AUTO_CONFIRMATION));
-        usage(logger, "Remove nodes from baseline topology:", BASELINE, BaselineSubcommands.REMOVE.text(),
-            constistIds, optional(CMD_AUTO_CONFIRMATION));
-        usage(logger, "Set baseline topology:", BASELINE, BaselineSubcommands.SET.text(), constistIds,
-            optional(CMD_AUTO_CONFIRMATION));
-        usage(logger, "Set baseline topology based on version:", BASELINE,
-            BaselineSubcommands.VERSION.text() + " topologyVersion", optional(CMD_AUTO_CONFIRMATION));
-        usage(logger, "Set baseline autoadjustment settings:", BASELINE,
-            BaselineSubcommands.AUTO_ADJUST.text(), "[disable|enable] [timeout <timeoutMillis>]", optional(CMD_AUTO_CONFIRMATION));
-    }
-
-    /** {@inheritDoc} */
-    @Override public String confirmationPrompt() {
-        if (baselineArgs != null && BaselineSubcommands.COLLECT != baselineArgs.getCmd())
-            return "Warning: the command will perform changes in baseline.";
-
-        return null;
-    }
-
-    /**
-     * Change baseline.
-     *
-     * @param clientCfg Client configuration.
-     * @throws Exception If failed to execute baseline action.
-     */
-    @Override public Object execute(GridClientConfiguration clientCfg, IgniteLogger logger) throws Exception {
-        try (GridClient client = Command.startClient(clientCfg)) {
-            UUID coordinatorId = client.compute()
-                //Only non client node can be coordinator.
-                .nodes(node -> !node.isClient())
-                .stream()
-                .min(Comparator.comparingLong(GridClientNode::order))
-                .map(GridClientNode::nodeId)
-                .orElse(null);
-
-            VisorBaselineTaskResult res = executeTaskByNameOnNode(
-                client,
-                VisorBaselineTask.class.getName(),
-                toVisorArguments(baselineArgs),
-                coordinatorId,
-                clientCfg
-            );
-
-            baselinePrint0(res, logger);
-        }
-        catch (Throwable e) {
-            logger.error("Failed to execute baseline command='" + baselineArgs.getCmd().text() + "'");
-            logger.error(CommandLogger.errorMessage(e));
-
-            throw e;
-        }
-
-        return null;
-    }
-
-    /** {@inheritDoc} */
-    @Override public BaselineArguments arg() {
-        return baselineArgs;
-    }
-
-    /**
-     * Prepare task argument.
-     *
-     * @param args Argument from command line.
-     * @return Task argument.
-     */
-    private VisorBaselineTaskArg toVisorArguments(BaselineArguments args) {
-        VisorBaselineAutoAdjustSettings settings = args.getCmd() == BaselineSubcommands.AUTO_ADJUST
-            ? new VisorBaselineAutoAdjustSettings(args.getEnableAutoAdjust(), args.getSoftBaselineTimeout())
-            : null;
-
-        return new VisorBaselineTaskArg(args.getCmd().visorBaselineOperation(), args.getTopVer(), args.getConsistentIds(), settings);
-    }
-
-    /**
-     * Print baseline topology.
-     *
-     * @param res Task result with baseline topology.
-     */
-    private void baselinePrint0(VisorBaselineTaskResult res, IgniteLogger logger) {
-        logger.info("Cluster state: " + (res.isActive() ? "active" : "inactive"));
-        logger.info("Current topology version: " + res.getTopologyVersion());
-        VisorBaselineAutoAdjustSettings autoAdjustSettings = res.getAutoAdjustSettings();
-
-        if (autoAdjustSettings != null) {
-            logger.info("Baseline auto adjustment " + (TRUE.equals(autoAdjustSettings.getEnabled()) ? "enabled" : "disabled")
-                + ": softTimeout=" + autoAdjustSettings.getSoftTimeout()
-            );
-        }
-
-        if (autoAdjustSettings.enabled) {
-            if (res.isBaselineAdjustInProgress())
-                logger.info("Baseline auto-adjust is in progress");
-            else if (res.getRemainingTimeToBaselineAdjust() < 0)
-                logger.info("Baseline auto-adjust are not scheduled");
-            else
-                logger.info("Baseline auto-adjust will happen in '" + res.getRemainingTimeToBaselineAdjust() + "' ms");
-        }
-
-        logger.info("");
-
-        Map<String, VisorBaselineNode> baseline = res.getBaseline();
-
-        Map<String, VisorBaselineNode> srvs = res.getServers();
-
-        // if task runs on a node with VisorBaselineNode of old version (V1) we'll get order=null for all nodes.
-        Function<VisorBaselineNode, String> extractFormattedAddrs = node -> {
-            Stream<String> sortedByIpHosts =
-                Optional.ofNullable(node)
-                    .map(addrs -> node.getAddrs())
-                    .orElse(Collections.emptyList())
-                    .stream()
-                    .sorted(Comparator
-                        .comparing(resolvedAddr -> new VisorTaskUtils.SortableAddress(resolvedAddr.address())))
-                    .map(resolvedAddr -> {
-                        if (!resolvedAddr.hostname().equals(resolvedAddr.address()))
-                            return resolvedAddr.hostname() + "/" + resolvedAddr.address();
-                        else
-                            return resolvedAddr.address();
-                    });
-            if (verbose) {
-                String hosts = String.join(",", sortedByIpHosts.collect(Collectors.toList()));
-
-                if (!hosts.isEmpty())
-                    return ", Addresses=" + hosts;
-                else
-                    return "";
-            }
-            else
-                return sortedByIpHosts.findFirst().map(ip -> ", Address=" + ip).orElse("");
-        };
-
-        String crdStr = srvs.values().stream()
-            // check for not null
-            .filter(node -> node.getOrder() != null)
-            .min(Comparator.comparing(VisorBaselineNode::getOrder))
-            // format
-            .map(crd -> " (Coordinator: ConsistentId=" + crd.getConsistentId() + extractFormattedAddrs.apply(crd) +
-                ", Order=" + crd.getOrder() + ")")
-            .orElse("");
-
-        logger.info("Current topology version: " + res.getTopologyVersion() + crdStr);
-        logger.info("");
-
-        if (F.isEmpty(baseline))
-            logger.info("Baseline nodes not found.");
-        else {
-            logger.info("Baseline nodes:");
-
-            for (VisorBaselineNode node : baseline.values()) {
-                VisorBaselineNode srvNode = srvs.get(node.getConsistentId());
-
-                String state = ", State=" + (srvNode != null ? "ONLINE" : "OFFLINE");
-
-                String order = srvNode != null ? ", Order=" + srvNode.getOrder() : "";
-
-                logger.info(DOUBLE_INDENT + "ConsistentId=" + node.getConsistentId() +
-                    extractFormattedAddrs.apply(srvNode) + state + order);
-            }
-
-            logger.info(DELIM);
-            logger.info("Number of baseline nodes: " + baseline.size());
-
-            logger.info("");
-
-            List<VisorBaselineNode> others = new ArrayList<>();
-
-            for (VisorBaselineNode node : srvs.values()) {
-                if (!baseline.containsKey(node.getConsistentId()))
-                    others.add(node);
-            }
-
-            if (F.isEmpty(others))
-                logger.info("Other nodes not found.");
-            else {
-                logger.info("Other nodes:");
-
-                for (VisorBaselineNode node : others)
-                    logger.info(DOUBLE_INDENT + "ConsistentId=" + node.getConsistentId() + ", Order=" + node.getOrder());
-
-                logger.info("Number of other nodes: " + others.size());
-            }
-        }
-    }
-
-    /** {@inheritDoc} */
-    @Override public void parseArguments(CommandArgIterator argIter) {
-        if (!argIter.hasNextSubArg()) {
-            this.baselineArgs = new BaselineArguments.Builder(BaselineSubcommands.COLLECT).build();
-
-            return;
-        }
-
-        BaselineSubcommands cmd = of(argIter.nextArg("Expected baseline action"));
-
-        if (cmd == null)
-            throw new IllegalArgumentException("Expected correct baseline action");
-
-        BaselineArguments.Builder baselineArgs = new BaselineArguments.Builder(cmd);
-
-        switch (cmd) {
-            case ADD:
-            case REMOVE:
-            case SET:
-                Set<String> ids = argIter.nextStringSet("list of consistent ids");
-
-                if (F.isEmpty(ids))
-                    throw new IllegalArgumentException("Empty list of consistent IDs");
-
-                baselineArgs.withConsistentIds(new ArrayList<>(ids));
-
-                break;
-
-            case VERSION:
-                baselineArgs.withTopVer(argIter.nextNonNegativeLongArg("topology version"));
-
-                break;
-
-            case AUTO_ADJUST:
-                do {
-                    AutoAdjustCommandArg autoAdjustArg = CommandArgUtils.of(
-                        argIter.nextArg("Expected one of auto-adjust arguments"), AutoAdjustCommandArg.class
-                    );
-
-                    if (autoAdjustArg == null)
-                        throw new IllegalArgumentException("Expected one of auto-adjust arguments");
-
-                    if (autoAdjustArg == AutoAdjustCommandArg.ENABLE || autoAdjustArg == AutoAdjustCommandArg.DISABLE)
-                        baselineArgs.withEnable(autoAdjustArg == AutoAdjustCommandArg.ENABLE);
-
-                    if (autoAdjustArg == AutoAdjustCommandArg.TIMEOUT)
-                        baselineArgs.withSoftBaselineTimeout(argIter.nextNonNegativeLongArg("soft timeout"));
-                }
-                while (argIter.hasNextSubArg());
-
-                break;
-        }
-
-        this.baselineArgs = baselineArgs.build();
-    }
-
-    /** {@inheritDoc} */
-    @Override public String name() {
-        return BASELINE.toCommandName();
-    }
-}
diff --git a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/ClusterChangeTagCommand.java b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/ClusterChangeTagCommand.java
deleted file mode 100644
index 521b318c70a..00000000000
--- a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/ClusterChangeTagCommand.java
+++ /dev/null
@@ -1,115 +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.ignite.internal.commandline;
-
-import java.util.Comparator;
-import java.util.UUID;
-import org.apache.ignite.IgniteLogger;
-import org.apache.ignite.internal.client.GridClient;
-import org.apache.ignite.internal.client.GridClientConfiguration;
-import org.apache.ignite.internal.client.GridClientNode;
-import org.apache.ignite.internal.visor.misc.VisorClusterChangeTagTask;
-import org.apache.ignite.internal.visor.misc.VisorClusterChangeTagTaskArg;
-import org.apache.ignite.internal.visor.misc.VisorClusterChangeTagTaskResult;
-
-import static org.apache.ignite.internal.commandline.CommandList.CLUSTER_CHANGE_TAG;
-import static org.apache.ignite.internal.commandline.CommandLogger.optional;
-import static org.apache.ignite.internal.commandline.CommonArgParser.CMD_AUTO_CONFIRMATION;
-import static org.apache.ignite.internal.commandline.TaskExecutor.executeTaskByNameOnNode;
-
-/**
- * Command to access cluster ID and tag functionality.
- */
-public class ClusterChangeTagCommand extends AbstractCommand<String> {
-    /** */
-    private static final String ERR_NO_NEW_TAG_PROVIDED = "Please provide new tag.";
-
-    /** */
-    private static final String ERR_EMPTY_TAG_PROVIDED = "Please provide non-empty tag.";
-
-    /** */
-    private String newTagArg;
-
-    /** {@inheritDoc} */
-    @Override public Object execute(GridClientConfiguration clientCfg, IgniteLogger logger) throws Exception {
-        try (GridClient client = Command.startClient(clientCfg)) {
-            UUID coordinatorId = client.compute().nodes().stream()
-                .min(Comparator.comparingLong(GridClientNode::order))
-                .map(GridClientNode::nodeId)
-                .orElse(null);
-
-            VisorClusterChangeTagTaskResult res = executeTaskByNameOnNode(
-                client,
-                VisorClusterChangeTagTask.class.getName(),
-                toVisorArguments(),
-                coordinatorId,
-                clientCfg
-            );
-
-            if (res.success())
-                logger.info("Cluster tag updated successfully, old tag was: " + res.tag());
-            else
-                logger.warning("Error has occurred during tag update: " + res.errorMessage());
-        }
-        catch (Throwable e) {
-            logger.error("Failed to execute Cluster ID and tag command: ");
-            logger.error(CommandLogger.errorMessage(e));
-
-            throw e;
-        }
-
-        return null;
-    }
-
-    /** {@inheritDoc} */
-    @Override public String arg() {
-        return newTagArg;
-    }
-
-    /** {@inheritDoc} */
-    @Override public void printUsage(IgniteLogger logger) {
-        usage(logger, "Change cluster tag to new value:", CLUSTER_CHANGE_TAG,
-            "newTagValue", optional(CMD_AUTO_CONFIRMATION));
-    }
-
-    /** {@inheritDoc} */
-    @Override public void parseArguments(CommandArgIterator argIter) {
-        if (!argIter.hasNextSubArg())
-            throw new IllegalArgumentException(ERR_NO_NEW_TAG_PROVIDED);
-
-        newTagArg = argIter.nextArg(ERR_NO_NEW_TAG_PROVIDED);
-
-        if (newTagArg == null || newTagArg.isEmpty())
-            throw new IllegalArgumentException(ERR_EMPTY_TAG_PROVIDED);
-    }
-
-    /** {@inheritDoc} */
-    @Override public String name() {
-        return CLUSTER_CHANGE_TAG.toCommandName();
-    }
-
-    /** {@inheritDoc} */
-    @Override public String confirmationPrompt() {
-        return "Warning: the command will change cluster tag.";
-    }
-
-    /** */
-    private VisorClusterChangeTagTaskArg toVisorArguments() {
-        return new VisorClusterChangeTagTaskArg(newTagArg);
-    }
-}
diff --git a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/ClusterStateChangeCommand.java b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/ClusterStateChangeCommand.java
deleted file mode 100644
index fd540435bca..00000000000
--- a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/ClusterStateChangeCommand.java
+++ /dev/null
@@ -1,130 +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.ignite.internal.commandline;
-
-import java.util.LinkedHashMap;
-import java.util.Map;
-import org.apache.ignite.IgniteLogger;
-import org.apache.ignite.cluster.ClusterState;
-import org.apache.ignite.internal.client.GridClient;
-import org.apache.ignite.internal.client.GridClientConfiguration;
-
-import static org.apache.ignite.cluster.ClusterState.ACTIVE;
-import static org.apache.ignite.cluster.ClusterState.ACTIVE_READ_ONLY;
-import static org.apache.ignite.cluster.ClusterState.INACTIVE;
-import static org.apache.ignite.internal.commandline.CommandList.SET_STATE;
-import static org.apache.ignite.internal.commandline.CommandLogger.optional;
-import static org.apache.ignite.internal.commandline.CommandLogger.or;
-import static org.apache.ignite.internal.commandline.CommonArgParser.CMD_AUTO_CONFIRMATION;
-
-/**
- * Command to change cluster state.
- */
-public class ClusterStateChangeCommand extends AbstractCommand<ClusterState> {
-    /** Flag of forced cluster deactivation. */
-    static final String FORCE_COMMAND = "--force";
-
-    /** New cluster state */
-    private ClusterState state;
-
-    /** Cluster name. */
-    private String clusterName;
-
-    /** If {@code true}, cluster deactivation will be forced. */
-    private boolean forceDeactivation;
-
-    /** {@inheritDoc} */
-    @Override public void printUsage(IgniteLogger log) {
-        Map<String, String> params = new LinkedHashMap<>();
-
-        params.put(ACTIVE.toString(), "Activate cluster. Cache updates are allowed.");
-        params.put(INACTIVE.toString(), "Deactivate cluster.");
-        params.put(ACTIVE_READ_ONLY.toString(), "Activate cluster. Cache updates are denied.");
-
-        usage(log, "Change cluster state:", SET_STATE, params, or((Object[])ClusterState.values()),
-            optional(FORCE_COMMAND), optional(CMD_AUTO_CONFIRMATION));
-    }
-
-    /** {@inheritDoc} */
-    @Override public void prepareConfirmation(GridClientConfiguration clientCfg) throws Exception {
-        try (GridClient client = Command.startClient(clientCfg)) {
-            clusterName = client.state().clusterName();
-        }
-    }
-
-    /** {@inheritDoc} */
-    @Override public String confirmationPrompt() {
-        return "Warning: the command will change state of cluster with name \"" + clusterName + "\" to " + state + ".";
-    }
-
-    /** {@inheritDoc} */
-    @Override public Object execute(GridClientConfiguration clientCfg, IgniteLogger log) throws Exception {
-        try (GridClient client = Command.startClient(clientCfg)) {
-            ClusterState clusterState = client.state().state();
-
-            if (clusterState == state)
-                log.info("Cluster state is already " + state + '.');
-            else {
-                client.state().state(state, forceDeactivation);
-
-                log.info("Cluster state changed to " + state + '.');
-            }
-
-            return null;
-        }
-        catch (Throwable e) {
-            log.info("Failed to change cluster state to " + state);
-
-            throw e;
-        }
-    }
-
-    /** {@inheritDoc} */
-    @Override public void parseArguments(CommandArgIterator argIter) {
-        String s = argIter.nextArg("New cluster state not found.");
-
-        try {
-            state = ClusterState.valueOf(s.toUpperCase());
-        }
-        catch (IllegalArgumentException e) {
-            throw new IllegalArgumentException("Can't parse new cluster state. State: " + s, e);
-        }
-
-        forceDeactivation = false;
-
-        if (argIter.hasNextArg()) {
-            String arg = argIter.peekNextArg();
-
-            if (FORCE_COMMAND.equalsIgnoreCase(arg)) {
-                forceDeactivation = true;
-
-                argIter.nextArg("");
-            }
-        }
-    }
-
-    /** {@inheritDoc} */
-    @Override public ClusterState arg() {
-        return state;
-    }
-
-    /** {@inheritDoc} */
-    @Override public String name() {
-        return SET_STATE.toCommandName();
-    }
-}
diff --git a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/Command.java b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/Command.java
deleted file mode 100644
index b4b9209e637..00000000000
--- a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/Command.java
+++ /dev/null
@@ -1,281 +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.ignite.internal.commandline;
-
-import java.util.Comparator;
-import java.util.Map;
-import org.apache.ignite.IgniteLogger;
-import org.apache.ignite.internal.client.GridClient;
-import org.apache.ignite.internal.client.GridClientBeforeNodeStart;
-import org.apache.ignite.internal.client.GridClientConfiguration;
-import org.apache.ignite.internal.client.GridClientException;
-import org.apache.ignite.internal.client.GridClientFactory;
-import org.apache.ignite.internal.util.typedef.F;
-import org.apache.ignite.internal.util.typedef.internal.SB;
-import org.jetbrains.annotations.Nullable;
-
-import static org.apache.ignite.internal.commandline.CommandHandler.UTILITY_NAME;
-import static org.apache.ignite.internal.commandline.CommandLogger.DOUBLE_INDENT;
-import static org.apache.ignite.internal.commandline.CommandLogger.INDENT;
-
-/**
- * Abstract class for all control.sh commands, has already implemented methods and abstract methods.
- * Define flow how to work with command.
- *
- * @param <T> Generic for getArg method which should return command-specific paramters which it would be run with.
- */
-public interface Command<T> {
-    /**
-     * Method to create thin client for communication with cluster.
-     *
-     * @param clientCfg Thin client configuration.
-     * @return Grid thin client instance which is already connected to cluster.
-     * @throws Exception If error occur.
-     */
-    public static GridClient startClient(GridClientConfiguration clientCfg) throws Exception {
-        GridClient client = GridClientFactory.start(clientCfg);
-
-        // If connection is unsuccessful, fail before doing any operations:
-        if (!client.connected()) {
-            GridClientException lastErr = client.checkLastError();
-
-            try {
-                client.close();
-            }
-            catch (Throwable e) {
-                lastErr.addSuppressed(e);
-            }
-
-            throw lastErr;
-        }
-
-        return client;
-    }
-
-    /**
-     * Method to create thin client for communication with node before it starts.
-     * If node has already started, there will be an error.
-     *
-     * @param clientCfg Thin client configuration.
-     * @return Grid thin client instance which is already connected to node before it starts.
-     * @throws Exception If error occur.
-     */
-    public static GridClientBeforeNodeStart startClientBeforeNodeStart(
-        GridClientConfiguration clientCfg
-    ) throws Exception {
-        GridClientBeforeNodeStart client = GridClientFactory.startBeforeNodeStart(clientCfg);
-
-        // If connection is unsuccessful, fail before doing any operations:
-        if (!client.connected()) {
-            GridClientException lastErr = client.checkLastError();
-
-            try {
-                client.close();
-            }
-            catch (Throwable e) {
-                lastErr.addSuppressed(e);
-            }
-
-            throw lastErr;
-        }
-
-        return client;
-    }
-
-    /**
-     * Print command usage.
-     *
-     * @param logger Logger to use.
-     * @param desc Command description.
-     * @param cmd Command.
-     * @param args Arguments.
-     */
-    public default void usage(IgniteLogger logger, String desc, CommandList cmd, String... args) {
-        usage(logger, desc, cmd, null, args);
-    }
-
-    /**
-     * Print command usage.
-     *
-     * @param logger Logger to use.
-     * @param desc Command description.
-     * @param cmd Command.
-     * @param paramsDesc Description of parameters (optional).
-     * @param args Arguments.
-     */
-    public default void usage(
-        IgniteLogger logger,
-        String desc,
-        CommandList cmd,
-        @Nullable Map<String, String> paramsDesc,
-        String... args
-    ) {
-        usage(logger, desc, cmd.text(), paramsDesc, args);
-    }
-
-    /**
-     * Print command usage.
-     *
-     * @param logger Logger to use.
-     * @param desc Command description.
-     * @param cmd Command.
-     * @param paramsDesc Description of parameters (optional).
-     * @param args Arguments.
-     */
-    public default void usage(
-        IgniteLogger logger,
-        String desc,
-        String cmd,
-        @Nullable Map<String, String> paramsDesc,
-        String... args
-    ) {
-        logger.info("");
-
-        if (experimental())
-            logger.info(INDENT + "[EXPERIMENTAL]");
-
-        logger.info(INDENT + desc);
-        logger.info(DOUBLE_INDENT + CommandLogger.join(" ", UTILITY_NAME, cmd, CommandLogger.join(" ", args)));
-
-        if (!F.isEmpty(paramsDesc)) {
-            logger.info("");
-
-            logger.info(DOUBLE_INDENT + "Parameters:");
-
-            usageParams(paramsDesc, DOUBLE_INDENT + INDENT, logger);
-        }
-    }
-
-    /**
-     * Print cache command arguments usage.
-     *
-     * @param paramsDesc Cache command arguments description.
-     * @param indent Indent string.
-     * @param logger Logger to use.
-     */
-    public default void usageParams(Map<String, String> paramsDesc, String indent, IgniteLogger logger) {
-        int maxParamLen = paramsDesc.keySet().stream().max(Comparator.comparingInt(String::length)).get().length();
-
-        for (Map.Entry<String, String> param : paramsDesc.entrySet())
-            logger.info(indent + extendToLen(param.getKey(), maxParamLen) + "  " + "- " + param.getValue());
-    }
-
-    /**
-     * Appends spaces to end of input string for extending to needed length.
-     *
-     * @param s Input string.
-     * @param targetLen Needed length.
-     * @return String with appended spaces on the end.
-     */
-    public static String extendToLen(String s, int targetLen) {
-        assert targetLen >= 0;
-        assert s.length() <= targetLen;
-
-        if (s.length() == targetLen)
-            return s;
-
-        SB sb = new SB(targetLen);
-
-        sb.a(s);
-
-        for (int i = 0; i < targetLen - s.length(); i++)
-            sb.a(" ");
-
-        return sb.toString();
-    }
-
-    /**
-     * Actual command execution. Parameters for run should be already set by calling parseArguments method.
-     *
-     * @param clientCfg Thin client configuration if connection to cluster is necessary.
-     * @param logger Logger to use.
-     * @return Result of operation (mostly usable for tests).
-     * @throws Exception If error occur.
-     */
-    public Object execute(GridClientConfiguration clientCfg, IgniteLogger logger) throws Exception;
-
-    /**
-     * Actual command execution with verbose mode if needed.
-     * Implement it if your command supports verbose mode.
-     *
-     * @see Command#execute(GridClientConfiguration, IgniteLogger)
-     *
-     * @param clientCfg Thin client configuration if connection to cluster is necessary.
-     * @param logger Logger to use.
-     * @param verbose Use verbose mode or not
-     * @return Result of operation (mostly usable for tests).
-     * @throws Exception If error occur.
-     */
-    default Object execute(GridClientConfiguration clientCfg, IgniteLogger logger, boolean verbose) throws Exception {
-        return execute(clientCfg, logger);
-    }
-
-    /**
-     * Prepares confirmation for the command.
-     *
-     * @param clientCfg Thin client configuration.
-     * @throws Exception If error occur.
-     */
-    default void prepareConfirmation(GridClientConfiguration clientCfg) throws Exception{
-        //no-op
-    }
-
-    /**
-     * @return Message text to show user for. If null it means that confirmantion is not needed.
-     */
-    public default String confirmationPrompt() {
-        return null;
-    }
-
-    /**
-     * Parse command-specific arguments.
-     *
-     * @param argIterator Argument iterator.
-     */
-    public default void parseArguments(CommandArgIterator argIterator) {
-        //Empty block.
-    }
-
-    /**
-     * @return Command arguments which were parsed during {@link #parseArguments(CommandArgIterator)} call.
-     */
-    public T arg();
-
-    /**
-     * Print info for user about command (parameters, use cases and so on).
-     *
-     * @param logger Logger to use.
-     */
-    public void printUsage(IgniteLogger logger);
-
-    /**
-     * @return command name.
-     */
-    String name();
-
-    /**
-     * Return {@code true} if the command is experimental or {@code false}
-     * otherwise.
-     *
-     * @return {@code true} if the command is experimental or {@code false}
-     *      otherwise.
-     */
-    default boolean experimental() {
-        return false;
-    }
-}
diff --git a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/CommandArgIterator.java b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/CommandArgIterator.java
deleted file mode 100644
index 3e7d94a2051..00000000000
--- a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/CommandArgIterator.java
+++ /dev/null
@@ -1,216 +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.ignite.internal.commandline;
-
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-import java.util.UUID;
-import org.apache.ignite.internal.util.typedef.F;
-import org.jetbrains.annotations.NotNull;
-
-/**
- * Iterator over command arguments.
- */
-public class CommandArgIterator {
-    /** */
-    private final Iterator<String> argsIt;
-
-    /** */
-    private final Map<String, Command<?>> cmds;
-
-    /** */
-    private String peekedArg;
-
-    /**
-     * Set of common arguments names and high level command name set.
-     */
-    private final Set<String> commonArgumentsAndHighLevelCommandSet;
-
-    /**
-     * @param argsIt Raw argument iterator.
-     * @param commonArgumentsAndHighLevelCommandSet All known subcomands.
-     * @param cmds Supported commands.
-     */
-    public CommandArgIterator(
-        Iterator<String> argsIt,
-        Set<String> commonArgumentsAndHighLevelCommandSet,
-        Map<String, Command<?>> cmds
-    ) {
-        this.argsIt = argsIt;
-        this.commonArgumentsAndHighLevelCommandSet = commonArgumentsAndHighLevelCommandSet;
-        this.cmds = cmds;
-    }
-
-    /**
-     * @return Returns {@code true} if the iteration has more elements.
-     */
-    public boolean hasNextArg() {
-        return peekedArg != null || argsIt.hasNext();
-    }
-
-    /**
-     * @return <code>true</code> if there's next argument for subcommand.
-     */
-    public boolean hasNextSubArg() {
-        return hasNextArg() && !cmds.containsKey(peekNextArg().toLowerCase()) &&
-            !commonArgumentsAndHighLevelCommandSet.contains(peekNextArg());
-    }
-
-    /**
-     * Extract next argument.
-     *
-     * @param err Error message.
-     * @return Next argument value.
-     */
-    public String nextArg(String err) {
-        if (peekedArg != null) {
-            String res = peekedArg;
-
-            peekedArg = null;
-
-            return res;
-        }
-
-        if (argsIt.hasNext())
-            return argsIt.next();
-
-        throw new IllegalArgumentException(err);
-    }
-
-    /**
-     * Returns the next argument in the iteration, without advancing the iteration.
-     *
-     * @return Next argument value or {@code null} if no next argument.
-     */
-    public String peekNextArg() {
-        if (peekedArg == null && argsIt.hasNext())
-            peekedArg = argsIt.next();
-
-        return peekedArg;
-    }
-
-    /**
-     * @return Numeric value.
-     */
-    public long nextNonNegativeLongArg(String argName) {
-        long val = nextLongArg(argName);
-
-        if (val < 0)
-            throw new IllegalArgumentException("Invalid value for " + argName + ": " + val);
-
-        return val;
-    }
-
-    /**
-     * @return Numeric value.
-     */
-    public int nextNonNegativeIntArg(String argName) {
-        int val = nextIntArg(argName);
-
-        if (val < 0)
-            throw new IllegalArgumentException("Invalid value for " + argName + ": " + val);
-
-        return val;
-    }
-
-    /**
-     * @return Numeric value.
-     */
-    public long nextLongArg(String argName) {
-        String str = nextArg("Expecting " + argName);
-
-        try {
-            return str.startsWith("0x") ? Long.parseLong(str.substring(2), 16) : Long.parseLong(str);
-        }
-        catch (NumberFormatException ignored) {
-            throw new IllegalArgumentException("Invalid value for " + argName + ": " + str);
-        }
-    }
-
-    /**
-     * @return Numeric value.
-     */
-    public int nextIntArg(String argName) {
-        String str = nextArg("Expecting " + argName);
-
-        try {
-            return str.startsWith("0x") ? Integer.parseInt(str.substring(2), 16) : Integer.parseInt(str);
-        }
-        catch (NumberFormatException ignored) {
-            throw new IllegalArgumentException("Invalid value for " + argName + ": " + str);
-        }
-    }
-
-    /** @return UUID value. */
-    public UUID nextUuidArg(String argName) {
-        String str = nextArg("Expecting " + argName + " command argument.");
-
-        try {
-            return UUID.fromString(str);
-        }
-        catch (IllegalArgumentException e) {
-            throw new IllegalArgumentException("Failed to parse " + argName + " command argument." +
-                " String representation of \"java.util.UUID\" is exepected. For example:" +
-                " 123e4567-e89b-42d3-a456-556642440000", e);
-        }
-    }
-
-    /**
-     * @param argName Name of argument.
-     */
-    public Set<String> nextStringSet(String argName) {
-        String nextArg = peekNextArg();
-
-        if (isCommandOrOption(nextArg))
-            return Collections.emptySet();
-
-        nextArg = nextArg("Expected " + argName);
-
-        return parseStringSet(nextArg);
-    }
-
-    /**
-     *
-     * @param string To scan on for string set.
-     * @return Set of string parsed from string param.
-     */
-    @NotNull public Set<String> parseStringSet(String string) {
-        Set<String> namesSet = new HashSet<>();
-
-        for (String name : string.split(",")) {
-            if (F.isEmpty(name))
-                throw new IllegalArgumentException("Non-empty string expected.");
-
-            namesSet.add(name.trim());
-        }
-        return namesSet;
-    }
-
-    /**
-     * Check if raw arg is command or option.
-     *
-     * @return {@code true} If raw arg is command, overwise {@code false}.
-     */
-    public static boolean isCommandOrOption(String raw) {
-        return raw != null && raw.contains("--");
-    }
-}
diff --git a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/CommandHandler.java b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/CommandHandler.java
index 84f592d57e8..318a4121c55 100644
--- a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/CommandHandler.java
+++ b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/CommandHandler.java
@@ -17,17 +17,20 @@
 
 package org.apache.ignite.internal.commandline;
 
+import java.lang.reflect.Field;
 import java.net.URL;
 import java.time.Duration;
 import java.time.LocalDateTime;
 import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
-import java.util.LinkedHashMap;
 import java.util.List;
-import java.util.Map;
+import java.util.Objects;
 import java.util.Scanner;
 import java.util.UUID;
+import java.util.function.BiConsumer;
+import java.util.function.Consumer;
 import javax.cache.configuration.Factory;
 import javax.net.ssl.SSLContext;
 import org.apache.ignite.IgniteCheckedException;
@@ -41,13 +44,29 @@ import org.apache.ignite.internal.client.GridClientDisconnectedException;
 import org.apache.ignite.internal.client.GridClientHandshakeException;
 import org.apache.ignite.internal.client.GridServerUnreachableException;
 import org.apache.ignite.internal.client.impl.connection.GridClientConnectionResetException;
+import org.apache.ignite.internal.dto.IgniteDataTransferObject;
 import org.apache.ignite.internal.logger.IgniteLoggerEx;
+import org.apache.ignite.internal.management.IgniteCommandRegistry;
+import org.apache.ignite.internal.management.api.Argument;
+import org.apache.ignite.internal.management.api.BeforeNodeStartCommand;
+import org.apache.ignite.internal.management.api.CliConfirmArgument;
+import org.apache.ignite.internal.management.api.CliSubcommandsWithPrefix;
+import org.apache.ignite.internal.management.api.Command;
+import org.apache.ignite.internal.management.api.CommandUtils;
+import org.apache.ignite.internal.management.api.CommandsRegistry;
+import org.apache.ignite.internal.management.api.ComputeCommand;
+import org.apache.ignite.internal.management.api.EnumDescription;
+import org.apache.ignite.internal.management.api.HelpCommand;
+import org.apache.ignite.internal.management.api.LocalCommand;
+import org.apache.ignite.internal.management.api.Positional;
+import org.apache.ignite.internal.management.cache.CacheCommand;
 import org.apache.ignite.internal.util.IgniteUtils;
 import org.apache.ignite.internal.util.spring.IgniteSpringHelperImpl;
 import org.apache.ignite.internal.util.typedef.F;
 import org.apache.ignite.internal.util.typedef.X;
 import org.apache.ignite.internal.util.typedef.internal.SB;
 import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.lang.IgniteExperimental;
 import org.apache.ignite.plugin.security.SecurityCredentials;
 import org.apache.ignite.plugin.security.SecurityCredentialsBasicProvider;
 import org.apache.ignite.plugin.security.SecurityCredentialsProvider;
@@ -60,17 +79,22 @@ import static java.util.Objects.nonNull;
 import static org.apache.ignite.IgniteSystemProperties.IGNITE_ENABLE_EXPERIMENTAL_COMMAND;
 import static org.apache.ignite.internal.IgniteVersionUtils.ACK_VER_STR;
 import static org.apache.ignite.internal.IgniteVersionUtils.COPYRIGHT;
-import static org.apache.ignite.internal.commandline.CommandLogger.DOUBLE_INDENT;
-import static org.apache.ignite.internal.commandline.CommandLogger.INDENT;
+import static org.apache.ignite.internal.commandline.ArgumentParser.CMD_AUTO_CONFIRMATION;
+import static org.apache.ignite.internal.commandline.ArgumentParser.CMD_ENABLE_EXPERIMENTAL;
+import static org.apache.ignite.internal.commandline.ArgumentParser.CMD_VERBOSE;
 import static org.apache.ignite.internal.commandline.CommandLogger.errorMessage;
-import static org.apache.ignite.internal.commandline.CommandLogger.optional;
-import static org.apache.ignite.internal.commandline.CommonArgParser.CMD_AUTO_CONFIRMATION;
-import static org.apache.ignite.internal.commandline.CommonArgParser.CMD_ENABLE_EXPERIMENTAL;
-import static org.apache.ignite.internal.commandline.CommonArgParser.CMD_VERBOSE;
-import static org.apache.ignite.internal.commandline.CommonArgParser.getCommonOptions;
-import static org.apache.ignite.internal.commandline.TaskExecutor.DFLT_HOST;
-import static org.apache.ignite.internal.commandline.TaskExecutor.DFLT_PORT;
-import static org.apache.ignite.ssl.SslContextFactory.DFLT_SSL_PROTOCOL;
+import static org.apache.ignite.internal.management.api.CommandUtils.CMD_WORDS_DELIM;
+import static org.apache.ignite.internal.management.api.CommandUtils.DOUBLE_INDENT;
+import static org.apache.ignite.internal.management.api.CommandUtils.INDENT;
+import static org.apache.ignite.internal.management.api.CommandUtils.NAME_PREFIX;
+import static org.apache.ignite.internal.management.api.CommandUtils.PARAM_WORDS_DELIM;
+import static org.apache.ignite.internal.management.api.CommandUtils.asOptional;
+import static org.apache.ignite.internal.management.api.CommandUtils.cmdText;
+import static org.apache.ignite.internal.management.api.CommandUtils.join;
+import static org.apache.ignite.internal.management.api.CommandUtils.parameterExample;
+import static org.apache.ignite.internal.management.api.CommandUtils.toFormattedCommandName;
+import static org.apache.ignite.internal.management.api.CommandUtils.valueExample;
+import static org.apache.ignite.internal.management.api.CommandUtils.visitCommandParams;
 
 /**
  * Class that execute several commands passed via command line.
@@ -82,9 +106,6 @@ public class CommandHandler {
     /** */
     public static final String CONFIRM_MSG = "y";
 
-    /** */
-    static final String DELIM = "--------------------------------------------------------------------------------";
-
     /** */
     public static final int EXIT_CODE_OK = 0;
 
@@ -106,20 +127,23 @@ public class CommandHandler {
     /** */
     private static final long DFLT_PING_TIMEOUT = 30_000L;
 
+    /** */
+    public static final String DFLT_HOST = "127.0.0.1";
+
+    /** */
+    public static final int DFLT_PORT = 11211;
+
     /** */
     private final Scanner in = new Scanner(System.in);
 
     /** Utility name. */
     public static final String UTILITY_NAME = "control.(sh|bat)";
 
-    /** */
-    public static final String NULL = "null";
-
     /** JULs logger. */
     private final IgniteLogger logger;
 
     /** Supported commands. */
-    private final Map<String, Command<?>> cmds;
+    private final IgniteCommandRegistry registry = new IgniteCommandRegistry();
 
     /** Session. */
     protected final String ses = U.id8(UUID.randomUUID());
@@ -174,33 +198,27 @@ public class CommandHandler {
         this.logger = logger;
         Iterable<CommandsProvider> it = U.loadService(CommandsProvider.class);
 
-        Map<String, Command<?>> cmds = new LinkedHashMap<>();
-
-        CommandList.commands().forEach((k, v) -> cmds.put(k.toLowerCase(), v));
-
         if (!F.isEmpty(it)) {
             for (CommandsProvider provider : it) {
                 if (logger.isDebugEnabled())
                     logger.debug("Registering pluggable commands provider: " + provider);
 
-                provider.commands().forEach((k, v) -> {
-                    k = k.toLowerCase();
+                provider.commands().forEach(cmd -> {
+                    String k = cmdText(cmd);
 
                     if (logger.isDebugEnabled())
                         logger.debug("Registering command: " + k);
 
-                    if (cmds.containsKey(k)) {
+                    if (registry.command(k) != null) {
                         throw new IllegalArgumentException("Found conflict for command " + k + ". Provider " +
-                            provider + " tries to register command " + v + ", but this command has already been " +
-                            "registered " + cmds.get(k));
+                            provider + " tries to register command " + cmd + ", but this command has already been " +
+                            "registered " + registry.command(k));
                     }
                     else
-                        cmds.put(k, v);
+                        registry.register(cmd);
                 });
             }
         }
-
-        this.cmds = Collections.unmodifiableMap(cmds);
     }
 
     /**
@@ -209,7 +227,7 @@ public class CommandHandler {
      * @param rawArgs Arguments to parse and execute.
      * @return Exit code.
      */
-    public int execute(List<String> rawArgs) {
+    public <A extends IgniteDataTransferObject> int execute(List<String> rawArgs) {
         LocalDateTime startTime = LocalDateTime.now();
 
         Thread.currentThread().setName("session=" + ses);
@@ -233,12 +251,11 @@ public class CommandHandler {
 
             verbose = F.exist(rawArgs, CMD_VERBOSE::equalsIgnoreCase);
 
-            ConnectionAndSslParameters args = new CommonArgParser(logger, cmds).parseAndValidate(rawArgs.iterator());
+            ConnectionAndSslParameters<A> args = new ArgumentParser(logger, registry).parseAndValidate(rawArgs);
 
-            Command command = args.command();
-            commandName = command.name();
+            commandName = toFormattedCommandName(args.root().getClass()).toUpperCase();
 
-            GridClientConfiguration clientCfg = getClientConfiguration(args);
+            CommandInvoker<A> invoker = new CommandInvoker<>(args.command(), args.commandArg(), getClientConfiguration(args));
 
             int tryConnectMaxCount = 3;
 
@@ -248,10 +265,11 @@ public class CommandHandler {
 
             while (true) {
                 try {
-                    if (!args.autoConfirmation()) {
-                        command.prepareConfirmation(clientCfg);
+                    if (!invoker.prepare(logger))
+                        return EXIT_CODE_OK;
 
-                        if (!confirm(command.confirmationPrompt())) {
+                    if (!args.autoConfirmation()) {
+                        if (!confirm(invoker.confirmationPrompt())) {
                             logger.info("Operation cancelled.");
 
                             return EXIT_CODE_OK;
@@ -260,9 +278,14 @@ public class CommandHandler {
 
                     logger.info("Command [" + commandName + "] started");
                     logger.info("Arguments: " + argumentsToString(rawArgs));
-                    logger.info(DELIM);
+                    logger.info(U.DELIM);
 
-                    lastOperationRes = command.execute(clientCfg, logger, args.verbose());
+                    if (args.command() instanceof HelpCommand)
+                        printUsage(logger, args.root());
+                    else if (args.command() instanceof BeforeNodeStartCommand)
+                        lastOperationRes = invoker.invokeBeforeNodeStart(logger);
+                    else
+                        lastOperationRes = invoker.invoke(logger, args.verbose());
 
                     break;
                 }
@@ -285,11 +308,11 @@ public class CommandHandler {
                     if (credentialsRequested)
                         tryConnectMaxCount--;
 
-                    String user = retrieveUserName(args, clientCfg);
-
-                    String pwd = new String(requestPasswordFromConsole("password: "));
-
-                    clientCfg = getClientConfiguration(user, pwd, args);
+                    invoker.clientConfiguration(getClientConfiguration(
+                        retrieveUserName(args, invoker.clientConfiguration()),
+                        new String(requestPasswordFromConsole("password: ")),
+                        args
+                    ));
 
                     credentialsRequested = true;
                 }
@@ -446,14 +469,6 @@ public class CommandHandler {
         return false;
     }
 
-    /**
-     * @param arg To check.
-     * @return True if provided argument is among sensitive one and not should be displayed.
-     */
-    protected boolean isSensitiveArgument(String arg) {
-        return CommonArgParser.isSensitiveArgument(arg);
-    }
-
     /**
      * Joins user's arguments and hides sensitive information.
      *
@@ -478,7 +493,7 @@ public class CommandHandler {
 
             sb.a(arg).a(' ');
 
-            hide = isSensitiveArgument(arg);
+            hide = ArgumentParser.isSensitiveArgument(arg);
         }
 
         return sb.toString();
@@ -592,21 +607,13 @@ public class CommandHandler {
 
         SslContextFactory factory = new SslContextFactory();
 
-        String[] sslProtocols = split(args.sslProtocol(), ",");
-
-        if (F.isEmpty(sslProtocols))
-            factory.setProtocol(DFLT_SSL_PROTOCOL);
-        else {
-            factory.setProtocol(sslProtocols[0]);
-
-            if (sslProtocols.length > 1)
-                factory.setProtocols(sslProtocols);
-        }
+        if (args.sslProtocol().length > 1)
+            factory.setProtocols(args.sslProtocol());
+        else
+            factory.setProtocol(args.sslProtocol()[0]);
 
         factory.setKeyAlgorithm(args.sslKeyAlgorithm());
-
-        factory.setCipherSuites(split(args.getSslCipherSuites(), ","));
-
+        factory.setCipherSuites(args.getSslCipherSuites());
         factory.setKeyStoreFilePath(args.sslKeyStorePath());
 
         if (args.sslKeyStorePassword() != null)
@@ -726,23 +733,6 @@ public class CommandHandler {
         }
     }
 
-    /**
-     * Split string into items.
-     *
-     * @param s String to process.
-     * @param delim Delimiter.
-     * @return List with items.
-     */
-    private static String[] split(String s, String delim) {
-        if (F.isEmpty(s))
-            return null;
-
-        return Arrays.stream(s.split(delim))
-            .map(String::trim)
-            .filter(item -> !item.isEmpty())
-            .toArray(String[]::new);
-    }
-
     /** @param rawArgs Arguments. */
     private void printHelp(List<String> rawArgs) {
         boolean experimentalEnabled = rawArgs.stream().anyMatch(CMD_ENABLE_EXPERIMENTAL::equalsIgnoreCase) ||
@@ -752,16 +742,25 @@ public class CommandHandler {
             "The command has the following syntax:");
         logger.info("");
 
-        logger.info(INDENT + CommandLogger.join(" ", CommandLogger.join(" ", UTILITY_NAME, CommandLogger.join(" ", getCommonOptions())),
-            optional("command"), "<command_parameters>"));
+        logger.info(INDENT + join(" ", join(" ", UTILITY_NAME, join(" ", new ArgumentParser(logger, registry).getCommonOptions())),
+            asOptional("command", true), "<command_parameters>"));
         logger.info("");
         logger.info("");
 
         logger.info("This utility can do the following commands:");
 
-        cmds.values().forEach(c -> {
-            if (experimentalEnabled || !c.experimental())
-                c.printUsage(logger);
+        registry.commands().forEachRemaining(e -> {
+            if (experimentalEnabled || !e.getValue().getClass().isAnnotationPresent(IgniteExperimental.class)) {
+                if (Objects.equals(e.getValue().getClass(), CacheCommand.class)) {
+                    logger.info("");
+                    logger.info("View caches information in a cluster. For more details type:");
+                    logger.info(DOUBLE_INDENT + UTILITY_NAME + " --cache help");
+
+                    return;
+                }
+
+                printUsage(logger, e.getValue());
+            }
         });
 
         logger.info("");
@@ -788,4 +787,225 @@ public class CommandHandler {
         logger.info(DOUBLE_INDENT + ERR_AUTHENTICATION_FAILED + " - authentication failed.");
         logger.info(DOUBLE_INDENT + EXIT_CODE_UNEXPECTED_ERROR + " - unexpected error.");
     }
+
+    /**
+     * Print info for user about command (parameters, use cases and so on).
+     *
+     * @param logger Logger to use.
+     */
+    public void printUsage(IgniteLogger logger, Command<?, ?> cmd) {
+        if (cmd instanceof CacheCommand || cmd instanceof CacheCommand.CacheHelpCommand)
+            printCacheHelpHeader(logger);
+
+        usage(cmd, Collections.emptyList(), logger);
+
+        if (cmd instanceof CacheCommand || cmd instanceof CacheCommand.CacheHelpCommand)
+            logger.info("");
+    }
+
+    /** */
+    private void printCacheHelpHeader(IgniteLogger logger) {
+        logger.info(INDENT + "The '--cache subcommand' is used to get information about and perform actions" +
+            " with caches. The command has the following syntax:");
+        logger.info("");
+        logger.info(INDENT + join(" ", UTILITY_NAME, join(" ", new ArgumentParser(logger, null).getCommonOptions())) + " " +
+            "--cache [subcommand] <subcommand_parameters>");
+        logger.info("");
+        logger.info(INDENT + "The subcommands that take [nodeId] as an argument ('list', 'find_garbage', " +
+            "'contention' and 'validate_indexes') will be executed on the given node or on all server nodes" +
+            " if the option is not specified. Other commands will run on a random server node.");
+        logger.info("");
+        logger.info("");
+        logger.info(INDENT + "Subcommands:");
+    }
+
+    /**
+     * Generates usage for base command and all of its children, if any.
+     *
+     * @param cmd Base command.
+     * @param parents Collection of parent commands.
+     * @param logger Logger to print help to.
+     */
+    public static void usage(Command<?, ?> cmd, List<Command<?, ?>> parents, IgniteLogger logger) {
+        if (cmd instanceof LocalCommand
+            || cmd instanceof ComputeCommand
+            || cmd instanceof HelpCommand
+            || cmd instanceof BeforeNodeStartCommand) {
+            logger.info("");
+
+            if (cmd.getClass().isAnnotationPresent(IgniteExperimental.class))
+                logger.info(INDENT + "[EXPERIMENTAL]");
+
+            printExample(cmd, parents, logger);
+
+            if (CommandUtils.hasDescribedParameters(cmd)) {
+                logger.info("");
+                logger.info(DOUBLE_INDENT + "Parameters:");
+
+                LengthCalculator lenCalc = new LengthCalculator();
+
+                visitCommandParams(cmd.argClass(), lenCalc, lenCalc, (argGrp, flds) -> flds.forEach(lenCalc));
+
+                Consumer<Field> printer = fld -> {
+                    BiConsumer<String, String> logParam = (name, description) -> {
+                        if (F.isEmpty(description))
+                            return;
+
+                        logger.info(
+                            DOUBLE_INDENT + INDENT + U.extendToLen(name, lenCalc.length) + "  - " + description + "."
+                        );
+                    };
+
+                    if (!fld.isAnnotationPresent(EnumDescription.class)) {
+                        logParam.accept(
+                            parameterExample(fld, false),
+                            fld.getAnnotation(Argument.class).description()
+                        );
+                    }
+                    else {
+                        EnumDescription enumDesc = fld.getAnnotation(EnumDescription.class);
+
+                        String[] names = enumDesc.names();
+                        String[] descriptions = enumDesc.descriptions();
+
+                        for (int i = 0; i < names.length; i++)
+                            logParam.accept(names[i], descriptions[i]);
+                    }
+                };
+
+                visitCommandParams(cmd.argClass(), printer, printer, (argGrp, flds) -> {
+                    flds.stream().filter(fld -> fld.isAnnotationPresent(Positional.class)).forEach(printer);
+                    flds.stream().filter(fld -> !fld.isAnnotationPresent(Positional.class)).forEach(printer);
+                });
+            }
+        }
+
+        if (cmd instanceof CommandsRegistry) {
+            List<Command<?, ?>> parents0 = new ArrayList<>(parents);
+
+            parents0.add(cmd);
+
+            ((CommandsRegistry<?, ?>)cmd).commands().forEachRemaining(cmd0 -> usage(cmd0.getValue(), parents0, logger));
+        }
+    }
+
+    /**
+     * Generates and prints example of command.
+     *
+     * @param cmd Command.
+     * @param parents Collection of parent commands.
+     * @param logger Logger to print help to.
+     */
+    private static void printExample(Command<?, ?> cmd, List<Command<?, ?>> parents, IgniteLogger logger) {
+        logger.info(INDENT + cmd.description() + ":");
+
+        StringBuilder bldr = new StringBuilder(DOUBLE_INDENT + UTILITY_NAME);
+
+        CommandName name = new CommandName();
+
+        parents.forEach(name);
+        name.accept(cmd);
+
+        bldr.append(name.name.toString());
+
+        BiConsumer<Boolean, Field> paramPrinter = (spaceReq, fld) -> {
+            if (spaceReq)
+                bldr.append(' ');
+
+            bldr.append(parameterExample(fld, true));
+        };
+
+        visitCommandParams(
+            cmd.argClass(),
+            fld -> bldr.append(' ').append(valueExample(fld)),
+            fld -> paramPrinter.accept(true, fld),
+            (argGrp, flds) -> {
+                if (argGrp.onlyOneOf()) {
+                    bldr.append(' ');
+
+                    if (argGrp.optional())
+                        bldr.append('[');
+
+                    for (int i = 0; i < flds.size(); i++) {
+                        if (i != 0)
+                            bldr.append('|');
+
+                        paramPrinter.accept(false, flds.get(i));
+                    }
+
+                    if (argGrp.optional())
+                        bldr.append(']');
+                }
+                else {
+                    flds.stream()
+                        .filter(fld -> fld.isAnnotationPresent(Positional.class))
+                        .forEach(fld -> bldr.append(' ').append(valueExample(fld)));
+                    flds.stream()
+                        .filter(fld -> !fld.isAnnotationPresent(Positional.class))
+                        .forEach(fld -> paramPrinter.accept(true, fld));
+                }
+            }
+        );
+
+        if (cmd.argClass().isAnnotationPresent(CliConfirmArgument.class))
+            bldr.append(' ').append(CommandUtils.asOptional(CMD_AUTO_CONFIRMATION, true));
+
+        logger.info(bldr.toString());
+    }
+
+    /** */
+    private static class LengthCalculator implements Consumer<Field> {
+        /** */
+        int length;
+
+        /** {@inheritDoc} */
+        @Override public void accept(Field fld) {
+            length = Math.max(length, parameterExample(fld, false).length());
+
+            if (fld.isAnnotationPresent(EnumDescription.class)) {
+                EnumDescription enumDesc = fld.getAnnotation(EnumDescription.class);
+
+                for (String name : enumDesc.names())
+                    length = Math.max(length, name.length());
+            }
+        }
+    }
+
+    /** */
+    public static class CommandName implements Consumer<Object> {
+        /** */
+        private boolean prefixInclude = true;
+
+        /** */
+        private String parentPrefix;
+
+        /** */
+        StringBuilder name = new StringBuilder();
+
+        /** {@inheritDoc} */
+        @Override public void accept(Object cmd) {
+            name.append(' ');
+
+            if (prefixInclude)
+                name.append(NAME_PREFIX);
+
+            String cmdName = toFormattedCommandName(cmd.getClass());
+
+            String parentPrefix0 = parentPrefix;
+
+            parentPrefix = cmdName;
+
+            if (!F.isEmpty(parentPrefix0)) {
+                cmdName = cmdName.replaceFirst(parentPrefix0 + CMD_WORDS_DELIM, "");
+
+                if (!prefixInclude)
+                    cmdName = cmdName.replaceAll(CMD_WORDS_DELIM + "", PARAM_WORDS_DELIM + "");
+            }
+
+            name.append(cmdName);
+
+            if (cmd instanceof CommandsRegistry)
+                prefixInclude = cmd.getClass().isAnnotationPresent(CliSubcommandsWithPrefix.class);
+        }
+    }
 }
diff --git a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/CommandInvoker.java b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/CommandInvoker.java
new file mode 100644
index 00000000000..06c66b3e015
--- /dev/null
+++ b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/CommandInvoker.java
@@ -0,0 +1,316 @@
+/*
+ * 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.ignite.internal.commandline;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import org.apache.ignite.IgniteLogger;
+import org.apache.ignite.internal.client.GridClient;
+import org.apache.ignite.internal.client.GridClientBeforeNodeStart;
+import org.apache.ignite.internal.client.GridClientCompute;
+import org.apache.ignite.internal.client.GridClientConfiguration;
+import org.apache.ignite.internal.client.GridClientDisconnectedException;
+import org.apache.ignite.internal.client.GridClientException;
+import org.apache.ignite.internal.client.GridClientFactory;
+import org.apache.ignite.internal.client.GridClientNode;
+import org.apache.ignite.internal.dto.IgniteDataTransferObject;
+import org.apache.ignite.internal.management.api.BeforeNodeStartCommand;
+import org.apache.ignite.internal.management.api.Command;
+import org.apache.ignite.internal.management.api.ComputeCommand;
+import org.apache.ignite.internal.management.api.LocalCommand;
+import org.apache.ignite.internal.management.api.PreparableCommand;
+import org.apache.ignite.internal.util.IgniteUtils;
+import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.internal.visor.VisorTaskArgument;
+import org.apache.ignite.lang.IgniteBiTuple;
+
+import static java.util.Collections.singleton;
+import static java.util.stream.Collectors.toMap;
+import static org.apache.ignite.internal.commandline.CommandHandler.DFLT_HOST;
+
+/**
+ * Adapter of new management API command for legacy {@code control.sh} execution flow.
+ */
+public class CommandInvoker<A extends IgniteDataTransferObject> {
+    /** Command to execute. */
+    private final Command<A, ?> cmd;
+
+    /** Parsed argument. */
+    private final A arg;
+
+    /** Client configuration. */
+    private GridClientConfiguration clientCfg;
+
+    /** @param cmd Command to execute. */
+    public CommandInvoker(Command<A, ?> cmd, A arg, GridClientConfiguration clientCfg) {
+        this.cmd = cmd;
+        this.arg = arg;
+        this.clientCfg = clientCfg;
+    }
+
+    /**
+     * Actual command execution with verbose mode if needed.
+     * Implement it if your command supports verbose mode.
+     *
+     * @param log Logger to use.
+     * @param verbose Use verbose mode or not
+     * @return Result of operation (mostly usable for tests).
+     * @throws Exception If error occur.
+     */
+    public <R> R invoke(IgniteLogger log, boolean verbose) throws Exception {
+        try (GridClient client = startClient(clientCfg)) {
+            String deprecationMsg = cmd.deprecationMessage(arg);
+
+            if (deprecationMsg != null)
+                log.warning(deprecationMsg);
+
+            R res;
+
+            if (cmd instanceof LocalCommand)
+                res = ((LocalCommand<A, R>)cmd).execute(client, arg, log::info);
+            else if (cmd instanceof ComputeCommand) {
+                GridClientCompute compute = client.compute();
+
+                Map<UUID, GridClientNode> nodes = compute.nodes().stream()
+                    .collect(toMap(GridClientNode::nodeId, n -> n));
+
+                ComputeCommand<A, R> cmd = (ComputeCommand<A, R>)this.cmd;
+
+                Collection<UUID> cmdNodes = cmd.nodes(nodes, arg);
+
+                if (cmdNodes == null)
+                    cmdNodes = singleton(defaultNode(client, clientCfg).nodeId());
+
+                for (UUID id : cmdNodes) {
+                    if (!nodes.containsKey(id))
+                        throw new IllegalArgumentException("Node with id=" + id + " not found.");
+                }
+
+                Collection<GridClientNode> connectable = F.viewReadOnly(
+                    cmdNodes,
+                    nodes::get,
+                    id -> nodes.get(id).connectable()
+                );
+
+                if (!F.isEmpty(connectable))
+                    compute = compute.projection(connectable);
+
+                res = compute.execute(cmd.taskClass().getName(), new VisorTaskArgument<>(cmdNodes, arg, false));
+
+                cmd.printResult(arg, res, log::info);
+            }
+            else
+                throw new IllegalArgumentException("Unknown command type: " + cmd);
+
+            return res;
+        }
+        catch (Throwable e) {
+            log.error("Failed to perform operation.");
+            log.error(CommandLogger.errorMessage(e));
+
+            throw e;
+        }
+    }
+
+    /** */
+    public boolean prepare(IgniteLogger log) throws Exception {
+        if (!(cmd instanceof PreparableCommand))
+            return true;
+
+        try (GridClient client = startClient(clientCfg)) {
+            return ((PreparableCommand<A, ?>)cmd).prepare(client, arg, log::info);
+        }
+    }
+
+    /**
+     * @return Message text to show user for. {@code null} means that confirmantion is not required.
+     */
+    public String confirmationPrompt() {
+        return cmd.confirmationPrompt(arg);
+    }
+
+    /** */
+    public <R> R invokeBeforeNodeStart(IgniteLogger log) throws Exception {
+        try (GridClientBeforeNodeStart client = startClientBeforeNodeStart(clientCfg)) {
+            return ((BeforeNodeStartCommand<A, R>)cmd).execute(client, arg, log::info);
+        }
+        catch (GridClientDisconnectedException e) {
+            throw new GridClientException(e.getCause());
+        }
+    }
+
+    /**
+     * Method to create thin client for communication with cluster.
+     *
+     * @param clientCfg Thin client configuration.
+     * @return Grid thin client instance which is already connected to cluster.
+     * @throws Exception If error occur.
+     */
+    private static GridClient startClient(GridClientConfiguration clientCfg) throws Exception {
+        GridClient client = GridClientFactory.start(clientCfg);
+
+        // If connection is unsuccessful, fail before doing any operations:
+        if (!client.connected()) {
+            GridClientException lastErr = client.checkLastError();
+
+            try {
+                client.close();
+            }
+            catch (Throwable e) {
+                lastErr.addSuppressed(e);
+            }
+
+            throw lastErr;
+        }
+
+        return client;
+    }
+
+    /**
+     * Method to create thin client for communication with node before it starts.
+     * If node has already started, there will be an error.
+     *
+     * @param clientCfg Thin client configuration.
+     * @return Grid thin client instance which is already connected to node before it starts.
+     * @throws Exception If error occur.
+     */
+    private static GridClientBeforeNodeStart startClientBeforeNodeStart(
+        GridClientConfiguration clientCfg
+    ) throws Exception {
+        GridClientBeforeNodeStart client = GridClientFactory.startBeforeNodeStart(clientCfg);
+
+        // If connection is unsuccessful, fail before doing any operations:
+        if (!client.connected()) {
+            GridClientException lastErr = client.checkLastError();
+
+            try {
+                client.close();
+            }
+            catch (Throwable e) {
+                lastErr.addSuppressed(e);
+            }
+
+            throw lastErr;
+        }
+
+        return client;
+    }
+
+    /** */
+    private static GridClientNode defaultNode(GridClient client, GridClientConfiguration clientCfg) throws GridClientException {
+        GridClientNode node;
+
+        // Prefer node from connect string.
+        final String cfgAddr = clientCfg.getServers().iterator().next();
+
+        String[] parts = cfgAddr.split(":");
+
+        if (DFLT_HOST.equals(parts[0])) {
+            InetAddress addr;
+
+            try {
+                addr = IgniteUtils.getLocalHost();
+            }
+            catch (IOException e) {
+                throw new GridClientException("Can't get localhost name.", e);
+            }
+
+            if (addr.isLoopbackAddress())
+                throw new GridClientException("Can't find localhost name.");
+
+            String origAddr = addr.getHostName() + ":" + parts[1];
+
+            node = listHosts(client).filter(tuple -> origAddr.equals(tuple.get2())).findFirst().map(IgniteBiTuple::get1).orElse(null);
+
+            if (node == null)
+                node = listHostsByClientNode(client).filter(tuple -> tuple.get2().size() == 1 && cfgAddr.equals(tuple.get2().get(0))).
+                    findFirst().map(IgniteBiTuple::get1).orElse(null);
+        }
+        else
+            node = listHosts(client).filter(tuple -> cfgAddr.equals(tuple.get2())).findFirst().map(IgniteBiTuple::get1).orElse(null);
+
+        // Otherwise choose random node.
+        if (node == null)
+            node = balancedNode(client.compute());
+
+        return node;
+    }
+
+    /**
+     * @param client Client.
+     * @return List of hosts.
+     */
+    private static Stream<IgniteBiTuple<GridClientNode, String>> listHosts(GridClient client) throws GridClientException {
+        return client.compute()
+            .nodes(GridClientNode::connectable)
+            .stream()
+            .flatMap(node -> Stream.concat(
+                node.tcpAddresses() == null ? Stream.empty() : node.tcpAddresses().stream(),
+                node.tcpHostNames() == null ? Stream.empty() : node.tcpHostNames().stream()
+            ).map(addr -> new IgniteBiTuple<>(node, addr + ":" + node.tcpPort())));
+    }
+
+    /**
+     * @param client Client.
+     * @return List of hosts.
+     */
+    private static Stream<IgniteBiTuple<GridClientNode, List<String>>> listHostsByClientNode(
+        GridClient client
+    ) throws GridClientException {
+        return client.compute().nodes(GridClientNode::connectable).stream()
+            .map(
+                node -> new IgniteBiTuple<>(
+                    node,
+                    Stream.concat(
+                            node.tcpAddresses() == null ? Stream.empty() : node.tcpAddresses().stream(),
+                            node.tcpHostNames() == null ? Stream.empty() : node.tcpHostNames().stream()
+                        )
+                        .map(addr -> addr + ":" + node.tcpPort()).collect(Collectors.toList())
+                )
+            );
+    }
+
+    /**
+     * @param compute instance
+     * @return balanced node
+     */
+    private static GridClientNode balancedNode(GridClientCompute compute) throws GridClientException {
+        Collection<GridClientNode> nodes = compute.nodes(GridClientNode::connectable);
+
+        if (F.isEmpty(nodes))
+            throw new GridClientDisconnectedException("Connectable node not found", null);
+
+        return compute.balancer().balancedNode(nodes);
+    }
+
+    /** */
+    public void clientConfiguration(GridClientConfiguration clientCfg) {
+        this.clientCfg = clientCfg;
+    }
+
+    /** */
+    public GridClientConfiguration clientConfiguration() {
+        return clientCfg;
+    }
+}
diff --git a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/CommandList.java b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/CommandList.java
deleted file mode 100644
index feabcdf3ac1..00000000000
--- a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/CommandList.java
+++ /dev/null
@@ -1,167 +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.ignite.internal.commandline;
-
-import java.util.Arrays;
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.stream.Collectors;
-import org.apache.ignite.internal.commandline.cache.CacheCommands;
-import org.apache.ignite.internal.commandline.cdc.CdcCommand;
-import org.apache.ignite.internal.commandline.consistency.ConsistencyCommand;
-import org.apache.ignite.internal.commandline.diagnostic.DiagnosticCommand;
-import org.apache.ignite.internal.commandline.encryption.EncryptionCommands;
-import org.apache.ignite.internal.commandline.meta.MetadataCommand;
-import org.apache.ignite.internal.commandline.metric.MetricCommand;
-import org.apache.ignite.internal.commandline.performancestatistics.PerformanceStatisticsCommand;
-import org.apache.ignite.internal.commandline.property.PropertyCommand;
-import org.apache.ignite.internal.commandline.query.KillCommand;
-import org.apache.ignite.internal.commandline.snapshot.SnapshotCommand;
-import org.apache.ignite.internal.commandline.systemview.SystemViewCommand;
-
-/**
- * High-level commands.
- */
-public enum CommandList {
-    /** */
-    ACTIVATE("--activate", new ActivateCommand()),
-
-    /** */
-    DEACTIVATE("--deactivate", new DeactivateCommand()),
-
-    /** */
-    STATE("--state", new StateCommand()),
-
-    /** */
-    SET_STATE("--set-state", new ClusterStateChangeCommand()),
-
-    /** */
-    BASELINE("--baseline", new BaselineCommand()),
-
-    /** */
-    TX("--tx", new TxCommands()),
-
-    /** */
-    CACHE("--cache", new CacheCommands()),
-
-    /** */
-    WAL("--wal", new WalCommands()),
-
-    /** */
-    DIAGNOSTIC("--diagnostic", new DiagnosticCommand()),
-
-    /** Encryption features command. */
-    ENCRYPTION("--encryption", new EncryptionCommands()),
-
-    /** Kill command. */
-    KILL("--kill", new KillCommand()),
-
-    /** Snapshot commands. */
-    SNAPSHOT("--snapshot", new SnapshotCommand()),
-
-    /** Change Cluster tag command. */
-    CLUSTER_CHANGE_TAG("--change-tag", new ClusterChangeTagCommand()),
-
-    /** Metadata commands. */
-    METADATA("--meta", new MetadataCommand()),
-
-    /** */
-    SHUTDOWN_POLICY("--shutdown-policy", new ShutdownPolicyCommand()),
-
-    /** */
-    TRACING_CONFIGURATION("--tracing-configuration", new TracingConfigurationCommand()),
-
-    /** Warm-up command. */
-    WARM_UP("--warm-up", new WarmUpCommand()),
-
-    /** Commands to manage distributed properties. */
-    PROPERTY("--property", new PropertyCommand()),
-
-    /** Command for printing system view content. */
-    SYSTEM_VIEW("--system-view", new SystemViewCommand()),
-
-    /** Command for printing metric values. */
-    METRIC("--metric", new MetricCommand()),
-
-    /** */
-    PERSISTENCE("--persistence", new PersistenceCommand()),
-
-    /** Command to manage PDS defragmentation. */
-    DEFRAGMENTATION("--defragmentation", new DefragmentationCommand()),
-
-    /** Command to manage performance statistics. */
-    PERFORMANCE_STATISTICS("--performance-statistics", new PerformanceStatisticsCommand()),
-
-    /** Command to check/repair consistency. */
-    CONSISTENCY("--consistency", new ConsistencyCommand()),
-
-    /** Cdc commands. */
-    CDC("--cdc", new CdcCommand());
-
-    /** Private values copy so there's no need in cloning it every time. */
-    private static final CommandList[] VALUES = CommandList.values();
-
-    /** */
-    private final String text;
-
-    /** Command implementation. */
-    private final Command<?> command;
-
-    /**
-     * @param text Text.
-     * @param command Command implementation.
-     */
-    CommandList(String text, Command<?> command) {
-        this.text = text;
-        this.command = command;
-    }
-
-    /**
-     * @return Map with commands.
-     */
-    public static Map<String, Command<?>> commands() {
-        return Arrays.stream(VALUES).collect(
-            Collectors.toMap(CommandList::text, CommandList::command, (a, b) -> a, LinkedHashMap::new));
-    }
-
-    /**
-     * @return Command text.
-     */
-    public String text() {
-        return text;
-    }
-
-    /**
-     * @return Command implementation.
-     */
-    public Command<?> command() {
-        return command;
-    }
-
-    /** {@inheritDoc} */
-    @Override public String toString() {
-        return text;
-    }
-
-    /**
-     * @return command name
-     */
-    public String toCommandName() {
-        return text.substring(2).toUpperCase();
-    }
-}
diff --git a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/CommandLogger.java b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/CommandLogger.java
index 862ca417d43..10ebdb03e12 100644
--- a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/CommandLogger.java
+++ b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/CommandLogger.java
@@ -17,85 +17,12 @@
 
 package org.apache.ignite.internal.commandline;
 
-import java.util.Map;
-import java.util.UUID;
-import org.apache.ignite.IgniteLogger;
 import org.apache.ignite.internal.util.typedef.F;
-import org.apache.ignite.internal.util.typedef.internal.SB;
 
 /**
  * Utility class for creating {@code CommangHandler} log messages.
  */
 public class CommandLogger {
-    /** Indent for help output. */
-    public static final String INDENT = "  ";
-
-    /** Double indent for help output. */
-    public static final String DOUBLE_INDENT = INDENT + INDENT;
-
-    /**
-     * Join input parameters with specified {@code delimeter} between them.
-     *
-     * @param delimeter Specified delimeter.
-     * @param params Other input parameter.
-     * @return Joined paramaters with specified {@code delimeter}.
-     */
-    public static String join(String delimeter, Object... params) {
-        return join(new SB(), "", delimeter, params).toString();
-    }
-
-    /**
-     * Join input parameters with specified {@code delimeter} between them and append to the end {@code delimeter}.
-     *
-     * @param sb Specified string builder.
-     * @param sbDelimeter Delimeter between {@code sb} and appended {@code param}.
-     * @param delimeter Specified delimeter.
-     * @param params Other input parameter.
-     * @return SB with appended to the end joined paramaters with specified {@code delimeter}.
-     */
-    public static SB join(SB sb, String sbDelimeter, String delimeter, Object... params) {
-        if (!F.isEmpty(params)) {
-            sb.a(sbDelimeter);
-
-            for (Object par : params)
-                sb.a(par).a(delimeter);
-
-            sb.setLength(sb.length() - delimeter.length());
-        }
-
-        return sb;
-    }
-
-    /**
-     * Join input parameters with space and wrap optional braces {@code []}.
-     *
-     * @param params Other input parameter.
-     * @return Joined parameters wrapped optional braces.
-     */
-    public static String optional(Object... params) {
-        return join(new SB(), "[", " ", params).a("]").toString();
-    }
-
-    /**
-     * Concatenates input parameters to single string with OR delimiter {@code |}.
-     *
-     * @param params Remaining parameters.
-     * @return Concatenated string.
-     */
-    public static String or(Object... params) {
-        return join("|", params);
-    }
-
-    /**
-     * Join input parameters with space and wrap grouping braces {@code ()}.
-     *
-     * @param params Input parameter.
-     * @return Joined parameters wrapped grouped braces.
-     */
-    public static String grouped(Object... params) {
-        return join(new SB(), "(", " ", params).a(")").toString();
-    }
-
     /**
      * Generates readable error message from exception
      * @param e Exctption
@@ -114,30 +41,4 @@ public class CommandLogger {
 
         return msg;
     }
-
-    /**
-     * Prints exception messages to log
-     *
-     * @param exceptions map containing node ids and exceptions
-     * @param infoMsg single message to log
-     * @param logger IgniteLogger to use
-     * @return true if errors were printed.
-     */
-    public static boolean printErrors(Map<UUID, Exception> exceptions, String infoMsg, IgniteLogger logger) {
-        if (!F.isEmpty(exceptions)) {
-            logger.info(infoMsg);
-
-            for (Map.Entry<UUID, Exception> e : exceptions.entrySet()) {
-                logger.info(INDENT + "Node ID: " + e.getKey());
-
-                logger.info(INDENT + "Exception message:");
-                logger.info(DOUBLE_INDENT + e.getValue().getMessage());
-                logger.info("");
-            }
-
-            return true;
-        }
-
-        return false;
-    }
 }
diff --git a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/CommandsProvider.java b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/CommandsProvider.java
index f9ee95175c1..45e7053f508 100644
--- a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/CommandsProvider.java
+++ b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/CommandsProvider.java
@@ -17,12 +17,13 @@
 
 package org.apache.ignite.internal.commandline;
 
-import java.util.Map;
+import java.util.Collection;
+import org.apache.ignite.internal.management.api.Command;
 
 /**
  * Pluggable Ignite component that is responsible for providing list of commands for control utility.
  */
 public interface CommandsProvider {
     /** Gets all supported by this provider commands. */
-    public Map<String, Command<?>> commands();
+    public Collection<Command<?, ?>> commands();
 }
diff --git a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/CommonArgParser.java b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/CommonArgParser.java
deleted file mode 100644
index 2a16b809f2f..00000000000
--- a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/CommonArgParser.java
+++ /dev/null
@@ -1,402 +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.ignite.internal.commandline;
-
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import org.apache.ignite.IgniteLogger;
-import org.apache.ignite.IgniteSystemProperties;
-import org.apache.ignite.ssl.SslContextFactory;
-
-import static org.apache.ignite.IgniteSystemProperties.IGNITE_ENABLE_EXPERIMENTAL_COMMAND;
-import static org.apache.ignite.internal.client.GridClientConfiguration.DFLT_PING_INTERVAL;
-import static org.apache.ignite.internal.client.GridClientConfiguration.DFLT_PING_TIMEOUT;
-import static org.apache.ignite.internal.commandline.CommandHandler.UTILITY_NAME;
-import static org.apache.ignite.internal.commandline.CommandLogger.optional;
-import static org.apache.ignite.internal.commandline.TaskExecutor.DFLT_HOST;
-import static org.apache.ignite.internal.commandline.TaskExecutor.DFLT_PORT;
-import static org.apache.ignite.ssl.SslContextFactory.DFLT_SSL_PROTOCOL;
-
-/**
- * Common argument parser.
- * Also would parse high-level command and delegate parsing for its argument to the command.
- */
-public class CommonArgParser {
-    /** */
-    private final IgniteLogger logger;
-
-    /** */
-    private final Map<String, Command<?>> cmds;
-
-    /** */
-    static final String CMD_HOST = "--host";
-
-    /** */
-    static final String CMD_PORT = "--port";
-
-    /** */
-    static final String CMD_PASSWORD = "--password";
-
-    /** */
-    static final String CMD_USER = "--user";
-
-    /** Option is used for auto confirmation. */
-    public static final String CMD_AUTO_CONFIRMATION = "--yes";
-
-    /** */
-    static final String CMD_PING_INTERVAL = "--ping-interval";
-
-    /** */
-    static final String CMD_PING_TIMEOUT = "--ping-timeout";
-
-    /** Verbose mode. */
-    public static final String CMD_VERBOSE = "--verbose";
-
-    // SSL configuration section
-
-    /** */
-    static final String CMD_SSL_PROTOCOL = "--ssl-protocol";
-
-    /** */
-    static final String CMD_SSL_KEY_ALGORITHM = "--ssl-key-algorithm";
-
-    /** */
-    static final String CMD_SSL_CIPHER_SUITES = "--ssl-cipher-suites";
-
-    /** */
-    static final String CMD_KEYSTORE = "--keystore";
-
-    /** */
-    static final String CMD_KEYSTORE_PASSWORD = "--keystore-password";
-
-    /** */
-    static final String CMD_KEYSTORE_TYPE = "--keystore-type";
-
-    /** */
-    static final String CMD_TRUSTSTORE = "--truststore";
-
-    /** */
-    static final String CMD_TRUSTSTORE_PASSWORD = "--truststore-password";
-
-    /** */
-    static final String CMD_TRUSTSTORE_TYPE = "--truststore-type";
-
-    /** */
-    static final String CMD_ENABLE_EXPERIMENTAL = "--enable-experimental";
-
-    /** */
-    static final String CMD_SSL_FACTORY = "--ssl-factory";
-
-    /** List of optional auxiliary commands. */
-    private static final Set<String> AUX_COMMANDS = new HashSet<>();
-
-    /** Set of sensitive arguments */
-    private static final Set<String> SENSITIVE_ARGUMENTS = new HashSet<>();
-
-    static {
-        AUX_COMMANDS.add(CMD_HOST);
-        AUX_COMMANDS.add(CMD_PORT);
-
-        AUX_COMMANDS.add(CMD_PASSWORD);
-        AUX_COMMANDS.add(CMD_USER);
-
-        AUX_COMMANDS.add(CMD_AUTO_CONFIRMATION);
-        AUX_COMMANDS.add(CMD_VERBOSE);
-
-        AUX_COMMANDS.add(CMD_PING_INTERVAL);
-        AUX_COMMANDS.add(CMD_PING_TIMEOUT);
-
-        AUX_COMMANDS.add(CMD_SSL_PROTOCOL);
-        AUX_COMMANDS.add(CMD_SSL_KEY_ALGORITHM);
-        AUX_COMMANDS.add(CMD_SSL_CIPHER_SUITES);
-        AUX_COMMANDS.add(CMD_SSL_FACTORY);
-
-        AUX_COMMANDS.add(CMD_KEYSTORE);
-        AUX_COMMANDS.add(CMD_KEYSTORE_PASSWORD);
-        AUX_COMMANDS.add(CMD_KEYSTORE_TYPE);
-
-        AUX_COMMANDS.add(CMD_TRUSTSTORE);
-        AUX_COMMANDS.add(CMD_TRUSTSTORE_PASSWORD);
-        AUX_COMMANDS.add(CMD_TRUSTSTORE_TYPE);
-
-        SENSITIVE_ARGUMENTS.add(CMD_PASSWORD);
-        SENSITIVE_ARGUMENTS.add(CMD_KEYSTORE_PASSWORD);
-        SENSITIVE_ARGUMENTS.add(CMD_TRUSTSTORE_PASSWORD);
-    }
-
-    /**
-     * @param arg To check.
-     * @return True if provided argument is among sensitive one and not should be displayed.
-     */
-    public static boolean isSensitiveArgument(String arg) {
-        return SENSITIVE_ARGUMENTS.contains(arg);
-    }
-
-    /**
-     * @param logger Logger.
-     * @param cmds Supported commands.
-     */
-    public CommonArgParser(IgniteLogger logger, Map<String, Command<?>> cmds) {
-        this.logger = logger;
-        this.cmds = cmds;
-    }
-
-    /**
-     * Creates list of common utility options.
-     *
-     * @return Array of common utility options.
-     */
-    public static String[] getCommonOptions() {
-        List<String> list = new ArrayList<>(32);
-
-        list.add(optional(CMD_HOST, "HOST_OR_IP"));
-        list.add(optional(CMD_PORT, "PORT"));
-        list.add(optional(CMD_USER, "USER"));
-        list.add(optional(CMD_PASSWORD, "PASSWORD"));
-        list.add(optional(CMD_PING_INTERVAL, "PING_INTERVAL"));
-        list.add(optional(CMD_PING_TIMEOUT, "PING_TIMEOUT"));
-        list.add(optional(CMD_VERBOSE));
-        list.add(optional(CMD_SSL_PROTOCOL, "SSL_PROTOCOL[, SSL_PROTOCOL_2, ..., SSL_PROTOCOL_N]"));
-        list.add(optional(CMD_SSL_CIPHER_SUITES, "SSL_CIPHER_1[, SSL_CIPHER_2, ..., SSL_CIPHER_N]"));
-        list.add(optional(CMD_SSL_KEY_ALGORITHM, "SSL_KEY_ALGORITHM"));
-        list.add(optional(CMD_SSL_FACTORY, "SSL_FACTORY_PATH"));
-        list.add(optional(CMD_KEYSTORE_TYPE, "KEYSTORE_TYPE"));
-        list.add(optional(CMD_KEYSTORE, "KEYSTORE_PATH"));
-        list.add(optional(CMD_KEYSTORE_PASSWORD, "KEYSTORE_PASSWORD"));
-        list.add(optional(CMD_TRUSTSTORE_TYPE, "TRUSTSTORE_TYPE"));
-        list.add(optional(CMD_TRUSTSTORE, "TRUSTSTORE_PATH"));
-        list.add(optional(CMD_TRUSTSTORE_PASSWORD, "TRUSTSTORE_PASSWORD"));
-        list.add(optional(CMD_ENABLE_EXPERIMENTAL));
-
-        return list.toArray(new String[0]);
-    }
-
-    /**
-     * Parses and validates arguments.
-     *
-     * @param rawArgIter Iterator of arguments.
-     * @return Arguments bean.
-     * @throws IllegalArgumentException In case arguments aren't valid.
-     */
-    ConnectionAndSslParameters parseAndValidate(Iterator<String> rawArgIter) {
-        String host = DFLT_HOST;
-
-        String port = DFLT_PORT;
-
-        String user = null;
-
-        String pwd = null;
-
-        Long pingInterval = DFLT_PING_INTERVAL;
-
-        Long pingTimeout = DFLT_PING_TIMEOUT;
-
-        boolean autoConfirmation = false;
-
-        boolean verbose = false;
-
-        String sslProtocol = DFLT_SSL_PROTOCOL;
-
-        String sslCipherSuites = "";
-
-        String sslKeyAlgorithm = SslContextFactory.DFLT_KEY_ALGORITHM;
-
-        String sslKeyStoreType = SslContextFactory.DFLT_STORE_TYPE;
-
-        String sslKeyStorePath = null;
-
-        char sslKeyStorePassword[] = null;
-
-        String sslTrustStoreType = SslContextFactory.DFLT_STORE_TYPE;
-
-        String sslTrustStorePath = null;
-
-        char sslTrustStorePassword[] = null;
-
-        boolean experimentalEnabled = IgniteSystemProperties.getBoolean(IGNITE_ENABLE_EXPERIMENTAL_COMMAND);
-
-        CommandArgIterator argIter = new CommandArgIterator(rawArgIter, AUX_COMMANDS, cmds);
-
-        Command<?> command = null;
-
-        String sslFactoryCfg = null;
-
-        while (argIter.hasNextArg()) {
-            String str = argIter.nextArg("").toLowerCase();
-
-            Command<?> cmd = cmds.get(str);
-
-            if (cmd != null) {
-                if (command != null)
-                    throw new IllegalArgumentException("Only one action can be specified, but found at least two:" +
-                        cmd.toString() + ", " + command.toString());
-
-                cmd.parseArguments(argIter);
-
-                command = cmd;
-            }
-            else {
-                switch (str) {
-                    case CMD_HOST:
-                        host = argIter.nextArg("Expected host name");
-
-                        break;
-
-                    case CMD_PORT:
-                        port = argIter.nextArg("Expected port number");
-
-                        try {
-                            int p = Integer.parseInt(port);
-
-                            if (p <= 0 || p > 65535)
-                                throw new IllegalArgumentException("Invalid value for port: " + port);
-                        }
-                        catch (NumberFormatException ignored) {
-                            throw new IllegalArgumentException("Invalid value for port: " + port);
-                        }
-
-                        break;
-
-                    case CMD_PING_INTERVAL:
-                        pingInterval = argIter.nextNonNegativeLongArg("ping interval");
-
-                        break;
-
-                    case CMD_PING_TIMEOUT:
-                        pingTimeout = argIter.nextNonNegativeLongArg("ping timeout");
-
-                        break;
-
-                    case CMD_USER:
-                        user = argIter.nextArg("Expected user name");
-
-                        break;
-
-                    case CMD_PASSWORD:
-                        pwd = argIter.nextArg("Expected password");
-
-                        logger.info(securityWarningMessage(CMD_PASSWORD));
-
-                        break;
-
-                    case CMD_SSL_PROTOCOL:
-                        sslProtocol = argIter.nextArg("Expected SSL protocol");
-
-                        break;
-
-                    case CMD_SSL_CIPHER_SUITES:
-                        sslCipherSuites = argIter.nextArg("Expected SSL cipher suites");
-
-                        break;
-
-                    case CMD_SSL_KEY_ALGORITHM:
-                        sslKeyAlgorithm = argIter.nextArg("Expected SSL key algorithm");
-
-                        break;
-
-                    case CMD_KEYSTORE:
-                        sslKeyStorePath = argIter.nextArg("Expected SSL key store path");
-
-                        break;
-
-                    case CMD_KEYSTORE_PASSWORD:
-                        sslKeyStorePassword = argIter.nextArg("Expected SSL key store password").toCharArray();
-
-                        logger.info(securityWarningMessage(CMD_KEYSTORE_PASSWORD));
-
-                        break;
-
-                    case CMD_KEYSTORE_TYPE:
-                        sslKeyStoreType = argIter.nextArg("Expected SSL key store type");
-
-                        break;
-
-                    case CMD_TRUSTSTORE:
-                        sslTrustStorePath = argIter.nextArg("Expected SSL trust store path");
-
-                        break;
-
-                    case CMD_TRUSTSTORE_PASSWORD:
-                        sslTrustStorePassword = argIter.nextArg("Expected SSL trust store password").toCharArray();
-
-                        logger.info(securityWarningMessage(CMD_TRUSTSTORE_PASSWORD));
-
-                        break;
-
-                    case CMD_TRUSTSTORE_TYPE:
-                        sslTrustStoreType = argIter.nextArg("Expected SSL trust store type");
-
-                        break;
-
-                    case CMD_AUTO_CONFIRMATION:
-                        autoConfirmation = true;
-
-                        break;
-
-                    case CMD_VERBOSE:
-                        verbose = true;
-                        break;
-
-                    case CMD_ENABLE_EXPERIMENTAL:
-                        experimentalEnabled = true;
-                        break;
-
-                    case CMD_SSL_FACTORY:
-                        sslFactoryCfg = argIter.nextArg("Expected SSL factory config path");
-
-                        break;
-
-                    default:
-                        throw new IllegalArgumentException("Unexpected argument: " + str);
-                }
-            }
-        }
-
-        if (command == null)
-            throw new IllegalArgumentException("No action was specified");
-
-        if (!experimentalEnabled && command.experimental()) {
-            logger.warning(String.format("To use experimental command add --enable-experimental parameter for %s",
-                UTILITY_NAME));
-
-            throw new IllegalArgumentException("Experimental commands disabled");
-        }
-
-        return new ConnectionAndSslParameters(command, host, port, user, pwd,
-                pingTimeout, pingInterval, autoConfirmation, verbose,
-                sslProtocol, sslCipherSuites,
-                sslKeyAlgorithm, sslKeyStorePath, sslKeyStorePassword, sslKeyStoreType,
-                sslTrustStorePath, sslTrustStorePassword, sslTrustStoreType, sslFactoryCfg);
-    }
-
-    /**
-     * @param password Parsed password.
-     * @return String with warning to show for user.
-     */
-    private String securityWarningMessage(String password) {
-        final String pwdArgWarnFmt = "Warning: %s is insecure. " +
-            "Whenever possible, use interactive prompt for password (just discard %s option).";
-
-        return String.format(pwdArgWarnFmt, password, password);
-    }
-}
diff --git a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/ConnectionAndSslParameters.java b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/ConnectionAndSslParameters.java
index c642ed0d5cd..4dc5c5ab0ae 100644
--- a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/ConnectionAndSslParameters.java
+++ b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/ConnectionAndSslParameters.java
@@ -18,142 +18,108 @@
 package org.apache.ignite.internal.commandline;
 
 import org.apache.ignite.internal.client.GridClientConfiguration;
+import org.apache.ignite.internal.commandline.argument.parser.CLIArgumentParser;
+import org.apache.ignite.internal.dto.IgniteDataTransferObject;
+import org.apache.ignite.internal.management.api.Command;
+
+import static org.apache.ignite.internal.commandline.ArgumentParser.CMD_AUTO_CONFIRMATION;
+import static org.apache.ignite.internal.commandline.ArgumentParser.CMD_HOST;
+import static org.apache.ignite.internal.commandline.ArgumentParser.CMD_KEYSTORE;
+import static org.apache.ignite.internal.commandline.ArgumentParser.CMD_KEYSTORE_PASSWORD;
+import static org.apache.ignite.internal.commandline.ArgumentParser.CMD_KEYSTORE_TYPE;
+import static org.apache.ignite.internal.commandline.ArgumentParser.CMD_PASSWORD;
+import static org.apache.ignite.internal.commandline.ArgumentParser.CMD_PING_INTERVAL;
+import static org.apache.ignite.internal.commandline.ArgumentParser.CMD_PING_TIMEOUT;
+import static org.apache.ignite.internal.commandline.ArgumentParser.CMD_PORT;
+import static org.apache.ignite.internal.commandline.ArgumentParser.CMD_SSL_CIPHER_SUITES;
+import static org.apache.ignite.internal.commandline.ArgumentParser.CMD_SSL_FACTORY;
+import static org.apache.ignite.internal.commandline.ArgumentParser.CMD_SSL_KEY_ALGORITHM;
+import static org.apache.ignite.internal.commandline.ArgumentParser.CMD_SSL_PROTOCOL;
+import static org.apache.ignite.internal.commandline.ArgumentParser.CMD_TRUSTSTORE;
+import static org.apache.ignite.internal.commandline.ArgumentParser.CMD_TRUSTSTORE_PASSWORD;
+import static org.apache.ignite.internal.commandline.ArgumentParser.CMD_TRUSTSTORE_TYPE;
+import static org.apache.ignite.internal.commandline.ArgumentParser.CMD_USER;
+import static org.apache.ignite.internal.commandline.ArgumentParser.CMD_VERBOSE;
 
 /**
  * Container with common parsed and validated arguments.
  */
-public class ConnectionAndSslParameters {
-    /** Host. */
-    private String host;
-
-    /** Port. */
-    private String port;
-
+public class ConnectionAndSslParameters<A extends IgniteDataTransferObject> {
     /** User. */
     private String user;
 
     /** Password. */
     private String pwd;
 
-    /** Force option is used for auto confirmation. */
-    private boolean autoConfirmation;
-
-    /** Ping timeout for grid client. See {@link GridClientConfiguration#getPingTimeout()}. */
-    private long pingTimeout;
-
-    /** Ping interval for grid client. See {@link GridClientConfiguration#getPingInterval()}. */
-    private long pingInterval;
-
-    /** Verbose mode. */
-    private boolean verbose;
-
-    /** SSL Protocol. */
-    private String sslProtocol;
-
-    /** SSL Cipher suites. */
-    private String sslCipherSuites;
-
-    /** SSL Key Algorithm. */
-    private String sslKeyAlgorithm;
-
-    /** Keystore. */
-    private String sslKeyStorePath;
-
-    /** Keystore Type. */
-    private String sslKeyStoreType;
-
     /** Keystore Password. */
     private char[] sslKeyStorePassword;
 
-    /** Truststore. */
-    private String sslTrustStorePath;
-
-    /** Truststore Type. */
-    private String sslTrustStoreType;
-
     /** Truststore Password. */
     private char[] sslTrustStorePassword;
 
-    /** SSL factory config. */
-    private String sslFactoryCfgPath;
+    /** Command to execute. */
+    private final Command<A, ?> command;
+
+    /** Command to execute. */
+    private final Command<?, ?> root;
 
-    /** High-level command. */
-    private Command command;
+    /** Command argument. */
+    private final A arg;
+
+    /** */
+    private final CLIArgumentParser parser;
 
     /**
      * @param command Command.
-     * @param host Host.
-     * @param port Port.
-     * @param user User.
-     * @param pwd Password.
-     * @param pingTimeout Ping timeout. See {@link GridClientConfiguration#getPingTimeout()}.
-     * @param pingInterval Ping interval. See {@link GridClientConfiguration#getPingInterval()}.
-     * @param autoConfirmation Auto confirmation flag.
-     * @param verbose Verbose mode.
-     * @param sslProtocol SSL Protocol.
-     * @param sslCipherSuites SSL cipher suites.
-     * @param sslKeyAlgorithm SSL Key Algorithm.
-     * @param sslKeyStorePath Keystore.
-     * @param sslKeyStorePassword Keystore Password.
-     * @param sslKeyStoreType Keystore Type.
-     * @param sslTrustStorePath Truststore.
-     * @param sslTrustStorePassword Truststore Password.
-     * @param sslTrustStoreType Truststore Type.
-     * @param sslFactoryCfgPath SSL Factory config.
      */
-    public ConnectionAndSslParameters(Command command, String host, String port, String user, String pwd,
-        Long pingTimeout, Long pingInterval, boolean autoConfirmation, boolean verbose,
-        String sslProtocol, String sslCipherSuites, String sslKeyAlgorithm,
-        String sslKeyStorePath, char[] sslKeyStorePassword, String sslKeyStoreType,
-        String sslTrustStorePath, char[] sslTrustStorePassword, String sslTrustStoreType,
-        String sslFactoryCfgPath
+    public ConnectionAndSslParameters(
+        Command<A, ?> command,
+        Command<?, ?> root,
+        A arg,
+        CLIArgumentParser parser
     ) {
         this.command = command;
-        this.host = host;
-        this.port = port;
-        this.user = user;
-        this.pwd = pwd;
-
-        this.pingTimeout = pingTimeout;
-        this.pingInterval = pingInterval;
-
-        this.autoConfirmation = autoConfirmation;
-        this.verbose = verbose;
-
-        this.sslProtocol = sslProtocol;
-        this.sslCipherSuites = sslCipherSuites;
-
-        this.sslKeyAlgorithm = sslKeyAlgorithm;
-        this.sslKeyStorePath = sslKeyStorePath;
-        this.sslKeyStoreType = sslKeyStoreType;
-        this.sslKeyStorePassword = sslKeyStorePassword;
-
-        this.sslTrustStorePath = sslTrustStorePath;
-        this.sslTrustStoreType = sslTrustStoreType;
-        this.sslTrustStorePassword = sslTrustStorePassword;
-
-        this.sslFactoryCfgPath = sslFactoryCfgPath;
+        this.root = root;
+        this.arg = arg;
+        this.parser = parser;
+
+        this.user = parser.get(CMD_USER);
+        this.pwd = parser.get(CMD_PASSWORD);
+        this.sslKeyStorePassword = parser.get(CMD_KEYSTORE_PASSWORD);
+        this.sslTrustStorePassword = parser.get(CMD_TRUSTSTORE_PASSWORD);
     }
 
     /**
      * @return High-level command which were defined by user to run.
      */
-    public Command command() {
+    public Command<A, ?> command() {
         return command;
     }
 
+    /**
+     * @return High-level command which were defined by user to run.
+     */
+    public Command<?, ?> root() {
+        return root != null ? root : command;
+    }
+
+    /** */
+    public A commandArg() {
+        return arg;
+    }
+
     /**
      * @return host name
      */
     public String host() {
-        return host;
+        return parser.get(CMD_HOST);
     }
 
     /**
      * @return port number
      */
-    public String port() {
-        return port;
+    public int port() {
+        return parser.get(CMD_PORT);
     }
 
     /**
@@ -190,7 +156,7 @@ public class ConnectionAndSslParameters {
      * @return Ping timeout.
      */
     public long pingTimeout() {
-        return pingTimeout;
+        return parser.get(CMD_PING_TIMEOUT);
     }
 
     /**
@@ -199,49 +165,49 @@ public class ConnectionAndSslParameters {
      * @return Ping interval.
      */
     public long pingInterval() {
-        return pingInterval;
+        return parser.get(CMD_PING_INTERVAL);
     }
 
     /**
      * @return Auto confirmation option.
      */
     public boolean autoConfirmation() {
-        return autoConfirmation;
+        return parser.get(CMD_AUTO_CONFIRMATION);
     }
 
     /**
      * @return SSL protocol
      */
-    public String sslProtocol() {
-        return sslProtocol;
+    public String[] sslProtocol() {
+        return parser.get(CMD_SSL_PROTOCOL);
     }
 
     /**
      * @return SSL cipher suites.
      */
-    public String getSslCipherSuites() {
-        return sslCipherSuites;
+    public String[] getSslCipherSuites() {
+        return parser.get(CMD_SSL_CIPHER_SUITES);
     }
 
     /**
      * @return SSL Key Algorithm
      */
     public String sslKeyAlgorithm() {
-        return sslKeyAlgorithm;
+        return parser.get(CMD_SSL_KEY_ALGORITHM);
     }
 
     /**
      * @return Keystore
      */
     public String sslKeyStorePath() {
-        return sslKeyStorePath;
+        return parser.get(CMD_KEYSTORE);
     }
 
     /**
      * @return Keystore type
      */
     public String sslKeyStoreType() {
-        return sslKeyStoreType;
+        return parser.get(CMD_KEYSTORE_TYPE);
     }
 
     /**
@@ -264,14 +230,14 @@ public class ConnectionAndSslParameters {
      * @return Truststore
      */
     public String sslTrustStorePath() {
-        return sslTrustStorePath;
+        return parser.get(CMD_TRUSTSTORE);
     }
 
     /**
      * @return Truststore type
      */
     public String sslTrustStoreType() {
-        return sslTrustStoreType;
+        return parser.get(CMD_TRUSTSTORE_TYPE);
     }
 
     /**
@@ -294,7 +260,7 @@ public class ConnectionAndSslParameters {
      * @return Predefined SSL Factory config.
      */
     public String sslFactoryConfigPath() {
-        return sslFactoryCfgPath;
+        return parser.get(CMD_SSL_FACTORY);
     }
 
     /**
@@ -303,6 +269,6 @@ public class ConnectionAndSslParameters {
      * @return {@code True} if verbose mode is enabled.
      */
     public boolean verbose() {
-        return verbose;
+        return parser.get(CMD_VERBOSE);
     }
 }
diff --git a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/DeactivateCommand.java b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/DeactivateCommand.java
deleted file mode 100644
index eb3b9eb0d9a..00000000000
--- a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/DeactivateCommand.java
+++ /dev/null
@@ -1,108 +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.ignite.internal.commandline;
-
-import org.apache.ignite.IgniteLogger;
-import org.apache.ignite.cluster.ClusterState;
-import org.apache.ignite.internal.client.GridClient;
-import org.apache.ignite.internal.client.GridClientConfiguration;
-
-import static org.apache.ignite.internal.commandline.ClusterStateChangeCommand.FORCE_COMMAND;
-import static org.apache.ignite.internal.commandline.CommandList.DEACTIVATE;
-import static org.apache.ignite.internal.commandline.CommandList.SET_STATE;
-import static org.apache.ignite.internal.commandline.CommandLogger.optional;
-import static org.apache.ignite.internal.commandline.CommonArgParser.CMD_AUTO_CONFIRMATION;
-
-/**
- * Command to deactivate cluster.
- * @deprecated Use {@link ClusterStateChangeCommand} instead.
- */
-@Deprecated
-public class DeactivateCommand extends AbstractCommand<Void> {
-    /** Cluster name. */
-    private String clusterName;
-
-    /** If {@code true}, cluster deactivation will be forced. */
-    private boolean forceDeactivation;
-
-    /** {@inheritDoc} */
-    @Override public void printUsage(IgniteLogger logger) {
-        usage(logger, "Deactivate cluster (deprecated. Use " + SET_STATE.toString() + " instead):", DEACTIVATE,
-            optional(FORCE_COMMAND), optional(CMD_AUTO_CONFIRMATION));
-    }
-
-    /** {@inheritDoc} */
-    @Override public void prepareConfirmation(GridClientConfiguration clientCfg) throws Exception {
-        try (GridClient client = Command.startClient(clientCfg)) {
-            clusterName = client.state().clusterName();
-        }
-    }
-
-    /** {@inheritDoc} */
-    @Override public String confirmationPrompt() {
-        return "Warning: the command will deactivate a cluster \"" + clusterName + "\".";
-    }
-
-    /**
-     * Deactivate cluster.
-     *
-     * @param clientCfg Client configuration.
-     * @throws Exception If failed to deactivate.
-     */
-    @Override public Object execute(GridClientConfiguration clientCfg, IgniteLogger logger) throws Exception {
-        logger.warning("Command deprecated. Use " + SET_STATE.toString() + " instead.");
-
-        try (GridClient client = Command.startClient(clientCfg)) {
-            client.state().state(ClusterState.INACTIVE, forceDeactivation);
-
-            logger.info("Cluster deactivated");
-        }
-        catch (Exception e) {
-            logger.error("Failed to deactivate cluster.");
-
-            throw e;
-        }
-
-        return null;
-    }
-
-    /** {@inheritDoc} */
-    @Override public void parseArguments(CommandArgIterator argIter) {
-        forceDeactivation = false;
-
-        if (argIter.hasNextArg()) {
-            String arg = argIter.peekNextArg();
-
-            if (FORCE_COMMAND.equalsIgnoreCase(arg)) {
-                forceDeactivation = true;
-
-                argIter.nextArg("");
-            }
-        }
-    }
-
-    /** {@inheritDoc} */
-    @Override public Void arg() {
-        return null;
-    }
-
-    /** {@inheritDoc} */
-    @Override public String name() {
-        return DEACTIVATE.toCommandName();
-    }
-}
diff --git a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/DefragmentationCommand.java b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/DefragmentationCommand.java
deleted file mode 100644
index 4bd0d809e85..00000000000
--- a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/DefragmentationCommand.java
+++ /dev/null
@@ -1,248 +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.ignite.internal.commandline;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Locale;
-import java.util.Optional;
-import java.util.Set;
-import java.util.stream.Collectors;
-import org.apache.ignite.IgniteLogger;
-import org.apache.ignite.internal.client.GridClient;
-import org.apache.ignite.internal.client.GridClientConfiguration;
-import org.apache.ignite.internal.client.GridClientNode;
-import org.apache.ignite.internal.commandline.defragmentation.DefragmentationArguments;
-import org.apache.ignite.internal.commandline.defragmentation.DefragmentationSubcommands;
-import org.apache.ignite.internal.visor.VisorTaskArgument;
-import org.apache.ignite.internal.visor.defragmentation.VisorDefragmentationOperation;
-import org.apache.ignite.internal.visor.defragmentation.VisorDefragmentationTask;
-import org.apache.ignite.internal.visor.defragmentation.VisorDefragmentationTaskArg;
-import org.apache.ignite.internal.visor.defragmentation.VisorDefragmentationTaskResult;
-
-import static org.apache.ignite.internal.commandline.CommandList.DEFRAGMENTATION;
-import static org.apache.ignite.internal.commandline.defragmentation.DefragmentationSubcommands.CANCEL;
-import static org.apache.ignite.internal.commandline.defragmentation.DefragmentationSubcommands.SCHEDULE;
-
-/** */
-public class DefragmentationCommand implements Command<DefragmentationArguments> {
-    /** */
-    private static final String NODES_ARG = "--nodes";
-
-    /** */
-    private static final String CACHES_ARG = "--caches";
-
-    /** */
-    private DefragmentationArguments args;
-
-    /** {@inheritDoc} */
-    @Override public Object execute(GridClientConfiguration clientCfg, IgniteLogger log) throws Exception {
-        try (GridClient client = Command.startClient(clientCfg)) {
-            Optional<GridClientNode> firstNodeOpt = client.compute().nodes().stream().filter(GridClientNode::connectable).findFirst();
-
-            if (firstNodeOpt.isPresent()) {
-                VisorDefragmentationTaskResult res;
-
-                if (args.nodeIds() == null) {
-                    res = TaskExecutor.executeTaskByNameOnNode(
-                        client,
-                        VisorDefragmentationTask.class.getName(),
-                        convertArguments(),
-                        null, // Use node from clientCfg.
-                        clientCfg
-                    );
-                }
-                else {
-                    VisorTaskArgument<?> visorArg = new VisorTaskArgument<>(
-                        client.compute().nodes().stream().filter(
-                            node -> args.nodeIds().contains(node.consistentId().toString())
-                        ).map(GridClientNode::nodeId).collect(Collectors.toList()),
-                        convertArguments(),
-                        false
-                    );
-
-                    res = client.compute()
-                        .projection(firstNodeOpt.get())
-                        .execute(
-                            VisorDefragmentationTask.class.getName(),
-                            visorArg
-                        );
-                }
-
-                printResult(res, log);
-            }
-            else
-                log.warning("No nodes found in topology, command won't be executed.");
-        }
-        catch (Throwable t) {
-            log.error("Failed to execute defragmentation command='" + args.subcommand().text() + "'");
-            log.error(CommandLogger.errorMessage(t));
-
-            throw t;
-        }
-
-        return null;
-    }
-
-    /** */
-    private void printResult(VisorDefragmentationTaskResult res, IgniteLogger log) {
-        assert res != null;
-
-        log.info(res.getMessage());
-    }
-
-    /** {@inheritDoc} */
-    @Override public void parseArguments(CommandArgIterator argIter) {
-        DefragmentationSubcommands cmd = DefragmentationSubcommands.of(argIter.nextArg("Expected defragmentation subcommand."));
-
-        if (cmd == null)
-            throw new IllegalArgumentException("Expected correct defragmentation subcommand.");
-
-        args = new DefragmentationArguments(cmd);
-
-        switch (cmd) {
-            case SCHEDULE:
-                List<String> consistentIds = null;
-                List<String> cacheNames = null;
-
-                String subarg;
-
-                do {
-                    subarg = argIter.peekNextArg();
-
-                    if (subarg == null)
-                        break;
-
-                    subarg = subarg.toLowerCase(Locale.ENGLISH);
-
-                    switch (subarg) {
-                        case NODES_ARG: {
-                            argIter.nextArg("");
-
-                            Set<String> ids = argIter.nextStringSet(NODES_ARG);
-
-                            if (ids.isEmpty())
-                                throw new IllegalArgumentException("Consistent ids list is empty.");
-
-                            consistentIds = new ArrayList<>(ids);
-
-                            break;
-                        }
-
-                        case CACHES_ARG: {
-                            argIter.nextArg("");
-
-                            Set<String> ids = argIter.nextStringSet(CACHES_ARG);
-
-                            if (ids.isEmpty())
-                                throw new IllegalArgumentException("Caches list is empty.");
-
-                            cacheNames = new ArrayList<>(ids);
-
-                            break;
-                        }
-
-                        default:
-                            subarg = null;
-                    }
-                }
-                while (subarg != null);
-
-                if (consistentIds == null)
-                    throw new IllegalArgumentException("--nodes argument is missing.");
-
-                args.setNodeIds(consistentIds);
-                args.setCacheNames(cacheNames);
-
-                break;
-
-            case STATUS:
-            case CANCEL:
-                // No-op.
-        }
-    }
-
-    /** {@inheritDoc} */
-    @Override public DefragmentationArguments arg() {
-        return args;
-    }
-
-    /** {@inheritDoc} */
-    @Override public void printUsage(IgniteLogger log) {
-        String consistentIds = "consistentId0,consistentId1";
-
-        String cacheNames = "cache1,cache2,cache3";
-
-        usage(
-            log,
-            "Schedule PDS defragmentation on given nodes for all caches:",
-            DEFRAGMENTATION,
-            SCHEDULE.text(),
-            NODES_ARG,
-            consistentIds
-        );
-
-        usage(
-            log,
-            "Schedule PDS defragmentation on given nodes but only for given caches:",
-            DEFRAGMENTATION,
-            SCHEDULE.text(),
-            NODES_ARG,
-            consistentIds,
-            CACHES_ARG,
-            cacheNames
-        );
-
-        usage(
-            log,
-            "Cancel scheduled or active PDS defragmentation on underlying node:",
-            DEFRAGMENTATION,
-            CANCEL.text()
-        );
-    }
-
-    /** {@inheritDoc} */
-    @Override public String name() {
-        return DEFRAGMENTATION.toCommandName();
-    }
-
-    /** */
-    private VisorDefragmentationTaskArg convertArguments() {
-        return new VisorDefragmentationTaskArg(
-            convertSubcommand(args.subcommand()),
-            args.cacheNames()
-        );
-    }
-
-    /** */
-    private static VisorDefragmentationOperation convertSubcommand(DefragmentationSubcommands subcmd) {
-        switch (subcmd) {
-            case SCHEDULE:
-                return VisorDefragmentationOperation.SCHEDULE;
-
-            case STATUS:
-                return VisorDefragmentationOperation.STATUS;
-
-            case CANCEL:
-                return VisorDefragmentationOperation.CANCEL;
-
-            default:
-                throw new IllegalArgumentException(subcmd.name());
-        }
-    }
-}
diff --git a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/OutputFormat.java b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/OutputFormat.java
deleted file mode 100644
index 356cb4b2e88..00000000000
--- a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/OutputFormat.java
+++ /dev/null
@@ -1,66 +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.ignite.internal.commandline;
-
-import org.jetbrains.annotations.NotNull;
-
-/**
- *
- */
-public enum OutputFormat {
-    /** Single line. */
-    SINGLE_LINE("single-line"),
-
-    /** Multi line. */
-    MULTI_LINE("multi-line");
-
-    /** */
-    private final String text;
-
-    /** */
-    OutputFormat(String text) {
-        this.text = text;
-    }
-
-    /**
-     * @return Text.
-     */
-    public String text() {
-        return text;
-    }
-
-    /**
-     * Converts format name in console to enumerated value.
-     *
-     * @param text Format name in console.
-     * @return Enumerated value.
-     * @throws IllegalArgumentException If enumerated value not found.
-     */
-    public static OutputFormat fromConsoleName(@NotNull String text) {
-        for (OutputFormat format : values()) {
-            if (format.text.equals(text))
-                return format;
-        }
-
-        throw new IllegalArgumentException("Unknown output format " + text);
-    }
-
-    /** {@inheritDoc} */
-    @Override public String toString() {
-        return text;
-    }
-}
diff --git a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/PersistenceCommand.java b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/PersistenceCommand.java
deleted file mode 100644
index 8464cd1a82f..00000000000
--- a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/PersistenceCommand.java
+++ /dev/null
@@ -1,288 +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.ignite.internal.commandline;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Optional;
-import java.util.Set;
-import java.util.UUID;
-import org.apache.ignite.IgniteLogger;
-import org.apache.ignite.internal.client.GridClient;
-import org.apache.ignite.internal.client.GridClientConfiguration;
-import org.apache.ignite.internal.client.GridClientNode;
-import org.apache.ignite.internal.commandline.argument.CommandArgUtils;
-import org.apache.ignite.internal.commandline.persistence.CleanAndBackupSubcommandArg;
-import org.apache.ignite.internal.commandline.persistence.PersistenceArguments;
-import org.apache.ignite.internal.commandline.persistence.PersistenceSubcommands;
-import org.apache.ignite.internal.util.typedef.F;
-import org.apache.ignite.internal.visor.persistence.PersistenceCleanAndBackupSettings;
-import org.apache.ignite.internal.visor.persistence.PersistenceCleanAndBackupType;
-import org.apache.ignite.internal.visor.persistence.PersistenceTask;
-import org.apache.ignite.internal.visor.persistence.PersistenceTaskArg;
-import org.apache.ignite.internal.visor.persistence.PersistenceTaskResult;
-import org.apache.ignite.lang.IgniteBiTuple;
-
-import static org.apache.ignite.internal.commandline.CommandList.PERSISTENCE;
-import static org.apache.ignite.internal.commandline.CommandLogger.INDENT;
-import static org.apache.ignite.internal.commandline.TaskExecutor.executeTaskByNameOnNode;
-import static org.apache.ignite.internal.commandline.persistence.CleanAndBackupSubcommandArg.ALL;
-import static org.apache.ignite.internal.commandline.persistence.CleanAndBackupSubcommandArg.CACHES;
-import static org.apache.ignite.internal.commandline.persistence.CleanAndBackupSubcommandArg.CORRUPTED;
-import static org.apache.ignite.internal.commandline.persistence.PersistenceSubcommands.BACKUP;
-import static org.apache.ignite.internal.commandline.persistence.PersistenceSubcommands.CLEAN;
-import static org.apache.ignite.internal.commandline.persistence.PersistenceSubcommands.INFO;
-import static org.apache.ignite.internal.commandline.persistence.PersistenceSubcommands.of;
-
-/** */
-public class PersistenceCommand implements Command<PersistenceArguments> {
-    /** */
-    private PersistenceArguments cleaningArgs;
-
-    /** {@inheritDoc} */
-    @Override public Object execute(GridClientConfiguration clientCfg, IgniteLogger logger) throws Exception {
-        try (GridClient client = Command.startClient(clientCfg)) {
-            Optional<GridClientNode> firstNodeOpt = client.compute().nodes().stream().findFirst();
-
-            if (firstNodeOpt.isPresent()) {
-                UUID uuid = firstNodeOpt.get().nodeId();
-
-                PersistenceTaskResult res = executeTaskByNameOnNode(client,
-                    PersistenceTask.class.getName(),
-                    convertArguments(cleaningArgs),
-                    uuid,
-                    clientCfg
-                );
-
-                printResult(res, logger);
-            }
-            else
-                logger.warning("No nodes found in topology, command won't be executed.");
-        }
-        catch (Throwable t) {
-            logger.error("Failed to execute persistence command='" + cleaningArgs.subcommand().text() + "'");
-            logger.error(CommandLogger.errorMessage(t));
-
-            throw t;
-        }
-
-        return null;
-    }
-
-    /**
-     * Prints result of command execution: information about caches or result of clean/backup command.
-     *
-     * @param res {@link PersistenceTaskResult} object with results of command execution.
-     * @param logger {@link IgniteLogger} to print output to.
-     */
-    private void printResult(PersistenceTaskResult res, IgniteLogger logger) {
-        if (!res.inMaintenanceMode()) {
-            logger.warning("Persistence command can be sent only to node in Maintenance Mode.");
-
-            return;
-        }
-        //info command
-        else if (res.cachesInfo() != null) {
-            logger.info("Persistent caches found on node:");
-
-            //sort results so corrupted caches occur in the list at the top
-            res.cachesInfo().entrySet().stream().sorted((ci0, ci1) -> {
-                IgniteBiTuple<Boolean, Boolean> t0 = ci0.getValue();
-                IgniteBiTuple<Boolean, Boolean> t1 = ci1.getValue();
-
-                boolean corrupted0 = t0.get1() || t0.get2();
-                boolean corrupted1 = t1.get1() || t1.get2();
-
-                if (corrupted0 && corrupted1)
-                    return 0;
-                else if (!corrupted0 && !corrupted1)
-                    return 0;
-                else if (corrupted0 && !corrupted1)
-                    return -1;
-                else
-                    return 1;
-            }).forEach(
-                e -> {
-                    IgniteBiTuple<Boolean, Boolean> t = e.getValue();
-
-                    String status;
-
-                    if (!t.get1())
-                        status = "corrupted - WAL disabled globally.";
-                    else if (!t.get1())
-                        status = "corrupted - WAL disabled locally.";
-                    else
-                        status = "no corruption.";
-
-                    logger.info(INDENT + "cache name: " + e.getKey() + ". Status: " + status);
-                }
-            );
-        }
-        //clean command
-        else if (cleaningArgs != null && cleaningArgs.subcommand() == CLEAN) {
-            logger.info("Maintenance task is " + (!res.maintenanceTaskCompleted() ? "not " : "") + "fixed.");
-
-            List<String> cleanedCaches = res.handledCaches();
-
-            if (cleanedCaches != null && !cleanedCaches.isEmpty()) {
-                String cacheDirNames = String.join(", ", cleanedCaches);
-
-                logger.info("Cache directories were cleaned: [" + cacheDirNames + ']');
-            }
-
-            List<String> failedToHandleCaches = res.failedCaches();
-
-            if (failedToHandleCaches != null && !failedToHandleCaches.isEmpty()) {
-                String failedToHandleCachesStr = String.join(", ", failedToHandleCaches);
-
-                logger.info("Failed to clean following directories: [" + failedToHandleCachesStr + ']');
-            }
-        }
-        // backup command
-        else {
-            List<String> backupCompletedCaches = res.handledCaches();
-
-            if (backupCompletedCaches != null && !backupCompletedCaches.isEmpty()) {
-                String cacheDirNames = String.join(", ", backupCompletedCaches);
-
-                logger.info("Cache data files was backed up to the following directories in node's work directory: [" +
-                    cacheDirNames + ']');
-            }
-
-            List<String> backupFailedCaches = res.failedCaches();
-
-            if (backupFailedCaches != null && !backupFailedCaches.isEmpty()) {
-                String backupFailedCachesStr = String.join(", ", backupFailedCaches);
-
-                logger.info("Failed to backup the following directories in node's work directory: [" +
-                    backupFailedCachesStr + ']');
-            }
-        }
-    }
-
-    /** {@inheritDoc} */
-    @Override public PersistenceArguments arg() {
-        return cleaningArgs;
-    }
-
-    /** {@inheritDoc} */
-    @Override public void printUsage(IgniteLogger logger) {
-        final String cacheNames = "cache1,cache2,cache3";
-
-        usage(logger, "Print information about potentially corrupted caches on local node:",
-            PERSISTENCE);
-        usage(logger, "The same information is printed when info subcommand is passed:", PERSISTENCE,
-            INFO.text());
-
-        usage(logger, "Clean directories of caches with corrupted data files:", PERSISTENCE, CLEAN.text(),
-            CORRUPTED.argName());
-        usage(logger, "Clean directories of all caches:", PERSISTENCE, CLEAN.text(),
-            ALL.argName());
-        usage(logger, "Clean directories of only given caches:", PERSISTENCE, CLEAN.text(),
-            CACHES.argName(), cacheNames);
-
-        usage(logger, "Backup data files of corrupted caches only:", PERSISTENCE, BACKUP.text(),
-            CORRUPTED.argName());
-        usage(logger, "Backup data files of all caches:", PERSISTENCE, BACKUP.text(), ALL.argName());
-        usage(logger, "Backup data files of only given caches:", PERSISTENCE, BACKUP.text(),
-            CACHES.argName(), cacheNames);
-    }
-
-    /** {@inheritDoc} */
-    @Override public void parseArguments(CommandArgIterator argIter) {
-        if (!argIter.hasNextSubArg()) {
-            cleaningArgs = new PersistenceArguments.Builder(INFO).build();
-
-            return;
-        }
-
-        PersistenceSubcommands cmd = of(argIter.nextArg("Expected persistence maintenance action"));
-
-        if (cmd == null)
-            throw new IllegalArgumentException("Expected correct persistence maintenance action");
-
-        PersistenceArguments.Builder bldr = new PersistenceArguments.Builder(cmd);
-
-        switch (cmd) {
-            case BACKUP:
-            case CLEAN:
-                CleanAndBackupSubcommandArg cleanAndBackupSubcommandArg = CommandArgUtils.of(
-                    argIter.nextArg("Expected one of subcommand arguments"), CleanAndBackupSubcommandArg.class
-                );
-
-                if (cleanAndBackupSubcommandArg == null)
-                    throw new IllegalArgumentException("Expected one of subcommand arguments");
-
-                bldr.withCleanAndBackupSubcommandArg(cleanAndBackupSubcommandArg);
-
-                if (cleanAndBackupSubcommandArg == ALL || cleanAndBackupSubcommandArg == CORRUPTED)
-                    break;
-
-                if (cleanAndBackupSubcommandArg == CACHES) {
-                    Set<String> caches = argIter.nextStringSet("list of cache names");
-
-                    if (F.isEmpty(caches))
-                        throw new IllegalArgumentException("Empty list of cache names");
-
-                    bldr.withCacheNames(new ArrayList<>(caches));
-                }
-
-                break;
-        }
-
-        cleaningArgs = bldr.build();
-    }
-
-    /** {@inheritDoc} */
-    @Override public String name() {
-        return PERSISTENCE.toCommandName();
-    }
-
-    /** */
-    private PersistenceTaskArg convertArguments(PersistenceArguments args) {
-        PersistenceCleanAndBackupSettings cleanSettings = convertCleanAndBackupSettings(args);
-
-        PersistenceTaskArg taskArgs = new PersistenceTaskArg(args.subcommand().operation(), cleanSettings);
-
-        return taskArgs;
-    }
-
-    /** */
-    private PersistenceCleanAndBackupSettings convertCleanAndBackupSettings(PersistenceArguments args) {
-        if (args.subcommand() == INFO)
-            return null;
-
-        PersistenceCleanAndBackupType type;
-
-        switch (args.cleanArg()) {
-            case ALL:
-                type = PersistenceCleanAndBackupType.ALL;
-
-                break;
-            case CORRUPTED:
-                type = PersistenceCleanAndBackupType.CORRUPTED;
-
-                break;
-
-            default:
-                type = PersistenceCleanAndBackupType.CACHES;
-        }
-
-        return new PersistenceCleanAndBackupSettings(type, args.cachesList());
-    }
-}
diff --git a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/ShutdownPolicyCommand.java b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/ShutdownPolicyCommand.java
deleted file mode 100644
index f23d8bd21e0..00000000000
--- a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/ShutdownPolicyCommand.java
+++ /dev/null
@@ -1,106 +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.ignite.internal.commandline;
-
-import java.util.Comparator;
-import java.util.UUID;
-import org.apache.ignite.IgniteLogger;
-import org.apache.ignite.ShutdownPolicy;
-import org.apache.ignite.internal.client.GridClient;
-import org.apache.ignite.internal.client.GridClientConfiguration;
-import org.apache.ignite.internal.client.GridClientNode;
-import org.apache.ignite.internal.commandline.shutdown.ShutdownPolicyArgument;
-import org.apache.ignite.internal.visor.shutdown.VisorShutdownPolicyTask;
-import org.apache.ignite.internal.visor.shutdown.VisorShutdownPolicyTaskArg;
-import org.apache.ignite.internal.visor.shutdown.VisorShutdownPolicyTaskResult;
-
-import static org.apache.ignite.internal.commandline.CommandList.SHUTDOWN_POLICY;
-
-/**
- * Command for change or display policy for shutdown.
- */
-public class ShutdownPolicyCommand extends AbstractCommand<ShutdownPolicyArgument> {
-    /** Arguments. */
-    private ShutdownPolicyArgument shutdownPolicyArgument;
-
-    /** {@inheritDoc} */
-    @Override public Object execute(GridClientConfiguration clientCfg, IgniteLogger logger) throws Exception {
-        try (GridClient client = Command.startClient(clientCfg)) {
-            UUID coordinatorId = client.compute()
-                //Only non client node can be coordinator.
-                .nodes(node -> !node.isClient())
-                .stream()
-                .min(Comparator.comparingLong(GridClientNode::order))
-                .map(GridClientNode::nodeId)
-                .orElse(null);
-
-            VisorShutdownPolicyTaskResult res = TaskExecutor.executeTaskByNameOnNode(
-                client,
-                VisorShutdownPolicyTask.class.getName(),
-                toTaskArg(shutdownPolicyArgument),
-                coordinatorId,
-                clientCfg
-            );
-
-            logger.info("Cluster shutdown policy is " + res.getShutdown());
-        }
-
-        return null;
-    }
-
-    /**
-     * Convert command argument to task argument.
-     *
-     * @param arg Shutdown policy command argument.
-     * @return Argument for shutdown policy task.
-     */
-    private static VisorShutdownPolicyTaskArg toTaskArg(ShutdownPolicyArgument arg) {
-        return new VisorShutdownPolicyTaskArg(arg.getShutdown());
-    }
-
-    /** {@inheritDoc} */
-    @Override public ShutdownPolicyArgument arg() {
-        return shutdownPolicyArgument;
-    }
-
-    /** {@inheritDoc} */
-    @Override public void printUsage(IgniteLogger logger) {
-        usage(logger, "Set or display shutdown policy:", SHUTDOWN_POLICY,
-            CommandLogger.optional(CommandLogger.join("|", ShutdownPolicy.values())));
-    }
-
-    /** {@inheritDoc} */
-    @Override public String name() {
-        return SHUTDOWN_POLICY.toCommandName();
-    }
-
-    /** {@inheritDoc} */
-    @Override public void parseArguments(CommandArgIterator argIter) {
-        if (!argIter.hasNextSubArg()) {
-            this.shutdownPolicyArgument = new ShutdownPolicyArgument.Builder().build();
-
-            return;
-        }
-
-        ShutdownPolicyArgument.Builder builderArg = new ShutdownPolicyArgument.Builder();
-
-        builderArg.setShutdownPolicy(ShutdownPolicy.valueOf(argIter.nextArg("Shutdown policy is expected")));
-
-        shutdownPolicyArgument = builderArg.build();
-    }
-}
diff --git a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/StateCommand.java b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/StateCommand.java
deleted file mode 100644
index eb4a0da74f1..00000000000
--- a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/StateCommand.java
+++ /dev/null
@@ -1,97 +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.ignite.internal.commandline;
-
-import java.util.UUID;
-import org.apache.ignite.IgniteLogger;
-import org.apache.ignite.cluster.ClusterState;
-import org.apache.ignite.internal.client.GridClient;
-import org.apache.ignite.internal.client.GridClientClusterState;
-import org.apache.ignite.internal.client.GridClientConfiguration;
-
-import static org.apache.ignite.internal.commandline.CommandList.STATE;
-
-/**
- * Command to print cluster state.
- */
-public class StateCommand extends AbstractCommand<Void> {
-    /** {@inheritDoc} */
-    @Override public void printUsage(IgniteLogger logger) {
-        usage(logger, "Print current cluster state:", STATE);
-    }
-
-    /**
-     * Print cluster state.
-     *
-     * @param clientCfg Client configuration.
-     * @throws Exception If failed to print state.
-     */
-    @Override public Object execute(GridClientConfiguration clientCfg, IgniteLogger log) throws Exception {
-        try (GridClient client = Command.startClient(clientCfg)) {
-            GridClientClusterState state = client.state();
-
-            UUID id = state.id();
-            String tag = state.tag();
-
-            log.info("Cluster  ID: " + id);
-            log.info("Cluster tag: " + tag);
-
-            log.info(CommandHandler.DELIM);
-
-            ClusterState clusterState = state.state();
-
-            switch (clusterState) {
-                case ACTIVE:
-                    log.info("Cluster is active");
-
-                    break;
-
-                case INACTIVE:
-                    log.info("Cluster is inactive");
-
-                    break;
-
-                case ACTIVE_READ_ONLY:
-                    log.info("Cluster is active (read-only)");
-
-                    break;
-
-                default:
-                    throw new IllegalStateException("Unknown state: " + clusterState);
-            }
-        }
-        catch (Throwable e) {
-            if (!CommandHandler.isAuthError(e))
-                log.error("Failed to get cluster state.");
-
-            throw e;
-        }
-
-        return null;
-    }
-
-    /** {@inheritDoc} */
-    @Override public Void arg() {
-        return null;
-    }
-
-    /** {@inheritDoc} */
-    @Override public String name() {
-        return STATE.toCommandName();
-    }
-}
diff --git a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/StringBuilderOutputStream.java b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/StringBuilderOutputStream.java
deleted file mode 100644
index 70255ed3eef..00000000000
--- a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/StringBuilderOutputStream.java
+++ /dev/null
@@ -1,69 +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.ignite.internal.commandline;
-
-import java.io.OutputStream;
-import java.nio.charset.Charset;
-import org.apache.ignite.internal.util.GridStringBuilder;
-
-/**
- * Output stream that can be used to print some output to string builder.
- */
-public class StringBuilderOutputStream extends OutputStream {
-    /** */
-    private final GridStringBuilder sb;
-
-    /** */
-    protected final Charset encoding;
-
-    /** */
-    public StringBuilderOutputStream() {
-        this(new GridStringBuilder(), Charset.forName("UTF-8"));
-    }
-
-    /** */
-    public StringBuilderOutputStream(GridStringBuilder sb) {
-        this(sb, Charset.forName("UTF-8"));
-    }
-
-    /** */
-    public StringBuilderOutputStream(GridStringBuilder sb, Charset encoding) {
-        this.sb = sb;
-        this.encoding = encoding;
-    }
-
-    /** {@inheritDoc} */
-    @Override public void write(int b) {
-        sb.a((char)b);
-    }
-
-    /** {@inheritDoc} */
-    @Override public void write(byte b[]) {
-        sb.a(new String(b, encoding));
-    }
-
-    /** {@inheritDoc} */
-    @Override public void write(byte b[], int off, int len) {
-        sb.a(new String(b, off, len, encoding));
-    }
-
-    /** {@inheritDoc} */
-    @Override public String toString() {
-        return this.sb.toString();
-    }
-}
diff --git a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/TaskExecutor.java b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/TaskExecutor.java
deleted file mode 100644
index b4f88cb4e84..00000000000
--- a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/TaskExecutor.java
+++ /dev/null
@@ -1,198 +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.ignite.internal.commandline;
-
-import java.io.IOException;
-import java.net.InetAddress;
-import java.util.Collection;
-import java.util.List;
-import java.util.UUID;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-import org.apache.ignite.compute.ComputeTask;
-import org.apache.ignite.internal.client.GridClient;
-import org.apache.ignite.internal.client.GridClientCompute;
-import org.apache.ignite.internal.client.GridClientConfiguration;
-import org.apache.ignite.internal.client.GridClientDisconnectedException;
-import org.apache.ignite.internal.client.GridClientException;
-import org.apache.ignite.internal.client.GridClientNode;
-import org.apache.ignite.internal.util.IgniteUtils;
-import org.apache.ignite.internal.util.typedef.F;
-import org.apache.ignite.internal.visor.VisorTaskArgument;
-import org.apache.ignite.lang.IgniteBiTuple;
-
-/**
- * Visor task executor.
- */
-public class TaskExecutor {
-    /** */
-    public static final String DFLT_HOST = "127.0.0.1";
-
-    /** */
-    public static final String DFLT_PORT = "11211";
-
-    /** Broadcast uuid. */
-    public static final UUID BROADCAST_UUID = UUID.randomUUID();
-
-    /**
-     * @param client Client
-     * @param taskClsName Task class name.
-     * @param taskArgs Task args.
-     * @param nodeId Node ID to execute task at (if null, random node will be chosen by balancer).
-     * @param clientCfg
-     * @return Task result.
-     * @throws GridClientException If failed to execute task.
-     */
-    public static <R> R executeTaskByNameOnNode(
-        GridClient client,
-        String taskClsName,
-        Object taskArgs,
-        UUID nodeId,
-        GridClientConfiguration clientCfg
-    ) throws GridClientException {
-        GridClientCompute compute = client.compute();
-
-        if (nodeId == BROADCAST_UUID) {
-            Collection<GridClientNode> nodes = compute.nodes(GridClientNode::connectable);
-
-            if (F.isEmpty(nodes))
-                throw new GridClientDisconnectedException("Connectable nodes not found", null);
-
-            List<UUID> nodeIds = nodes.stream()
-                .map(GridClientNode::nodeId)
-                .collect(Collectors.toList());
-
-            return client.compute().execute(taskClsName, new VisorTaskArgument<>(nodeIds, taskArgs, false));
-        }
-
-        GridClientNode node = null;
-
-        if (nodeId == null) {
-            // Prefer node from connect string.
-            final String cfgAddr = clientCfg.getServers().iterator().next();
-
-            String[] parts = cfgAddr.split(":");
-
-            if (DFLT_HOST.equals(parts[0])) {
-                InetAddress addr;
-
-                try {
-                    addr = IgniteUtils.getLocalHost();
-                }
-                catch (IOException e) {
-                    throw new GridClientException("Can't get localhost name.", e);
-                }
-
-                if (addr.isLoopbackAddress())
-                    throw new GridClientException("Can't find localhost name.");
-
-                String origAddr = addr.getHostName() + ":" + parts[1];
-
-                node = listHosts(client).filter(tuple -> origAddr.equals(tuple.get2())).findFirst().map(IgniteBiTuple::get1).orElse(null);
-
-                if (node == null)
-                    node = listHostsByClientNode(client).filter(tuple -> tuple.get2().size() == 1 && cfgAddr.equals(tuple.get2().get(0))).
-                        findFirst().map(IgniteBiTuple::get1).orElse(null);
-            }
-            else
-                node = listHosts(client).filter(tuple -> cfgAddr.equals(tuple.get2())).findFirst().map(IgniteBiTuple::get1).orElse(null);
-
-            // Otherwise choose random node.
-            if (node == null)
-                node = getBalancedNode(compute);
-        }
-        else {
-            for (GridClientNode n : compute.nodes()) {
-                if (n.connectable() && nodeId.equals(n.nodeId())) {
-                    node = n;
-
-                    break;
-                }
-            }
-
-            if (node == null)
-                throw new IllegalArgumentException("Node with id=" + nodeId + " not found");
-        }
-
-        return compute.projection(node).execute(taskClsName, new VisorTaskArgument<>(node.nodeId(), taskArgs, false));
-    }
-
-    /**
-     * @param client Client.
-     * @param taskCls Task class.
-     * @param taskArgs Task arguments.
-     * @param clientCfg Client configuration.
-     * @return Task result.
-     * @throws GridClientException If failed to execute task.
-     */
-    public static <R> R executeTask(
-        GridClient client,
-        Class<? extends ComputeTask<?, R>> taskCls,
-        Object taskArgs,
-        GridClientConfiguration clientCfg
-    ) throws GridClientException {
-        return executeTaskByNameOnNode(client, taskCls.getName(), taskArgs, null, clientCfg);
-    }
-
-    /**
-     * @param client Client.
-     * @return List of hosts.
-     */
-    private static Stream<IgniteBiTuple<GridClientNode, String>> listHosts(GridClient client) throws GridClientException {
-        return client.compute()
-            .nodes(GridClientNode::connectable)
-            .stream()
-            .flatMap(node -> Stream.concat(
-                node.tcpAddresses() == null ? Stream.empty() : node.tcpAddresses().stream(),
-                node.tcpHostNames() == null ? Stream.empty() : node.tcpHostNames().stream()
-            ).map(addr -> new IgniteBiTuple<>(node, addr + ":" + node.tcpPort())));
-    }
-
-    /**
-     * @param client Client.
-     * @return List of hosts.
-     */
-    private static Stream<IgniteBiTuple<GridClientNode, List<String>>> listHostsByClientNode(
-        GridClient client
-    ) throws GridClientException {
-        return client.compute().nodes(GridClientNode::connectable).stream()
-            .map(
-                node -> new IgniteBiTuple<>(
-                    node,
-                    Stream.concat(
-                        node.tcpAddresses() == null ? Stream.empty() : node.tcpAddresses().stream(),
-                        node.tcpHostNames() == null ? Stream.empty() : node.tcpHostNames().stream()
-                    )
-                        .map(addr -> addr + ":" + node.tcpPort()).collect(Collectors.toList())
-                )
-            );
-    }
-
-    /**
-     * @param compute instance
-     * @return balanced node
-     */
-    public static GridClientNode getBalancedNode(GridClientCompute compute) throws GridClientException {
-        Collection<GridClientNode> nodes = compute.nodes(GridClientNode::connectable);
-
-        if (F.isEmpty(nodes))
-            throw new GridClientDisconnectedException("Connectable node not found", null);
-
-        return compute.balancer().balancedNode(nodes);
-    }
-}
diff --git a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/TracingConfigurationCommand.java b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/TracingConfigurationCommand.java
deleted file mode 100644
index a9ac3d9c7cc..00000000000
--- a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/TracingConfigurationCommand.java
+++ /dev/null
@@ -1,334 +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.ignite.internal.commandline;
-
-import java.util.Arrays;
-import java.util.Comparator;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.UUID;
-import java.util.function.Consumer;
-import org.apache.ignite.IgniteLogger;
-import org.apache.ignite.internal.client.GridClient;
-import org.apache.ignite.internal.client.GridClientConfiguration;
-import org.apache.ignite.internal.client.GridClientNode;
-import org.apache.ignite.internal.commandline.argument.CommandArgUtils;
-import org.apache.ignite.internal.commandline.tracing.configuration.TracingConfigurationArguments;
-import org.apache.ignite.internal.commandline.tracing.configuration.TracingConfigurationCommandArg;
-import org.apache.ignite.internal.commandline.tracing.configuration.TracingConfigurationSubcommand;
-import org.apache.ignite.internal.visor.tracing.configuration.VisorTracingConfigurationTask;
-import org.apache.ignite.internal.visor.tracing.configuration.VisorTracingConfigurationTaskArg;
-import org.apache.ignite.internal.visor.tracing.configuration.VisorTracingConfigurationTaskResult;
-import org.apache.ignite.spi.tracing.Scope;
-
-import static org.apache.ignite.internal.commandline.CommandList.TRACING_CONFIGURATION;
-import static org.apache.ignite.internal.commandline.CommandLogger.grouped;
-import static org.apache.ignite.internal.commandline.CommandLogger.join;
-import static org.apache.ignite.internal.commandline.CommandLogger.optional;
-import static org.apache.ignite.internal.commandline.TaskExecutor.executeTaskByNameOnNode;
-import static org.apache.ignite.internal.commandline.tracing.configuration.TracingConfigurationSubcommand.GET_ALL;
-import static org.apache.ignite.internal.commandline.tracing.configuration.TracingConfigurationSubcommand.RESET_ALL;
-import static org.apache.ignite.internal.commandline.tracing.configuration.TracingConfigurationSubcommand.of;
-import static org.apache.ignite.spi.tracing.TracingConfigurationParameters.SAMPLING_RATE_ALWAYS;
-import static org.apache.ignite.spi.tracing.TracingConfigurationParameters.SAMPLING_RATE_NEVER;
-
-/**
- * Commands associated with tracing configuration functionality.
- */
-public class TracingConfigurationCommand extends AbstractCommand<TracingConfigurationArguments> {
-    /** Arguments. */
-    private TracingConfigurationArguments args;
-
-    /** {@inheritDoc} */
-    @Override public void printUsage(IgniteLogger log) {
-        usage(
-            log,
-            "Print tracing configuration: ",
-            TRACING_CONFIGURATION);
-
-        usage(
-            log,
-            "Print tracing configuration: ",
-            TRACING_CONFIGURATION,
-            TracingConfigurationSubcommand.GET_ALL.text(),
-            optional(TracingConfigurationCommandArg.SCOPE.argName(), join("|", Scope.values())));
-
-        usage(
-            log,
-            "Print specific tracing configuration based on specified " +
-                TracingConfigurationCommandArg.SCOPE.argName() + " and " +
-                TracingConfigurationCommandArg.LABEL.argName() + ": ",
-            TRACING_CONFIGURATION,
-            TracingConfigurationSubcommand.GET.text(),
-            grouped(TracingConfigurationCommandArg.SCOPE.argName(), join("|", Scope.values())),
-            optional(TracingConfigurationCommandArg.LABEL.argName()));
-
-        usage(
-            log,
-            "Reset all specific tracing configuration the to default. If " +
-                TracingConfigurationCommandArg.SCOPE.argName() +
-                " is specified, then remove all label specific configuration for the given scope and reset given scope" +
-                " specific configuration to the default, if " + TracingConfigurationCommandArg.SCOPE.argName() +
-                " is skipped then reset all tracing configurations to the default. Print tracing configuration.",
-            TRACING_CONFIGURATION,
-            RESET_ALL.text(),
-            optional(TracingConfigurationCommandArg.SCOPE.argName(), join("|", Scope.values())));
-
-        usage(
-            log,
-            "Reset specific tracing configuration to the default. If both " +
-                TracingConfigurationCommandArg.SCOPE.argName() + " and " +
-                TracingConfigurationCommandArg.LABEL.argName() + " are specified then remove given configuration," +
-                " if only " + TracingConfigurationCommandArg.SCOPE.argName() +
-                " is specified then reset given configuration to the default." +
-                " Print reseted configuration.",
-            TRACING_CONFIGURATION,
-            TracingConfigurationSubcommand.RESET.text(),
-            grouped(TracingConfigurationCommandArg.SCOPE.argName(), join("|", Scope.values())),
-            optional(TracingConfigurationCommandArg.LABEL.argName()));
-
-        usage(
-            log,
-            "Set new tracing configuration. If both " +
-                TracingConfigurationCommandArg.SCOPE.argName() + " and " +
-                TracingConfigurationCommandArg.LABEL.argName() + " are specified then add or override label" +
-                " specific configuration, if only " + TracingConfigurationCommandArg.SCOPE.argName() +
-                " is specified, then override scope specific configuration. Print applied configuration.",
-            TRACING_CONFIGURATION,
-            TracingConfigurationSubcommand.SET.text(),
-            grouped(TracingConfigurationCommandArg.SCOPE.argName(), join("|", Scope.values()),
-            optional(TracingConfigurationCommandArg.LABEL.argName()),
-            optional(TracingConfigurationCommandArg.SAMPLING_RATE.argName(),
-                "Decimal value between 0 and 1, " +
-                "where 0 means never and 1 means always. " +
-                "More or less reflects the probability of sampling specific trace."),
-            optional(TracingConfigurationCommandArg.INCLUDED_SCOPES.argName(),
-                "Set of scopes with comma as separator ",
-                join("|", Scope.values()))));
-    }
-
-    /**
-     * Execute tracing-configuration command.
-     *
-     * @param clientCfg Client configuration.
-     * @throws Exception If failed to execute tracing-configuration action.
-     */
-    @Override public Object execute(GridClientConfiguration clientCfg, IgniteLogger log) throws Exception {
-        try (GridClient client = Command.startClient(clientCfg)) {
-            UUID crdId = client.compute()
-                //Only non client node can be coordinator.
-                .nodes(node -> !node.isClient())
-                .stream()
-                .min(Comparator.comparingLong(GridClientNode::order))
-                .map(GridClientNode::nodeId)
-                .orElse(null);
-
-            VisorTracingConfigurationTaskResult res = executeTaskByNameOnNode(
-                client,
-                VisorTracingConfigurationTask.class.getName(),
-                toVisorArguments(args),
-                crdId,
-                clientCfg
-            );
-
-            printResult(res, log::info);
-
-            return res;
-        }
-        catch (Throwable e) {
-            log.error("Failed to execute tracing-configuration command='" + args.command().text() + "'");
-
-            throw e;
-        }
-    }
-
-    /** {@inheritDoc} */
-    @Override public void parseArguments(CommandArgIterator argIter) {
-        // If there is no arguments, use list command.
-        if (!argIter.hasNextSubArg()) {
-            args = new TracingConfigurationArguments.Builder(TracingConfigurationSubcommand.GET_ALL).build();
-
-            return;
-        }
-
-        TracingConfigurationSubcommand cmd = of(argIter.nextArg("Expected tracing configuration action."));
-
-        if (cmd == null)
-            throw new IllegalArgumentException("Expected correct tracing configuration action.");
-
-        TracingConfigurationArguments.Builder tracingConfigurationArgs = new TracingConfigurationArguments.Builder(cmd);
-
-        Scope scope = null;
-
-        String lb = null;
-
-        double samplingRate = SAMPLING_RATE_NEVER;
-
-        Set<Scope> includedScopes = new HashSet<>();
-
-        while (argIter.hasNextSubArg()) {
-            TracingConfigurationCommandArg arg =
-                CommandArgUtils.of(argIter.nextArg(""), TracingConfigurationCommandArg.class);
-
-            String strVal;
-
-            assert arg != null;
-
-            switch (arg) {
-                case SCOPE: {
-                    String peekedNextArg = argIter.peekNextArg();
-
-                    if (!TracingConfigurationCommandArg.args().contains(peekedNextArg)) {
-                        strVal = argIter.nextArg(
-                            "The scope should be specified. The following " +
-                                "values can be used: " + Arrays.toString(Scope.values()) + '.');
-
-                        try {
-                            scope = Scope.valueOf(strVal);
-                        }
-                        catch (IllegalArgumentException e) {
-                            throw new IllegalArgumentException(
-                                "Invalid scope '" + strVal + "'. The following " +
-                                    "values can be used: " + Arrays.toString(Scope.values()) + '.');
-                        }
-                    }
-
-                    break;
-                }
-                case LABEL: {
-                    lb = argIter.nextArg(
-                        "The label should be specified.");
-
-                    break;
-                }
-                case SAMPLING_RATE: {
-                    strVal = argIter.nextArg(
-                        "The sampling rate should be specified. Decimal value between 0 and 1 should be used.");
-
-                    try {
-                        samplingRate = Double.parseDouble(strVal);
-                    }
-                    catch (IllegalArgumentException e) {
-                        throw new IllegalArgumentException(
-                            "Invalid sampling-rate '" + strVal + "'. Decimal value between 0 and 1 should be used.");
-                    }
-
-                    if (samplingRate < SAMPLING_RATE_NEVER || samplingRate > SAMPLING_RATE_ALWAYS)
-                        throw new IllegalArgumentException(
-                            "Invalid sampling-rate '" + strVal + "'. Decimal value between 0 and 1 should be used.");
-
-                    break;
-                }
-                case INCLUDED_SCOPES: {
-                    Set<String> setStrVals = argIter.nextStringSet(
-                        "At least one supported scope should be specified.");
-
-                    for (String scopeStrVal : setStrVals) {
-                        try {
-                            includedScopes.add(Scope.valueOf(scopeStrVal));
-                        }
-                        catch (IllegalArgumentException e) {
-                            throw new IllegalArgumentException(
-                                "Invalid supported scope '" + scopeStrVal + "'. The following " +
-                                    "values can be used: " + Arrays.toString(Scope.values()) + '.');
-                        }
-                    }
-
-                    break;
-                }
-            }
-        }
-
-        // Scope is a mandatory attribute for all sub-commands except get_all and reset_all.
-        if ((cmd != GET_ALL && cmd != RESET_ALL) && scope == null) {
-            throw new IllegalArgumentException(
-                "Scope attribute is missing. Following values can be used: " + Arrays.toString(Scope.values()) + '.');
-        }
-
-        switch (cmd) {
-            case GET_ALL:
-            case RESET_ALL: {
-                tracingConfigurationArgs.withScope(scope);
-
-                break;
-            }
-
-            case RESET:
-            case GET: {
-                tracingConfigurationArgs.withScope(scope).withLabel(lb);
-
-                break;
-            }
-
-            case SET: {
-                tracingConfigurationArgs.withScope(scope).withLabel(lb).withSamplingRate(samplingRate).
-                    withIncludedScopes(includedScopes);
-
-                break;
-            }
-
-            default: {
-                // We should never get here.
-                assert false : "Unexpected tracing configuration argument [arg= " + cmd + ']';
-            }
-        }
-
-        args = tracingConfigurationArgs.build();
-    }
-
-    /** {@inheritDoc} */
-    @Override public TracingConfigurationArguments arg() {
-        return args;
-    }
-
-    /** {@inheritDoc} */
-    @Override public String name() {
-        return TRACING_CONFIGURATION.toCommandName();
-    }
-
-    /** {@inheritDoc} */
-    @Override public boolean experimental() {
-        return true;
-    }
-
-    /**
-     * Print result.
-     *
-     * @param res Visor tracing configuration result.
-     * @param printer Printer.
-     */
-    private void printResult(VisorTracingConfigurationTaskResult res, Consumer<String> printer) {
-        res.print(printer);
-    }
-
-    /**
-     * Prepare task argument.
-     *
-     * @param args Argument from command line.
-     * @return Task argument.
-     */
-    private VisorTracingConfigurationTaskArg toVisorArguments(TracingConfigurationArguments args) {
-        return new VisorTracingConfigurationTaskArg(
-            args.command().visorBaselineOperation(),
-            args.scope(),
-            args.label(),
-            args.samplingRate(),
-            args.includedScopes()
-        );
-    }
-}
diff --git a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/TxCommandArg.java b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/TxCommandArg.java
deleted file mode 100644
index 4f4165b8837..00000000000
--- a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/TxCommandArg.java
+++ /dev/null
@@ -1,78 +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.ignite.internal.commandline;
-
-import org.apache.ignite.internal.commandline.argument.CommandArg;
-
-/**
- * Transaction command arguments name.
- */
-public enum TxCommandArg implements CommandArg {
-    /** */
-    TX_LIMIT("--limit"),
-
-    /** */
-    TX_ORDER("--order"),
-
-    /** */
-    TX_SERVERS("--servers"),
-
-    /** */
-    TX_CLIENTS("--clients"),
-
-    /** */
-    TX_DURATION("--min-duration"),
-
-    /** */
-    TX_SIZE("--min-size"),
-
-    /** */
-    TX_LABEL("--label"),
-
-    /** */
-    TX_NODES("--nodes"),
-
-    /** */
-    TX_XID("--xid"),
-
-    /** */
-    TX_KILL("--kill"),
-
-    /** */
-    TX_INFO("--info");
-
-    /** Option name. */
-    private final String name;
-
-    /**
-     * @param name Argument name.
-     */
-    TxCommandArg(String name) {
-        this.name = name;
-    }
-
-    /** {@inheritDoc} */
-    @Override public String argName() {
-        return name;
-    }
-
-    /** {@inheritDoc} */
-    @Override public String toString() {
-        return name;
-    }
-}
diff --git a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/TxCommands.java b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/TxCommands.java
deleted file mode 100644
index 60c8d6554b7..00000000000
--- a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/TxCommands.java
+++ /dev/null
@@ -1,558 +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.ignite.internal.commandline;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.regex.Pattern;
-import java.util.regex.PatternSyntaxException;
-import org.apache.ignite.IgniteLogger;
-import org.apache.ignite.cluster.ClusterNode;
-import org.apache.ignite.internal.IgniteFeatures;
-import org.apache.ignite.internal.client.GridClient;
-import org.apache.ignite.internal.client.GridClientConfiguration;
-import org.apache.ignite.internal.client.GridClientException;
-import org.apache.ignite.internal.commandline.argument.CommandArgUtils;
-import org.apache.ignite.internal.processors.cache.version.GridCacheVersion;
-import org.apache.ignite.internal.util.typedef.F;
-import org.apache.ignite.internal.visor.tx.FetchNearXidVersionTask;
-import org.apache.ignite.internal.visor.tx.TxKeyLockType;
-import org.apache.ignite.internal.visor.tx.TxMappingType;
-import org.apache.ignite.internal.visor.tx.TxVerboseId;
-import org.apache.ignite.internal.visor.tx.TxVerboseInfo;
-import org.apache.ignite.internal.visor.tx.TxVerboseKey;
-import org.apache.ignite.internal.visor.tx.VisorTxInfo;
-import org.apache.ignite.internal.visor.tx.VisorTxOperation;
-import org.apache.ignite.internal.visor.tx.VisorTxProjection;
-import org.apache.ignite.internal.visor.tx.VisorTxSortOrder;
-import org.apache.ignite.internal.visor.tx.VisorTxTask;
-import org.apache.ignite.internal.visor.tx.VisorTxTaskArg;
-import org.apache.ignite.internal.visor.tx.VisorTxTaskResult;
-import org.apache.ignite.transactions.TransactionState;
-
-import static org.apache.ignite.internal.client.util.GridClientUtils.checkFeatureSupportedByCluster;
-import static org.apache.ignite.internal.commandline.CommandList.TX;
-import static org.apache.ignite.internal.commandline.CommandLogger.DOUBLE_INDENT;
-import static org.apache.ignite.internal.commandline.CommandLogger.optional;
-import static org.apache.ignite.internal.commandline.CommandLogger.or;
-import static org.apache.ignite.internal.commandline.CommonArgParser.CMD_AUTO_CONFIRMATION;
-import static org.apache.ignite.internal.commandline.TaskExecutor.executeTask;
-import static org.apache.ignite.internal.commandline.TxCommandArg.TX_INFO;
-
-/**
- * Transaction commands.
- */
-public class TxCommands extends AbstractCommand<VisorTxTaskArg> {
-    /** Arguments */
-    private VisorTxTaskArg args;
-
-    /** Logger. */
-    private IgniteLogger logger;
-
-    /** {@inheritDoc} */
-    @Override public void printUsage(IgniteLogger logger) {
-        usage(logger, "List or kill transactions:", TX, getTxOptions());
-        usage(logger, "Print detailed information (topology and key lock ownership) about specific transaction:",
-            TX, TX_INFO.argName(), or("<TX identifier as GridCacheVersion [topVer=..., order=..., nodeOrder=...] " +
-                "(can be found in logs)>", "<TX identifier as UUID (can be retrieved via --tx command)>"));
-
-    }
-
-    /**
-     * @return Transaction command options.
-     */
-    private String[] getTxOptions() {
-        List<String> list = new ArrayList<>();
-
-        list.add(optional(TxCommandArg.TX_XID, "XID"));
-        list.add(optional(TxCommandArg.TX_DURATION, "SECONDS"));
-        list.add(optional(TxCommandArg.TX_SIZE, "SIZE"));
-        list.add(optional(TxCommandArg.TX_LABEL, "PATTERN_REGEX"));
-        list.add(optional(or(TxCommandArg.TX_SERVERS, TxCommandArg.TX_CLIENTS)));
-        list.add(optional(TxCommandArg.TX_NODES, "consistentId1[,consistentId2,....,consistentIdN]"));
-        list.add(optional(TxCommandArg.TX_LIMIT, "NUMBER"));
-        list.add(optional(TxCommandArg.TX_ORDER, or(VisorTxSortOrder.values())));
-        list.add(optional(TxCommandArg.TX_KILL));
-        list.add(optional(TX_INFO));
-        list.add(optional(CMD_AUTO_CONFIRMATION));
-
-        return list.toArray(new String[list.size()]);
-    }
-
-    /** {@inheritDoc} */
-    @Override public VisorTxTaskArg arg() {
-        return args;
-    }
-
-    /**
-     * Dump transactions information.
-     *
-     * @param clientCfg Client configuration.
-     */
-    @Override public Object execute(GridClientConfiguration clientCfg, IgniteLogger logger) throws Exception {
-        this.logger = logger;
-
-        try (GridClient client = Command.startClient(clientCfg)) {
-            if (args.getOperation() == VisorTxOperation.INFO)
-                return transactionInfo(client, clientCfg);
-
-            Map<ClusterNode, VisorTxTaskResult> res = executeTask(client, VisorTxTask.class, args, clientCfg);
-
-            if (res.isEmpty())
-                logger.info("Nothing found.");
-            else if (args.getOperation() == VisorTxOperation.KILL)
-                logger.info("Killed transactions:");
-            else
-                logger.info("Matching transactions:");
-
-            for (Map.Entry<ClusterNode, VisorTxTaskResult> entry : res.entrySet()) {
-                if (entry.getValue().getInfos().isEmpty())
-                    continue;
-
-                ClusterNode key = entry.getKey();
-
-                logger.info(key.getClass().getSimpleName() + " [id=" + key.id() +
-                    ", addrs=" + key.addresses() +
-                    ", order=" + key.order() +
-                    ", ver=" + key.version() +
-                    ", isClient=" + key.isClient() +
-                    ", consistentId=" + key.consistentId() +
-                    "]");
-
-                for (VisorTxInfo info : entry.getValue().getInfos())
-                    logger.info(info.toUserString());
-            }
-
-            return res;
-        }
-        catch (Throwable e) {
-            logger.error("Failed to perform operation.");
-            logger.error(CommandLogger.errorMessage(e));
-
-            throw e;
-        }
-    }
-
-    /**
-     * Dump transactions information.
-     *
-     * @param client Client.
-     */
-    private void transactions(GridClient client, GridClientConfiguration conf) throws GridClientException {
-        try {
-            if (args.getOperation() == VisorTxOperation.INFO) {
-                transactionInfo(client, conf);
-
-                return;
-            }
-
-            Map<ClusterNode, VisorTxTaskResult> res = executeTask(client, VisorTxTask.class, args, conf);
-
-            for (Map.Entry<ClusterNode, VisorTxTaskResult> entry : res.entrySet()) {
-                if (entry.getValue().getInfos().isEmpty())
-                    continue;
-
-                ClusterNode key = entry.getKey();
-
-                logger.info(nodeDescription(key));
-
-                for (VisorTxInfo info : entry.getValue().getInfos())
-                    logger.info(info.toUserString());
-            }
-        }
-        catch (Throwable e) {
-            logger.error("Failed to perform operation.");
-
-            throw e;
-        }
-    }
-
-    /** {@inheritDoc} */
-    @Override public String confirmationPrompt() {
-        if (args != null && args.getOperation() == VisorTxOperation.KILL)
-            return "Warning: the command will kill some transactions.";
-
-        return null;
-    }
-
-    /**
-     * @param argIter Argument iterator.
-     */
-    @Override public void parseArguments(CommandArgIterator argIter) {
-        VisorTxProjection proj = null;
-
-        Integer limit = null;
-
-        VisorTxSortOrder sortOrder = null;
-
-        Long duration = null;
-
-        Integer size = null;
-
-        String lbRegex = null;
-
-        List<String> consistentIds = null;
-
-        VisorTxOperation op = VisorTxOperation.LIST;
-
-        String xid = null;
-
-        TxVerboseId txVerboseId = null;
-
-        while (true) {
-            String str = argIter.peekNextArg();
-
-            if (str == null)
-                break;
-
-            TxCommandArg arg = CommandArgUtils.of(str, TxCommandArg.class);
-
-            if (arg == null)
-                break;
-
-            switch (arg) {
-                case TX_LIMIT:
-                    argIter.nextArg("");
-
-                    limit = (int)argIter.nextNonNegativeLongArg(TxCommandArg.TX_LIMIT.toString());
-
-                    break;
-
-                case TX_ORDER:
-                    argIter.nextArg("");
-
-                    sortOrder = VisorTxSortOrder.valueOf(argIter.nextArg(TxCommandArg.TX_ORDER.toString()).toUpperCase());
-
-                    break;
-
-                case TX_SERVERS:
-                    argIter.nextArg("");
-
-                    proj = VisorTxProjection.SERVER;
-                    break;
-
-                case TX_CLIENTS:
-                    argIter.nextArg("");
-
-                    proj = VisorTxProjection.CLIENT;
-                    break;
-
-                case TX_NODES:
-                    argIter.nextArg("");
-
-                    Set<String> ids = argIter.nextStringSet(TxCommandArg.TX_NODES.toString());
-
-                    if (ids.isEmpty()) {
-                        throw new IllegalArgumentException("Consistent id list is empty.");
-                    }
-
-                    consistentIds = new ArrayList<>(ids);
-                    break;
-
-                case TX_DURATION:
-                    argIter.nextArg("");
-
-                    duration = argIter.nextNonNegativeLongArg(TxCommandArg.TX_DURATION.toString()) * 1000L;
-                    break;
-
-                case TX_SIZE:
-                    argIter.nextArg("");
-
-                    size = (int)argIter.nextNonNegativeLongArg(TxCommandArg.TX_SIZE.toString());
-                    break;
-
-                case TX_LABEL:
-                    argIter.nextArg("");
-
-                    lbRegex = argIter.nextArg(TxCommandArg.TX_LABEL.toString());
-
-                    try {
-                        Pattern.compile(lbRegex);
-                    }
-                    catch (PatternSyntaxException ignored) {
-                        throw new IllegalArgumentException("Illegal regex syntax");
-                    }
-
-                    break;
-
-                case TX_XID:
-                    argIter.nextArg("");
-
-                    xid = argIter.nextArg(TxCommandArg.TX_XID.toString());
-                    break;
-
-                case TX_KILL:
-                    argIter.nextArg("");
-
-                    op = VisorTxOperation.KILL;
-                    break;
-
-                case TX_INFO:
-                    argIter.nextArg("");
-
-                    op = VisorTxOperation.INFO;
-
-                    txVerboseId = TxVerboseId.fromString(argIter.nextArg(TX_INFO.argName()));
-
-                    break;
-
-                default:
-                    throw new AssertionError();
-            }
-        }
-
-        if (proj != null && consistentIds != null)
-            throw new IllegalArgumentException("Projection can't be used together with list of consistent ids.");
-
-        this.args = new VisorTxTaskArg(op, limit, duration, size, null, proj,
-            consistentIds, xid, lbRegex, sortOrder, txVerboseId);
-    }
-
-    /**
-     * Provides text descrition of a cluster node.
-     *
-     * @param node Node.
-     */
-    private static String nodeDescription(ClusterNode node) {
-        return node.getClass().getSimpleName() + " [id=" + node.id() +
-            ", addrs=" + node.addresses() +
-            ", order=" + node.order() +
-            ", ver=" + node.version() +
-            ", isClient=" + node.isClient() +
-            ", consistentId=" + node.consistentId() +
-            "]";
-    }
-
-    /**
-     * Executes --tx --info command.
-     *
-     * @param client Client.
-     */
-    private Object transactionInfo(GridClient client, GridClientConfiguration conf) throws GridClientException {
-        checkFeatureSupportedByCluster(client, IgniteFeatures.TX_INFO_COMMAND, true, true);
-
-        GridCacheVersion nearXidVer = executeTask(client, FetchNearXidVersionTask.class, args.txInfoArgument(), conf);
-
-        boolean histMode = false;
-
-        if (nearXidVer != null) {
-            logger.info("Resolved transaction near XID version: " + nearXidVer);
-
-            args.txInfoArgument(new TxVerboseId(null, nearXidVer));
-        }
-        else {
-            logger.info("Active transactions not found.");
-
-            if (args.txInfoArgument().gridCacheVersion() != null) {
-                logger.info("Will try to peek history to find out whether transaction was committed / rolled back.");
-
-                histMode = true;
-            }
-            else {
-                logger.info("You can specify transaction in GridCacheVersion format in order to peek history " +
-                    "to find out whether transaction was committed / rolled back.");
-
-                return null;
-            }
-        }
-
-        Map<ClusterNode, VisorTxTaskResult> res = executeTask(client, VisorTxTask.class, args, conf);
-
-        if (histMode)
-            printTxInfoHistoricalResult(res);
-        else
-            printTxInfoResult(res);
-
-        return res;
-    }
-
-    /**
-     * Prints result of --tx --info command to output.
-     *
-     * @param res Response.
-     */
-    private void printTxInfoResult(Map<ClusterNode, VisorTxTaskResult> res) {
-        String lb = null;
-
-        Map<Integer, String> usedCaches = new HashMap<>();
-        Map<Integer, String> usedCacheGroups = new HashMap<>();
-        VisorTxInfo firstInfo = null;
-        TxVerboseInfo firstVerboseInfo = null;
-        Set<TransactionState> states = new HashSet<>();
-
-        for (Map.Entry<ClusterNode, VisorTxTaskResult> entry : res.entrySet()) {
-            for (VisorTxInfo info : entry.getValue().getInfos()) {
-                assert info.getTxVerboseInfo() != null;
-
-                if (lb == null)
-                    lb = info.getLabel();
-
-                if (firstInfo == null) {
-                    firstInfo = info;
-                    firstVerboseInfo = info.getTxVerboseInfo();
-                }
-
-                usedCaches.putAll(info.getTxVerboseInfo().usedCaches());
-                usedCacheGroups.putAll(info.getTxVerboseInfo().usedCacheGroups());
-                states.add(info.getState());
-            }
-        }
-
-        String indent = "";
-
-        logger.info("");
-        logger.info(indent + "Transaction detailed info:");
-
-        printTransactionDetailedInfo(
-            res, usedCaches, usedCacheGroups, firstInfo, firstVerboseInfo, states, indent + DOUBLE_INDENT);
-    }
-
-    /**
-     * Prints detailed info about transaction to output.
-     *
-     * @param res Response.
-     * @param usedCaches Used caches.
-     * @param usedCacheGroups Used cache groups.
-     * @param firstInfo First info.
-     * @param firstVerboseInfo First verbose info.
-     * @param states States.
-     * @param indent Indent.
-     */
-    private void printTransactionDetailedInfo(Map<ClusterNode, VisorTxTaskResult> res, Map<Integer, String> usedCaches,
-        Map<Integer, String> usedCacheGroups, VisorTxInfo firstInfo, TxVerboseInfo firstVerboseInfo,
-        Set<TransactionState> states, String indent) {
-        logger.info(indent + "Near XID version: " + firstVerboseInfo.nearXidVersion());
-        logger.info(indent + "Near XID version (UUID): " + firstInfo.getNearXid());
-        logger.info(indent + "Isolation: " + firstInfo.getIsolation());
-        logger.info(indent + "Concurrency: " + firstInfo.getConcurrency());
-        logger.info(indent + "Timeout: " + firstInfo.getTimeout());
-        logger.info(indent + "Initiator node: " + firstVerboseInfo.nearNodeId());
-        logger.info(indent + "Initiator node (consistent ID): " + firstVerboseInfo.nearNodeConsistentId());
-        logger.info(indent + "Label: " + firstInfo.getLabel());
-        logger.info(indent + "Topology version: " + firstInfo.getTopologyVersion());
-        logger.info(indent + "Used caches (ID to name): " + usedCaches);
-        logger.info(indent + "Used cache groups (ID to name): " + usedCacheGroups);
-        logger.info(indent + "States across the cluster: " + states);
-        logger.info(indent + "Transaction topology: ");
-
-        printTransactionTopology(res, indent + DOUBLE_INDENT);
-    }
-
-    /**
-     * Prints transaction topology to output.
-     *
-     * @param res Response.
-     * @param indent Indent.
-     */
-    private void printTransactionTopology(Map<ClusterNode, VisorTxTaskResult> res, String indent) {
-        for (Map.Entry<ClusterNode, VisorTxTaskResult> entry : res.entrySet()) {
-            logger.info(indent + nodeDescription(entry.getKey()) + ':');
-
-            printTransactionMappings(indent + DOUBLE_INDENT, entry);
-        }
-    }
-
-    /**
-     * Prints transaction mappings for specific cluster node to output.
-     *
-     * @param indent Indent.
-     * @param entry Entry.
-     */
-    private void printTransactionMappings(String indent, Map.Entry<ClusterNode, VisorTxTaskResult> entry) {
-        for (VisorTxInfo info : entry.getValue().getInfos()) {
-            TxVerboseInfo verboseInfo = info.getTxVerboseInfo();
-
-            if (verboseInfo != null) {
-                logger.info(indent + "Mapping [type=" + verboseInfo.txMappingType() + "]:");
-
-                printTransactionMapping(indent + DOUBLE_INDENT, info, verboseInfo);
-            }
-            else {
-                logger.info(indent + "Mapping [type=HISTORICAL]:");
-
-                logger.info(indent + DOUBLE_INDENT + "State: " + info.getState());
-            }
-        }
-    }
-
-    /**
-     * Prints specific transaction mapping to output.
-     *
-     * @param indent Indent.
-     * @param info Info.
-     * @param verboseInfo Verbose info.
-     */
-    private void printTransactionMapping(String indent, VisorTxInfo info, TxVerboseInfo verboseInfo) {
-        logger.info(indent + "XID version (UUID): " + info.getXid());
-        logger.info(indent + "State: " + info.getState());
-
-        if (verboseInfo.txMappingType() == TxMappingType.REMOTE) {
-            logger.info(indent + "Primary node: " + verboseInfo.dhtNodeId());
-            logger.info(indent + "Primary node (consistent ID): " + verboseInfo.dhtNodeConsistentId());
-        }
-
-        if (!F.isEmpty(verboseInfo.localTxKeys())) {
-            logger.info(indent + "Mapped keys:");
-
-            printTransactionKeys(indent + DOUBLE_INDENT, verboseInfo);
-        }
-    }
-
-    /**
-     * Prints keys of specific transaction mapping to output.
-     *
-     * @param indent Indent.
-     * @param verboseInfo Verbose info.
-     */
-    private void printTransactionKeys(String indent, TxVerboseInfo verboseInfo) {
-        for (TxVerboseKey txVerboseKey : verboseInfo.localTxKeys()) {
-            logger.info(indent + (txVerboseKey.read() ? "Read" : "Write") +
-                " [lock=" + txVerboseKey.lockType() + "]: " + txVerboseKey.txKey());
-
-            if (txVerboseKey.lockType() == TxKeyLockType.AWAITS_LOCK)
-                logger.info(indent + DOUBLE_INDENT + "Lock owner XID: " + txVerboseKey.ownerVersion());
-        }
-    }
-
-    /**
-     * Prints results of --tx --info to output in case requested transaction is not active.
-     *
-     * @param res Response.
-     */
-    private void printTxInfoHistoricalResult(Map<ClusterNode, VisorTxTaskResult> res) {
-        if (F.isEmpty(res))
-            logger.info("Transaction was not found in history across the cluster.");
-        else {
-            logger.info("Transaction was found in completed versions history of the following nodes:");
-
-            for (Map.Entry<ClusterNode, VisorTxTaskResult> entry : res.entrySet()) {
-                logger.info(DOUBLE_INDENT + nodeDescription(entry.getKey()) + ':');
-                logger.info(DOUBLE_INDENT + DOUBLE_INDENT + "State: " + entry.getValue().getInfos().get(0).getState());
-            }
-        }
-    }
-
-    /** {@inheritDoc} */
-    @Override public String name() {
-        return TX.toCommandName();
-    }
-}
diff --git a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/WalCommands.java b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/WalCommands.java
deleted file mode 100644
index 670eca58a43..00000000000
--- a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/WalCommands.java
+++ /dev/null
@@ -1,270 +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.ignite.internal.commandline;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import org.apache.ignite.IgniteLogger;
-import org.apache.ignite.internal.client.GridClient;
-import org.apache.ignite.internal.client.GridClientConfiguration;
-import org.apache.ignite.internal.util.typedef.F;
-import org.apache.ignite.internal.util.typedef.T2;
-import org.apache.ignite.internal.util.typedef.internal.U;
-import org.apache.ignite.internal.visor.misc.VisorClusterNode;
-import org.apache.ignite.internal.visor.misc.VisorWalTask;
-import org.apache.ignite.internal.visor.misc.VisorWalTaskArg;
-import org.apache.ignite.internal.visor.misc.VisorWalTaskOperation;
-import org.apache.ignite.internal.visor.misc.VisorWalTaskResult;
-
-import static org.apache.ignite.internal.commandline.CommandArgIterator.isCommandOrOption;
-import static org.apache.ignite.internal.commandline.CommandList.WAL;
-import static org.apache.ignite.internal.commandline.CommandLogger.DOUBLE_INDENT;
-import static org.apache.ignite.internal.commandline.CommandLogger.INDENT;
-import static org.apache.ignite.internal.commandline.CommandLogger.optional;
-import static org.apache.ignite.internal.commandline.CommonArgParser.CMD_AUTO_CONFIRMATION;
-import static org.apache.ignite.internal.commandline.TaskExecutor.executeTask;
-
-/**
- * Wal commands.
- */
-public class WalCommands extends AbstractCommand<T2<String, String>> {
-    /** */
-    static final String WAL_PRINT = "print";
-
-    /** */
-    static final String WAL_DELETE = "delete";
-
-    /** */
-    private IgniteLogger logger;
-
-    /**
-     * Wal action.
-     */
-    private String walAct;
-
-    /**
-     * Wal arguments.
-     */
-    private String walArgs;
-
-    /** {@inheritDoc} */
-    @Override public void printUsage(IgniteLogger logger) {
-        usage(logger, "Print absolute paths of unused archived wal segments on each node:", WAL,
-            WAL_PRINT, "[consistentId1,consistentId2,....,consistentIdN]");
-        usage(logger, "Delete unused archived wal segments on each node:", WAL, WAL_DELETE,
-            "[consistentId1,consistentId2,....,consistentIdN]", optional(CMD_AUTO_CONFIRMATION));
-    }
-
-    /**
-     * Execute WAL command.
-     *
-     * @param clientCfg Client configuration.
-     * @throws Exception If failed to execute wal action.
-     */
-    @Override public Object execute(GridClientConfiguration clientCfg, IgniteLogger logger) throws Exception {
-        this.logger = logger;
-
-        try (GridClient client = Command.startClient(clientCfg)) {
-            switch (walAct) {
-                case WAL_DELETE:
-                    deleteUnusedWalSegments(client, walArgs, clientCfg);
-
-                    break;
-
-                case WAL_PRINT:
-                default:
-                    printUnusedWalSegments(client, walArgs, clientCfg);
-
-                    break;
-            }
-        }
-
-        return null;
-    }
-
-    /** {@inheritDoc} */
-    @Override public String confirmationPrompt() {
-        if (WAL_DELETE.equals(walAct))
-            return "Warning: the command will delete unused WAL segments.";
-
-        return null;
-    }
-
-    /** {@inheritDoc} */
-    @Override public void parseArguments(CommandArgIterator argIter) {
-        String str = argIter.nextArg("Expected arguments for " + WAL.text());
-
-        String walAct = str.toLowerCase();
-
-        if (WAL_PRINT.equals(walAct) || WAL_DELETE.equals(walAct)) {
-            String walArgs = (str = argIter.peekNextArg()) != null && !isCommandOrOption(str)
-                ? argIter.nextArg("Unexpected argument for " + WAL.text() + ": " + walAct)
-                : "";
-
-            this.walAct = walAct;
-            this.walArgs = walArgs;
-        }
-        else
-            throw new IllegalArgumentException("Unexpected action " + walAct + " for " + WAL.text());
-    }
-
-    /**
-     * @return Tuple where first string is wal action, second - wal arguments.
-     */
-    @Override public T2<String, String> arg() {
-        return new T2<>(walAct, walArgs);
-    }
-
-    /**
-     * Execute delete unused WAL segments task.
-     *  @param client Client.
-     * @param walArgs WAL args.
-     * @param clientCfg Client configuration.
-     */
-    private void deleteUnusedWalSegments(
-        GridClient client,
-        String walArgs,
-        GridClientConfiguration clientCfg
-    ) throws Exception {
-        VisorWalTaskResult res = executeTask(client, VisorWalTask.class,
-            walArg(VisorWalTaskOperation.DELETE_UNUSED_WAL_SEGMENTS, walArgs), clientCfg);
-        printDeleteWalSegments0(res);
-    }
-
-    /**
-     * Execute print unused WAL segments task.
-     *  @param client Client.
-     * @param walArgs Wal args.
-     * @param clientCfg Client configuration.
-     */
-    private void printUnusedWalSegments(
-        GridClient client,
-        String walArgs,
-        GridClientConfiguration clientCfg
-    ) throws Exception {
-        VisorWalTaskResult res = executeTask(client, VisorWalTask.class,
-            walArg(VisorWalTaskOperation.PRINT_UNUSED_WAL_SEGMENTS, walArgs), clientCfg);
-        printUnusedWalSegments0(res);
-    }
-
-    /**
-     * Prepare WAL task argument.
-     *
-     * @param op Operation.
-     * @param s Argument from command line.
-     * @return Task argument.
-     */
-    private VisorWalTaskArg walArg(VisorWalTaskOperation op, String s) {
-        List<String> consistentIds = null;
-
-        if (!F.isEmpty(s)) {
-            consistentIds = new ArrayList<>();
-
-            for (String consistentId : s.split(","))
-                consistentIds.add(consistentId.trim());
-        }
-
-        switch (op) {
-            case DELETE_UNUSED_WAL_SEGMENTS:
-            case PRINT_UNUSED_WAL_SEGMENTS:
-                return new VisorWalTaskArg(op, consistentIds);
-
-            default:
-                return new VisorWalTaskArg(VisorWalTaskOperation.PRINT_UNUSED_WAL_SEGMENTS, consistentIds);
-        }
-
-    }
-
-    /**
-     * Print list of unused wal segments.
-     *
-     * @param taskRes Task result with baseline topology.
-     */
-    private void printUnusedWalSegments0(VisorWalTaskResult taskRes) {
-        logger.info("Unused wal segments per node:");
-        logger.info("");
-
-        Map<String, Collection<String>> res = taskRes.results();
-        Map<String, Exception> failRes = taskRes.exceptions();
-        Map<String, VisorClusterNode> nodesInfo = taskRes.getNodesInfo();
-
-        for (Map.Entry<String, Collection<String>> entry : res.entrySet()) {
-            VisorClusterNode node = nodesInfo.get(entry.getKey());
-
-            logger.info("Node=" + node.getConsistentId());
-            logger.info(DOUBLE_INDENT + "addresses " + U.addressesAsString(node.getAddresses(), node.getHostNames()));
-
-            for (String fileName : entry.getValue())
-                logger.info(INDENT + fileName);
-
-            logger.info("");
-        }
-
-        for (Map.Entry<String, Exception> entry : failRes.entrySet()) {
-            VisorClusterNode node = nodesInfo.get(entry.getKey());
-
-            logger.info("Node=" + node.getConsistentId());
-            logger.info(DOUBLE_INDENT + "addresses " + U.addressesAsString(node.getAddresses(), node.getHostNames()));
-            logger.info(INDENT + "failed with error: " + entry.getValue().getMessage());
-            logger.info("");
-        }
-    }
-
-    /**
-     * Print list of unused wal segments.
-     *
-     * @param taskRes Task result with baseline topology.
-     */
-    private void printDeleteWalSegments0(VisorWalTaskResult taskRes) {
-        logger.info("WAL segments deleted for nodes:");
-        logger.info("");
-
-        Map<String, Collection<String>> res = taskRes.results();
-        Map<String, Exception> errors = taskRes.exceptions();
-        Map<String, VisorClusterNode> nodesInfo = taskRes.getNodesInfo();
-
-        for (Map.Entry<String, Collection<String>> entry : res.entrySet()) {
-            VisorClusterNode node = nodesInfo.get(entry.getKey());
-
-            logger.info("Node=" + node.getConsistentId());
-            logger.info(DOUBLE_INDENT + "addresses " + U.addressesAsString(node.getAddresses(), node.getHostNames()));
-            logger.info("");
-        }
-
-        for (Map.Entry<String, Exception> entry : errors.entrySet()) {
-            VisorClusterNode node = nodesInfo.get(entry.getKey());
-
-            logger.info("Node=" + node.getConsistentId());
-            logger.info(DOUBLE_INDENT + "addresses " + U.addressesAsString(node.getAddresses(), node.getHostNames()));
-            logger.info(INDENT + "failed with error: " + entry.getValue().getMessage());
-            logger.info("");
-        }
-    }
-
-    /** {@inheritDoc} */
-    @Override public String name() {
-        return WAL.toCommandName();
-    }
-
-    /** {@inheritDoc} */
-    @Override public boolean experimental() {
-        return true;
-    }
-}
diff --git a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/WarmUpCommand.java b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/WarmUpCommand.java
deleted file mode 100644
index 0732c77b028..00000000000
--- a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/WarmUpCommand.java
+++ /dev/null
@@ -1,127 +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.ignite.internal.commandline;
-
-import org.apache.ignite.IgniteLogger;
-import org.apache.ignite.internal.client.GridClientBeforeNodeStart;
-import org.apache.ignite.internal.client.GridClientConfiguration;
-import org.apache.ignite.internal.client.GridClientDisconnectedException;
-import org.apache.ignite.internal.client.GridClientException;
-import org.apache.ignite.internal.commandline.argument.CommandArg;
-import org.apache.ignite.internal.commandline.argument.CommandArgUtils;
-
-import static java.util.Objects.isNull;
-import static org.apache.ignite.internal.commandline.CommandList.WARM_UP;
-
-/**
- * Command for interacting with warm-up.
- */
-public class WarmUpCommand extends AbstractCommand<Void> {
-    /** {@inheritDoc} */
-    @Override public void printUsage(IgniteLogger logger) {
-        usage(logger, "Stop warm-up:", WARM_UP, WarmUpCommandArg.STOP.argName());
-    }
-
-    /** {@inheritDoc} */
-    @Override public String name() {
-        return CommandList.WARM_UP.toCommandName();
-    }
-
-    /** {@inheritDoc} */
-    @Override public Void arg() {
-        return null;
-    }
-
-    /** {@inheritDoc} */
-    @Override public void parseArguments(CommandArgIterator argIter) {
-        boolean stop = false;
-
-        while (true) {
-            String nextArg = argIter.peekNextArg();
-
-            if (nextArg == null)
-                break;
-
-            WarmUpCommandArg arg = CommandArgUtils.of(nextArg, WarmUpCommandArg.class);
-
-            if (isNull(arg))
-                break;
-
-            switch (arg) {
-                case STOP:
-                    argIter.nextArg("");
-
-                    stop = true;
-                    break;
-
-                default:
-                    throw new AssertionError();
-            }
-        }
-
-        if (!stop)
-            throw new IllegalArgumentException(WarmUpCommandArg.STOP.argName() + " argument is missing.");
-    }
-
-    /** {@inheritDoc} */
-    @Override public String confirmationPrompt() {
-        return "Warning: command will stop warm-up.";
-    }
-
-    /** {@inheritDoc} */
-    @Override public Object execute(GridClientConfiguration clientCfg, IgniteLogger log) throws Exception {
-        try (GridClientBeforeNodeStart client = Command.startClientBeforeNodeStart(clientCfg)) {
-            client.beforeStartState().stopWarmUp();
-        }
-        catch (GridClientDisconnectedException e) {
-            throw new GridClientException(e.getCause());
-        }
-
-        return true;
-    }
-
-    /**
-     * Warm-up command arguments name.
-     */
-    private enum WarmUpCommandArg implements CommandArg {
-        /** Stop warm-up argument. */
-        STOP("--stop");
-
-        /** Option name. */
-        private final String name;
-
-        /**
-         * Constructor.
-         *
-         * @param name Argument name.
-         */
-        WarmUpCommandArg(String name) {
-            this.name = name;
-        }
-
-        /** {@inheritDoc} */
-        @Override public String argName() {
-            return name;
-        }
-
-        /** {@inheritDoc} */
-        @Override public String toString() {
-            return name;
-        }
-    }
-}
diff --git a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/argument/CommandArg.java b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/argument/CommandArg.java
deleted file mode 100644
index 0665ddabe61..00000000000
--- a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/argument/CommandArg.java
+++ /dev/null
@@ -1,28 +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.ignite.internal.commandline.argument;
-
-/**
- * Command argument interface.
- */
-public interface CommandArg {
-    /**
-     * @return Argument name.
-     */
-    String argName();
-}
diff --git a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/argument/CommandArgUtils.java b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/argument/CommandArgUtils.java
deleted file mode 100644
index 6cd16f17c0a..00000000000
--- a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/argument/CommandArgUtils.java
+++ /dev/null
@@ -1,46 +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.ignite.internal.commandline.argument;
-
-import org.jetbrains.annotations.Nullable;
-
-/**
- * Utility class for control.sh arguments.
- */
-public class CommandArgUtils {
-    /**
-     * Tries convert {@code text} to one of values {@code enumClass}.
-     * @param text Input test.
-     * @param enumClass {@link CommandArg} enum class.
-     * @param <E>
-     * @return Converted argument or {@code null} if convert failed.
-     */
-    public static <E extends Enum<E> & CommandArg> @Nullable E of(String text, Class<E> enumClass) {
-        for (E e : enumClass.getEnumConstants()) {
-            if (e.argName().equalsIgnoreCase(text))
-                return e;
-        }
-
-        return null;
-    }
-
-    /** Private constructor. */
-    private CommandArgUtils() {
-        /* No-op. */
-    }
-}
diff --git a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/argument/parser/CLIArgument.java b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/argument/parser/CLIArgument.java
index 80b91f36c47..94ce189a7a7 100644
--- a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/argument/parser/CLIArgument.java
+++ b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/argument/parser/CLIArgument.java
@@ -17,6 +17,7 @@
 
 package org.apache.ignite.internal.commandline.argument.parser;
 
+import java.util.function.BiConsumer;
 import java.util.function.Function;
 import java.util.function.Supplier;
 
@@ -25,6 +26,9 @@ import java.util.function.Supplier;
  * @param <T> Value type.
  */
 public class CLIArgument<T> {
+    /** */
+    private final BiConsumer<String, T> EMPTY = (name, val) -> {};
+
     /** */
     private final String name;
 
@@ -40,28 +44,44 @@ public class CLIArgument<T> {
     /** */
     private final Function<CLIArgumentParser, T> dfltValSupplier;
 
+    /** */
+    private final BiConsumer<String, T> validator;
+
     /** */
     public static <T> CLIArgument<T> optionalArg(String name, String usage, Class<T> type) {
-        return new CLIArgument<>(name, usage, true, type, null);
+        return new CLIArgument<>(name, usage, true, type, null, null);
     }
 
     /** */
     public static <T> CLIArgument<T> optionalArg(String name, String usage, Class<T> type, Supplier<T> dfltValSupplier) {
-        return new CLIArgument<>(name, usage, true, type, p -> dfltValSupplier.get());
+        return new CLIArgument<>(name, usage, true, type, p -> dfltValSupplier.get(), null);
     }
 
     /** */
-    public static <T> CLIArgument<T> optionalArg(String name, String usage, Class<T> type, Function<CLIArgumentParser, T> dfltValSupplier) {
-        return new CLIArgument<>(name, usage, true, type, dfltValSupplier);
+    public static <T> CLIArgument<T> optionalArg(
+        String name,
+        String usage,
+        Class<T> type,
+        Function<CLIArgumentParser, T> dfltValSupplier,
+        BiConsumer<String, T> validator
+    ) {
+        return new CLIArgument<>(name, usage, true, type, dfltValSupplier, validator);
     }
 
     /** */
     public static <T> CLIArgument<T> mandatoryArg(String name, String usage, Class<T> type) {
-        return new CLIArgument<>(name, usage, false, type, null);
+        return new CLIArgument<>(name, usage, false, type, null, null);
     }
 
     /** */
-    public CLIArgument(String name, String usage, boolean isOptional, Class<T> type, Function<CLIArgumentParser, T> dfltValSupplier) {
+    public CLIArgument(
+        String name,
+        String usage,
+        boolean isOptional,
+        Class<T> type,
+        Function<CLIArgumentParser, T> dfltValSupplier,
+        BiConsumer<String, T> validator
+    ) {
         this.name = name;
         this.usage = usage;
         this.isOptional = isOptional;
@@ -69,6 +89,7 @@ public class CLIArgument<T> {
         this.dfltValSupplier = dfltValSupplier == null
             ? (type.equals(Boolean.class) ? p -> (T)Boolean.FALSE : p -> null)
             : dfltValSupplier;
+        this.validator = validator;
     }
 
     /** */
@@ -95,4 +116,9 @@ public class CLIArgument<T> {
     public Function<CLIArgumentParser, T> defaultValueSupplier() {
         return dfltValSupplier;
     }
+
+    /** */
+    public BiConsumer<String, T> validator() {
+        return validator == null ? EMPTY : validator;
+    }
 }
diff --git a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/argument/parser/CLIArgumentParser.java b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/argument/parser/CLIArgumentParser.java
index 9bf30eff2b9..f361f751d55 100644
--- a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/argument/parser/CLIArgumentParser.java
+++ b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/argument/parser/CLIArgumentParser.java
@@ -17,32 +17,50 @@
 
 package org.apache.ignite.internal.commandline.argument.parser;
 
+import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
-import java.util.UUID;
-import java.util.function.Supplier;
 import org.apache.ignite.IgniteException;
 import org.apache.ignite.internal.util.GridStringBuilder;
 
 import static java.util.stream.Collectors.toSet;
+import static org.apache.ignite.internal.management.api.CommandUtils.NAME_PREFIX;
+import static org.apache.ignite.internal.management.api.CommandUtils.parseVal;
 
 /**
  * Parser for command line arguments.
  */
 public class CLIArgumentParser {
+    /** */
+    private final List<CLIArgument<?>> positionalArgCfg;
+
     /** */
     private final Map<String, CLIArgument<?>> argConfiguration = new LinkedHashMap<>();
 
+    /** */
+    private final List<Object> parsedPositionalArgs = new ArrayList<>();
+
     /** */
     private final Map<String, Object> parsedArgs = new HashMap<>();
 
     /** */
     public CLIArgumentParser(List<CLIArgument<?>> argConfiguration) {
+        this(Collections.emptyList(), argConfiguration);
+    }
+
+    /** */
+    public CLIArgumentParser(
+        List<CLIArgument<?>> positionalArgConfig,
+        List<CLIArgument<?>> argConfiguration
+    ) {
+        this.positionalArgCfg = positionalArgConfig;
+
         for (CLIArgument<?> cliArgument : argConfiguration)
             this.argConfiguration.put(cliArgument.name(), cliArgument);
     }
@@ -57,63 +75,60 @@ public class CLIArgumentParser {
         Set<String> obligatoryArgs =
             argConfiguration.values().stream().filter(a -> !a.optional()).map(CLIArgument::name).collect(toSet());
 
+        int positionalIdx = 0;
+
         while (argsIter.hasNext()) {
             String arg = argsIter.next();
 
-            CLIArgument<?> cliArg = argConfiguration.get(arg);
+            CLIArgument<?> cliArg = argConfiguration.get(arg.toLowerCase());
+
+            if (cliArg == null) {
+                if (positionalIdx < positionalArgCfg.size()) {
+                    cliArg = positionalArgCfg.get(positionalIdx);
 
-            if (cliArg == null)
-                throw new IgniteException("Unexpected argument: " + arg);
+                    Object value = parseVal(arg, cliArg.type());
 
-            if (cliArg.type().equals(Boolean.class))
-                parsedArgs.put(cliArg.name(), true);
-            else {
-                if (!argsIter.hasNext())
-                    throw new IgniteException("Please specify a value for argument: " + arg);
+                    ((CLIArgument<Object>)cliArg).validator().accept(cliArg.name(), value);
 
-                String strVal = argsIter.next();
+                    parsedPositionalArgs.add(value);
 
-                parsedArgs.put(cliArg.name(), parseVal(strVal, cliArg.type()));
+                    positionalIdx++;
+                }
+                else
+                    throw new IllegalArgumentException("Unexpected argument: " + arg);
+
+                continue;
             }
+            else if (parsedArgs.get(cliArg.name()) != null)
+                throw new IllegalArgumentException(cliArg.name() + " argument specified twice");
 
-            obligatoryArgs.remove(cliArg.name());
-        }
+            boolean bool = cliArg.type().equals(Boolean.class) || cliArg.type().equals(boolean.class);
 
-        if (!obligatoryArgs.isEmpty())
-            throw new IgniteException("Mandatory argument(s) missing: " + obligatoryArgs);
-    }
+            if (!bool && !argsIter.hasNext())
+                throw new IllegalArgumentException("Please specify a value for argument: " + arg);
 
-    /** */
-    private <T> T parseVal(String val, Class<T> type) {
-        if (type == String.class)
-            return (T)val;
-        else if (type == String[].class)
-            return (T)val.split(",");
-        else if (type == Integer.class)
-            return (T)wrapNumberFormatException(() -> Integer.parseInt(val), val, Integer.class);
-        else if (type == Long.class)
-            return (T)wrapNumberFormatException(() -> Long.parseLong(val), val, Long.class);
-        else if (type == UUID.class)
-            return (T)UUID.fromString(val);
-
-        throw new IgniteException("Unsupported argument type: " + type.getName());
-    }
+            String strVal = bool ? null : argsIter.next();
 
-    /**
-     * Wrap {@link NumberFormatException} to get more user friendly message.
-     *
-     * @param closure Closure that parses number.
-     * @param val String value.
-     * @param expectedType Expected type.
-     * @return Parsed result, if parse had success.
-     */
-    private Object wrapNumberFormatException(Supplier<Object> closure, String val, Class<? extends Number> expectedType) {
-        try {
-            return closure.get();
-        }
-        catch (NumberFormatException e) {
-            throw new NumberFormatException("Can't parse number '" + val + "', expected type: " + expectedType.getName());
+            if (strVal != null && strVal.startsWith(NAME_PREFIX))
+                throw new IllegalArgumentException("Unexpected value: " + strVal);
+
+            try {
+                Object value = parseVal(strVal, cliArg.type());
+
+                ((CLIArgument<Object>)cliArg).validator().accept(cliArg.name(), value);
+
+                parsedArgs.put(cliArg.name(), value);
+            }
+            catch (IllegalArgumentException e) {
+                throw new IllegalArgumentException("Failed to parse " + cliArg.name() + " command argument. "
+                    + e.getMessage());
+            }
+
+            obligatoryArgs.remove(cliArg.name());
         }
+
+        if (!obligatoryArgs.isEmpty())
+            throw new IllegalArgumentException("Mandatory argument(s) missing: " + obligatoryArgs);
     }
 
     /**
@@ -148,6 +163,20 @@ public class CLIArgumentParser {
         return get(arg);
     }
 
+    /**
+     * Get parsed positional argument value.
+     *
+     * @param position Argument position.
+     * @param <T> Value type.
+     * @return Value.
+     */
+    public <T> T get(int position) {
+        if (parsedPositionalArgs.size() - 1 < position)
+            return null;
+
+        return (T)parsedPositionalArgs.get(position);
+    }
+
     /**
      * Returns usage description.
      *
diff --git a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/baseline/BaselineArguments.java b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/baseline/BaselineArguments.java
deleted file mode 100644
index 78a2a920545..00000000000
--- a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/baseline/BaselineArguments.java
+++ /dev/null
@@ -1,173 +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.ignite.internal.commandline.baseline;
-
-import java.util.List;
-
-/**
- * This class contains all possible arguments after parsing baseline command input.
- */
-public class BaselineArguments {
-    /** Command. */
-    private BaselineSubcommands cmd;
-
-    /**
-     * {@code true} if auto-adjust should be enable, {@code false} if it should be disable, {@code null} if no operation
-     * needed.
-     */
-    private Boolean enableAutoAdjust;
-
-    /** New value of soft timeout. */
-    private Long softBaselineTimeout;
-
-    /** Requested topology version. */
-    private long topVer = -1;
-
-    /** List of consistent ids for operation. */
-    List<String> consistentIds;
-
-    /**
-     * @param cmd Command.
-     * @param enableAutoAdjust Auto-adjust enabled feature.
-     * @param softBaselineTimeout New value of soft timeout.
-     * @param topVer Requested topology version.
-     * @param consistentIds List of consistent ids for operation.
-     */
-    public BaselineArguments(BaselineSubcommands cmd, Boolean enableAutoAdjust, Long softBaselineTimeout,
-        long topVer, List<String> consistentIds) {
-        this.cmd = cmd;
-        this.enableAutoAdjust = enableAutoAdjust;
-        this.softBaselineTimeout = softBaselineTimeout;
-        this.topVer = topVer;
-        this.consistentIds = consistentIds;
-    }
-
-    /**
-     * @return Command.
-     */
-    public BaselineSubcommands getCmd() {
-        return cmd;
-    }
-
-    /**
-     * @return {@code true} if auto-adjust should be enable, {@code false} if it should be disable, {@code null} if no
-     * operation needed.
-     */
-    public Boolean getEnableAutoAdjust() {
-        return enableAutoAdjust;
-    }
-
-    /**
-     * @return New value of soft timeout.
-     */
-    public Long getSoftBaselineTimeout() {
-        return softBaselineTimeout;
-    }
-
-    /**
-     * @return Requested topology version.
-     */
-    public long getTopVer() {
-        return topVer;
-    }
-
-    /**
-     * @return List of consistent ids for operation.
-     */
-    public List<String> getConsistentIds() {
-        return consistentIds;
-    }
-
-    /**
-     * Builder of {@link BaselineArguments}.
-     */
-    public static class Builder {
-        /** Command. */
-        private BaselineSubcommands cmd;
-
-        /**
-         * {@code true} if auto-adjust should be enable, {@code false} if it should be disable, {@code null} if no
-         * operation needed.
-         */
-        private Boolean enable;
-
-        /** New value of soft timeout. */
-        private Long timeout;
-
-        /** Requested topology version. */
-        private long ver = -1;
-
-        /** List of consistent ids for operation. */
-        private List<String> ids;
-
-        /**
-         * @param cmd Command.
-         */
-        public Builder(BaselineSubcommands cmd) {
-            this.cmd = cmd;
-        }
-
-        /**
-         * @param enable {@code true} if auto-adjust should be enable, {@code false} if it should be disable, {@code
-         * null} if no operation needed.
-         * @return This instance for chaining.
-         */
-        public Builder withEnable(Boolean enable) {
-            this.enable = enable;
-
-            return this;
-        }
-
-        /**
-         * @param timeout New value of soft timeout.
-         * @return This instance for chaining.
-         */
-        public Builder withSoftBaselineTimeout(Long timeout) {
-            this.timeout = timeout;
-
-            return this;
-        }
-
-        /**
-         * @param ver Requested topology version.
-         * @return This instance for chaining.
-         */
-        public Builder withTopVer(long ver) {
-            this.ver = ver;
-
-            return this;
-        }
-
-        /**
-         * @param ids List of consistent ids for operation.
-         * @return This instance for chaining.
-         */
-        public Builder withConsistentIds(List<String> ids) {
-            this.ids = ids;
-
-            return this;
-        }
-
-        /**
-         * @return {@link BaselineArguments}.
-         */
-        public BaselineArguments build() {
-            return new BaselineArguments(cmd, enable, timeout, ver, ids);
-        }
-    }
-}
diff --git a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/baseline/BaselineSubcommands.java b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/baseline/BaselineSubcommands.java
deleted file mode 100644
index 0426237aeb1..00000000000
--- a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/baseline/BaselineSubcommands.java
+++ /dev/null
@@ -1,116 +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.ignite.internal.commandline.baseline;
-
-import org.apache.ignite.internal.visor.baseline.VisorBaselineOperation;
-import org.jetbrains.annotations.Nullable;
-
-/**
- * Set of baseline commands.
- */
-public enum BaselineSubcommands {
-    /**
-     * Add nodes to baseline.
-     */
-    ADD("add", VisorBaselineOperation.ADD),
-
-    /**
-     * Remove nodes from baseline.
-     */
-    REMOVE("remove", VisorBaselineOperation.REMOVE),
-
-    /**
-     * Collect information about baseline.
-     */
-    COLLECT("collect", VisorBaselineOperation.COLLECT),
-
-    /**
-     * Set new baseline.
-     */
-    SET("set", VisorBaselineOperation.SET),
-
-    /**
-     * Check current topology version.
-     */
-    VERSION("version", VisorBaselineOperation.VERSION),
-
-    /**
-     * Baseline auto-adjust configuration.
-     */
-    AUTO_ADJUST("auto_adjust", VisorBaselineOperation.AUTOADJUST);
-
-    /** Enumerated values. */
-    private static final BaselineSubcommands[] VALS = values();
-
-    /** Name. */
-    private final String name;
-
-    /** Corresponding visor baseline operation. */
-    private final VisorBaselineOperation visorBaselineOperation;
-
-    /**
-     * @param name Name.
-     * @param operation
-     */
-    BaselineSubcommands(String name, VisorBaselineOperation operation) {
-        this.name = name;
-        visorBaselineOperation = operation;
-    }
-
-    /**
-     * @param text Command text.
-     * @return Command for the text.
-     */
-    public static BaselineSubcommands of(String text) {
-        for (BaselineSubcommands cmd : BaselineSubcommands.values()) {
-            if (cmd.text().equalsIgnoreCase(text))
-                return cmd;
-        }
-
-        return null;
-    }
-
-    /**
-     * @return Name.
-     */
-    public String text() {
-        return name;
-    }
-
-    /**
-     * @return {@link VisorBaselineOperation} which is associated with baseline subcommand.
-     */
-    public VisorBaselineOperation visorBaselineOperation() {
-        return visorBaselineOperation;
-    }
-
-    /**
-     * Efficiently gets enumerated value from its ordinal.
-     *
-     * @param ord Ordinal value.
-     * @return Enumerated value or {@code null} if ordinal out of range.
-     */
-    @Nullable public static BaselineSubcommands fromOrdinal(int ord) {
-        return ord >= 0 && ord < VALS.length ? VALS[ord] : null;
-    }
-
-    /** {@inheritDoc} */
-    @Override public String toString() {
-        return name;
-    }
-}
diff --git a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/cache/CacheClear.java b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/cache/CacheClear.java
deleted file mode 100644
index 45fa20647c0..00000000000
--- a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/cache/CacheClear.java
+++ /dev/null
@@ -1,117 +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.ignite.internal.commandline.cache;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.stream.Collectors;
-import org.apache.ignite.IgniteLogger;
-import org.apache.ignite.internal.client.GridClient;
-import org.apache.ignite.internal.client.GridClientConfiguration;
-import org.apache.ignite.internal.commandline.AbstractCommand;
-import org.apache.ignite.internal.commandline.Command;
-import org.apache.ignite.internal.commandline.CommandArgIterator;
-import org.apache.ignite.internal.commandline.TaskExecutor;
-import org.apache.ignite.internal.processors.cache.ClearCachesTask;
-import org.apache.ignite.internal.processors.cache.ClearCachesTaskArg;
-import org.apache.ignite.internal.processors.cache.ClearCachesTaskResult;
-import org.apache.ignite.internal.util.typedef.F;
-import org.apache.ignite.internal.util.typedef.internal.U;
-
-import static org.apache.ignite.internal.commandline.cache.CacheSubcommands.CLEAR;
-
-/** Command that clears specified caches. */
-public class CacheClear extends AbstractCommand<ClearCachesTaskArg> {
-    /** Message that contains cleared caches. */
-    public static final String CLEAR_MSG = "The following caches have been cleared: %s";
-
-    /** Message that contains not-cleared caches (they don't exist). */
-    public static final String SKIP_CLEAR_MSG = "The following caches don't exist: %s";
-
-    /** Confirmation message format. */
-    public static final String CONFIRM_MSG = "Warning! The command will clear all data from %d caches: %s.\n" +
-        "If you continue, it will be impossible to recover cleared data.";
-
-    /** Comma-separated list of cache names. */
-    public static final String CACHES = "--caches";
-
-    /** Command parsed arguments. */
-    private ClearCachesTaskArg arg;
-
-    /** {@inheritDoc} */
-    @Override public Object execute(GridClientConfiguration clientCfg, IgniteLogger log) throws Exception {
-        try (GridClient client = Command.startClient(clientCfg)) {
-            ClearCachesTaskResult res = TaskExecutor.executeTask(client, ClearCachesTask.class, arg(), clientCfg);
-
-            if (!F.isEmpty(res.clearedCaches()))
-                U.log(log, String.format(CLEAR_MSG, String.join(", ", res.clearedCaches())));
-
-            if (!F.isEmpty(res.nonExistentCaches()))
-                U.warn(log, String.format(SKIP_CLEAR_MSG, String.join(", ", res.nonExistentCaches())));
-        }
-
-        return null;
-    }
-
-    /** {@inheritDoc} */
-    @Override public String confirmationPrompt() {
-        return String.format(CONFIRM_MSG, arg.caches().size(), String.join(", ", arg.caches()));
-    }
-
-    /** {@inheritDoc} */
-    @Override public ClearCachesTaskArg arg() {
-        return arg;
-    }
-
-    /** {@inheritDoc} */
-    @Override public void printUsage(IgniteLogger logger) {
-        usageCache(
-            logger,
-            CacheSubcommands.CLEAR,
-            "Clear specified caches.",
-            F.asMap(CACHES, "specifies a comma-separated list of cache names to be cleared."));
-    }
-
-    /** {@inheritDoc} */
-    @Override public void parseArguments(CommandArgIterator argIter) {
-        String cmdArg = argIter.nextArg("Command arguments are expected.");
-
-        if (cmdArg == null)
-            throw new IllegalArgumentException("Unknown argument: " + cmdArg);
-
-        if (CACHES.equals(cmdArg)) {
-            String cacheNamesArg = argIter.nextArg("Expected a comma-separated cache names.");
-
-            List<String> caches = Arrays.stream(cacheNamesArg.split(",")).collect(Collectors.toList());
-
-            arg = new ClearCachesTaskArg(caches);
-        }
-        else
-            throw new IllegalArgumentException("Unknown argument: " + cmdArg);
-
-        if (argIter.hasNextSubArg()) {
-            throw new IllegalArgumentException(
-                "Invalid argument \"" + argIter.peekNextArg() + "\", no more arguments are expected.");
-        }
-    }
-
-    /** {@inheritDoc} */
-    @Override public String name() {
-        return CLEAR.text().toUpperCase();
-    }
-}
diff --git a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/cache/CacheCommands.java b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/cache/CacheCommands.java
deleted file mode 100644
index f94b9fc2cdd..00000000000
--- a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/cache/CacheCommands.java
+++ /dev/null
@@ -1,148 +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.ignite.internal.commandline.cache;
-
-import java.util.Arrays;
-import org.apache.ignite.IgniteLogger;
-import org.apache.ignite.internal.client.GridClientConfiguration;
-import org.apache.ignite.internal.commandline.AbstractCommand;
-import org.apache.ignite.internal.commandline.Command;
-import org.apache.ignite.internal.commandline.CommandArgIterator;
-import org.apache.ignite.internal.commandline.CommandLogger;
-
-import static org.apache.ignite.internal.commandline.CommandHandler.UTILITY_NAME;
-import static org.apache.ignite.internal.commandline.CommandList.CACHE;
-import static org.apache.ignite.internal.commandline.CommandLogger.DOUBLE_INDENT;
-import static org.apache.ignite.internal.commandline.CommandLogger.INDENT;
-import static org.apache.ignite.internal.commandline.CommandLogger.optional;
-import static org.apache.ignite.internal.commandline.CommonArgParser.getCommonOptions;
-import static org.apache.ignite.internal.commandline.cache.CacheSubcommands.CONTENTION;
-import static org.apache.ignite.internal.commandline.cache.CacheSubcommands.FIND_AND_DELETE_GARBAGE;
-import static org.apache.ignite.internal.commandline.cache.CacheSubcommands.HELP;
-import static org.apache.ignite.internal.commandline.cache.CacheSubcommands.LIST;
-import static org.apache.ignite.internal.commandline.cache.CacheSubcommands.VALIDATE_INDEXES;
-
-/**
- * High-level "cache" command implementation.
- */
-public class CacheCommands extends AbstractCommand<CacheSubcommands> {
-    /** Empty group name. */
-    public static final String EMPTY_GROUP_NAME = "no_group";
-
-    /** */
-    protected static final String NODE_ID = "nodeId";
-
-    /** */
-    protected static final String OP_NODE_ID = optional(NODE_ID);
-
-    /** */
-    private CacheSubcommands subcommand;
-
-    /** {@inheritDoc} */
-    @Override public void printUsage(IgniteLogger logger) {
-        logger.info("");
-        logger.info(INDENT + "View caches information in a cluster. For more details type:");
-        logger.info(DOUBLE_INDENT + CommandLogger.join(" ", UTILITY_NAME, CACHE, HELP));
-    }
-
-    /** {@inheritDoc} */
-    @Override public Object execute(GridClientConfiguration clientCfg, IgniteLogger logger) throws Exception {
-        if (subcommand == CacheSubcommands.HELP) {
-            printCacheHelp(logger);
-
-            return null;
-        }
-
-        Command command = subcommand.subcommand();
-
-        if (command == null)
-            throw new IllegalStateException("Unknown command " + subcommand);
-
-        return command.execute(clientCfg, logger, verbose);
-    }
-
-    /** {@inheritDoc} */
-    @Override public void parseArguments(CommandArgIterator argIter) {
-        if (!argIter.hasNextSubArg()) {
-            throw new IllegalArgumentException("Arguments are expected for --cache subcommand, " +
-                "run '--cache help' for more info.");
-        }
-
-        String str = argIter.nextArg("").toLowerCase();
-
-        CacheSubcommands cmd = CacheSubcommands.of(str);
-
-        if (cmd == null)
-            cmd = CacheSubcommands.HELP;
-
-        if (cmd != HELP)
-            cmd.subcommand().parseArguments(argIter);
-
-        if (argIter.hasNextSubArg())
-            throw new IllegalArgumentException("Unexpected argument of --cache subcommand: " + argIter.peekNextArg());
-
-        subcommand = cmd;
-    }
-
-    /** */
-    private void printCacheHelp(IgniteLogger logger) {
-        logger.info(INDENT + "The '" + CACHE + " subcommand' is used to get information about and perform actions" +
-            " with caches. The command has the following syntax:");
-        logger.info("");
-        logger.info(INDENT + CommandLogger.join(" ", UTILITY_NAME, CommandLogger.join(" ", getCommonOptions())) + " " +
-            CACHE + " [subcommand] <subcommand_parameters>");
-        logger.info("");
-        logger.info(INDENT + "The subcommands that take " + OP_NODE_ID + " as an argument ('" + LIST + "', '"
-            + FIND_AND_DELETE_GARBAGE + "', '" + CONTENTION + "' and '" + VALIDATE_INDEXES +
-            "') will be executed on the given node or on all server nodes" +
-            " if the option is not specified. Other commands will run on a random server node.");
-        logger.info("");
-        logger.info("");
-        logger.info(INDENT + "Subcommands:");
-
-        Arrays.stream(CacheSubcommands.values()).forEach(c -> {
-            if (c.subcommand() != null) c.subcommand().printUsage(logger);
-        });
-
-        logger.info("");
-    }
-
-    /** {@inheritDoc} */
-    @Override public void prepareConfirmation(GridClientConfiguration clientCfg) throws Exception {
-        if (subcommand != null && subcommand.subcommand() != null)
-            subcommand.subcommand().prepareConfirmation(clientCfg);
-    }
-
-    /** {@inheritDoc} */
-    @Override public String confirmationPrompt() {
-        if (subcommand != null && subcommand.subcommand() != null)
-            return subcommand.subcommand().confirmationPrompt();
-
-        return null;
-    }
-
-    /** {@inheritDoc} */
-    @Override public CacheSubcommands arg() {
-        return subcommand;
-    }
-
-    /** {@inheritDoc} */
-    @Override public String name() {
-        return CACHE.toCommandName();
-    }
-}
diff --git a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/cache/CacheContention.java b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/cache/CacheContention.java
deleted file mode 100644
index ec260adbb89..00000000000
--- a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/cache/CacheContention.java
+++ /dev/null
@@ -1,146 +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.ignite.internal.commandline.cache;
-
-import java.util.UUID;
-import org.apache.ignite.IgniteLogger;
-import org.apache.ignite.internal.client.GridClient;
-import org.apache.ignite.internal.client.GridClientConfiguration;
-import org.apache.ignite.internal.commandline.AbstractCommand;
-import org.apache.ignite.internal.commandline.Command;
-import org.apache.ignite.internal.commandline.CommandArgIterator;
-import org.apache.ignite.internal.commandline.CommandLogger;
-import org.apache.ignite.internal.processors.cache.verify.ContentionInfo;
-import org.apache.ignite.internal.visor.verify.VisorContentionTask;
-import org.apache.ignite.internal.visor.verify.VisorContentionTaskArg;
-import org.apache.ignite.internal.visor.verify.VisorContentionTaskResult;
-
-import static org.apache.ignite.internal.commandline.CommandLogger.optional;
-import static org.apache.ignite.internal.commandline.TaskExecutor.BROADCAST_UUID;
-import static org.apache.ignite.internal.commandline.TaskExecutor.executeTaskByNameOnNode;
-import static org.apache.ignite.internal.commandline.cache.CacheCommands.OP_NODE_ID;
-import static org.apache.ignite.internal.commandline.cache.CacheSubcommands.CONTENTION;
-
-/**
- * Cache contention detection subcommand.
- */
-public class CacheContention extends AbstractCommand<CacheContention.Arguments> {
-    /** {@inheritDoc} */
-    @Override public void printUsage(IgniteLogger logger) {
-        String description = "Show the keys that are point of contention for multiple transactions.";
-
-        usageCache(logger, CONTENTION, description, null, "minQueueSize",
-            OP_NODE_ID, optional("maxPrint"));
-    }
-
-    /**
-     * Container for command arguments.
-     */
-    public class Arguments {
-        /** Node id. */
-        private UUID nodeId;
-
-        /** Min queue size. */
-        private int minQueueSize;
-
-        /** Max print. */
-        private int maxPrint;
-
-        /**
-         *
-         */
-        public Arguments(UUID nodeId, int minQueueSize, int maxPrint) {
-            this.nodeId = nodeId;
-            this.minQueueSize = minQueueSize;
-            this.maxPrint = maxPrint;
-        }
-
-        /**
-         * @return Node id.
-         */
-        public UUID nodeId() {
-            return nodeId;
-        }
-
-        /**
-         * @return Min queue size.
-         */
-        public int minQueueSize() {
-            return minQueueSize;
-        }
-
-        /**
-         * @return Max print.
-         */
-        public int maxPrint() {
-            return maxPrint;
-        }
-    }
-
-    /**
-     * Command parsed arguments.
-     */
-    private Arguments args;
-
-    /** {@inheritDoc} */
-    @Override public Arguments arg() {
-        return args;
-    }
-
-    /** {@inheritDoc} */
-    @Override public Object execute(GridClientConfiguration clientCfg, IgniteLogger logger) throws Exception {
-        VisorContentionTaskArg taskArg = new VisorContentionTaskArg(args.minQueueSize(), args.maxPrint());
-
-        UUID nodeId = args.nodeId() == null ? BROADCAST_UUID : args.nodeId();
-
-        VisorContentionTaskResult res;
-
-        try (GridClient client = Command.startClient(clientCfg);) {
-            res = executeTaskByNameOnNode(client, VisorContentionTask.class.getName(), taskArg, nodeId, clientCfg);
-        }
-
-        CommandLogger.printErrors(res.exceptions(), "Contention check failed on nodes:", logger);
-
-        for (ContentionInfo info : res.getInfos())
-            info.print();
-
-        return res;
-    }
-
-    /** {@inheritDoc} */
-    @Override public void parseArguments(CommandArgIterator argIter) {
-        int minQueueSize = Integer.parseInt(argIter.nextArg("Min queue size expected"));
-
-        UUID nodeId = null;
-
-        if (argIter.hasNextSubArg())
-            nodeId = UUID.fromString(argIter.nextArg(""));
-
-        int maxPrint = 10;
-
-        if (argIter.hasNextSubArg())
-            maxPrint = Integer.parseInt(argIter.nextArg(""));
-
-        args = new Arguments(nodeId, minQueueSize, maxPrint);
-    }
-
-    /** {@inheritDoc} */
-    @Override public String name() {
-        return CONTENTION.text().toUpperCase();
-    }
-}
diff --git a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/cache/CacheCreate.java b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/cache/CacheCreate.java
deleted file mode 100644
index a253de81e0d..00000000000
--- a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/cache/CacheCreate.java
+++ /dev/null
@@ -1,124 +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.ignite.internal.commandline.cache;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.Set;
-import org.apache.ignite.IgniteException;
-import org.apache.ignite.IgniteLogger;
-import org.apache.ignite.configuration.CacheConfiguration;
-import org.apache.ignite.internal.client.GridClient;
-import org.apache.ignite.internal.client.GridClientConfiguration;
-import org.apache.ignite.internal.commandline.AbstractCommand;
-import org.apache.ignite.internal.commandline.Command;
-import org.apache.ignite.internal.commandline.CommandArgIterator;
-import org.apache.ignite.internal.commandline.TaskExecutor;
-import org.apache.ignite.internal.util.GridStringBuilder;
-import org.apache.ignite.internal.util.typedef.F;
-import org.apache.ignite.internal.util.typedef.internal.U;
-import org.apache.ignite.internal.visor.cache.VisorCacheCreateTask;
-
-import static org.apache.ignite.internal.IgniteComponentType.SPRING;
-
-/**
- * Command to create caches from Spring XML configuration.
- */
-public class CacheCreate extends AbstractCommand<String> {
-    /** */
-    public static final String SPRING_XML_CONFIG = "--springXmlConfig";
-
-    /** */
-    private String springXmlCfgPath;
-
-    /** {@inheritDoc} */
-    @Override public Object execute(GridClientConfiguration clientCfg, IgniteLogger log) throws Exception {
-        if (!new File(springXmlCfgPath).exists()) {
-            throw new IgniteException("Failed to create caches. Spring XML configuration file not found " +
-                "[file=" + springXmlCfgPath + ']');
-        }
-
-        String springXmlCfg;
-
-        try {
-            springXmlCfg = U.readFileToString(springXmlCfgPath, "UTF-8");
-        }
-        catch (IOException e) {
-            throw new IgniteException("Failed to create caches. Failed to read Spring XML configuration file " +
-                "[file=" + springXmlCfgPath + ']', e);
-        }
-
-        try (GridClient client = Command.startClient(clientCfg)) {
-            Set<String> caches = TaskExecutor.executeTask(client, VisorCacheCreateTask.class, springXmlCfg, clientCfg);
-
-            GridStringBuilder s = new GridStringBuilder("Caches created successfully:").nl();
-
-            for (String cache : caches)
-                s.a(cache).nl();
-
-            s.nl().a("Total count: " + caches.size());
-
-            log.info(s.toString());
-
-            return caches;
-        }
-    }
-
-    /** {@inheritDoc} */
-    @Override public void parseArguments(CommandArgIterator argIter) {
-        springXmlCfgPath = null;
-
-        while (argIter.hasNextSubArg()) {
-            String opt = argIter.nextArg("Failed to read command argument.");
-
-            if (SPRING_XML_CONFIG.equalsIgnoreCase(opt)) {
-                if (springXmlCfgPath != null)
-                    throw new IllegalArgumentException(SPRING_XML_CONFIG + " argument specified twice.");
-
-                if (!argIter.hasNextSubArg())
-                    throw new IllegalArgumentException("Expected path to the Spring XML configuration.");
-
-                springXmlCfgPath = argIter.nextArg("Expected path to the Spring XML configuration.");
-            }
-        }
-
-        if (F.isEmpty(springXmlCfgPath))
-            throw new IllegalArgumentException(SPRING_XML_CONFIG + " must be specified.");
-    }
-
-    /** {@inheritDoc} */
-    @Override public String arg() {
-        return springXmlCfgPath;
-    }
-
-    /** {@inheritDoc} */
-    @Override public void printUsage(IgniteLogger log) {
-        String springXmlPathArgDesc = SPRING_XML_CONFIG + " springXmlConfigPath";
-
-        usageCache(log, CacheSubcommands.CREATE, "Create caches from Spring XML configuration. Note that the '" +
-                SPRING.module() + "' module should be enabled.",
-            F.asMap(springXmlPathArgDesc, "Path to the Spring XML configuration that contains '" +
-                CacheConfiguration.class.getName() + "' beans to create caches from."),
-            springXmlPathArgDesc);
-    }
-
-    /** {@inheritDoc} */
-    @Override public String name() {
-        return CacheSubcommands.CREATE.name().toUpperCase();
-    }
-}
diff --git a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/cache/CacheDestroy.java b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/cache/CacheDestroy.java
deleted file mode 100644
index 44a24a49760..00000000000
--- a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/cache/CacheDestroy.java
+++ /dev/null
@@ -1,162 +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.ignite.internal.commandline.cache;
-
-import java.util.ArrayList;
-import java.util.Set;
-import java.util.TreeSet;
-import org.apache.ignite.IgniteLogger;
-import org.apache.ignite.internal.client.GridClient;
-import org.apache.ignite.internal.client.GridClientConfiguration;
-import org.apache.ignite.internal.client.GridClientNode;
-import org.apache.ignite.internal.commandline.AbstractCommand;
-import org.apache.ignite.internal.commandline.Command;
-import org.apache.ignite.internal.commandline.CommandArgIterator;
-import org.apache.ignite.internal.commandline.TaskExecutor;
-import org.apache.ignite.internal.util.typedef.F;
-import org.apache.ignite.internal.util.typedef.internal.S;
-import org.apache.ignite.internal.visor.cache.VisorCacheStopTask;
-import org.apache.ignite.internal.visor.cache.VisorCacheStopTaskArg;
-
-import static org.apache.ignite.internal.commandline.CommandLogger.or;
-import static org.apache.ignite.internal.commandline.cache.CacheSubcommands.DESTROY;
-
-/**
- * Cache destroy command.
- */
-public class CacheDestroy extends AbstractCommand<VisorCacheStopTaskArg> {
-    /** Command argument to destroy all user-created caches. */
-    public static final String DESTROY_ALL_ARG = "--destroy-all-caches";
-
-    /** Command argument to specify a comma-separated list of cache names to be destroyed. */
-    public static final String CACHE_NAMES_ARG = "--caches";
-
-    /** Confirmation message format. */
-    public static final String CONFIRM_MSG = "Warning! The command will destroy %d caches: %s.\n" +
-        "If you continue, the cache data will be impossible to recover.";
-
-    /** No user-created caches exists message. */
-    public static final String NOOP_MSG = "No user-created caches exist.";
-
-    /** Result message. */
-    public static final String RESULT_MSG = "The following caches have been stopped: %s.";
-
-    /** Flag to destroy all user-created caches. */
-    private boolean destroyAll;
-
-    /** Caches to destroy. */
-    private Set<String> cacheNames;
-
-    /** {@inheritDoc} */
-    @Override public VisorCacheStopTaskArg arg() {
-        return new VisorCacheStopTaskArg(new ArrayList<>(cacheNames));
-    }
-
-    /** {@inheritDoc} */
-    @Override public void printUsage(IgniteLogger log) {
-        String cacheNamesArgFull = CACHE_NAMES_ARG + " cache1,...,cacheN";
-
-        usageCache(
-            log,
-            DESTROY,
-            "Permanently destroy specified caches.",
-            F.asMap(cacheNamesArgFull, "specifies a comma-separated list of cache names to be destroyed.",
-                DESTROY_ALL_ARG, "permanently destroy all user-created caches."),
-            or(cacheNamesArgFull, DESTROY_ALL_ARG)
-        );
-    }
-
-    /** {@inheritDoc} */
-    @Override public void parseArguments(CommandArgIterator argIter) {
-        cacheNames = null;
-        destroyAll = false;
-
-        String requiredArgsMsg = "One of \"" + CACHE_NAMES_ARG + "\" or \"" + DESTROY_ALL_ARG + "\" is expected.";
-
-        String cmdArg = argIter.nextArg(requiredArgsMsg);
-
-        if (DESTROY_ALL_ARG.equals(cmdArg))
-            destroyAll = true;
-        else if (CACHE_NAMES_ARG.equals(cmdArg))
-            cacheNames = new TreeSet<>(argIter.nextStringSet("cache names"));
-        else
-            throw new IllegalArgumentException("Invalid argument \"" + cmdArg + "\". " + requiredArgsMsg);
-
-        if (argIter.hasNextSubArg()) {
-            throw new IllegalArgumentException(
-                "Invalid argument \"" + argIter.peekNextArg() + "\", no more arguments is expected.");
-        }
-    }
-
-    /** {@inheritDoc} */
-    @Override public void prepareConfirmation(GridClientConfiguration clientCfg) throws Exception {
-        if (destroyAll)
-            cacheNames = collectClusterCaches(clientCfg);
-    }
-
-    /** {@inheritDoc} */
-    @Override public String confirmationPrompt() {
-        if (F.isEmpty(cacheNames))
-            return null;
-
-        return String.format(CONFIRM_MSG, cacheNames.size(), S.joinToString(cacheNames, ", ", "..", 80, 0));
-    }
-
-    /** {@inheritDoc} */
-    @Override public Object execute(GridClientConfiguration clientCfg, IgniteLogger log) throws Exception {
-        if (destroyAll && cacheNames == null)
-            cacheNames = collectClusterCaches(clientCfg);
-
-        if (cacheNames.isEmpty()) {
-            assert destroyAll;
-
-            log.info(NOOP_MSG);
-
-            return null;
-        }
-
-        try (GridClient client = Command.startClient(clientCfg)) {
-            TaskExecutor.executeTask(client, VisorCacheStopTask.class, arg(), clientCfg);
-        }
-
-        log.info(String.format(RESULT_MSG, F.concat(cacheNames, ", ")));
-
-        return null;
-    }
-
-    /** {@inheritDoc} */
-    @Override public String name() {
-        return DESTROY.text().toUpperCase();
-    }
-
-    /**
-     * @param clientCfg Client configuration.
-     * @return Names of user-created caches that exist in the cluster.
-     * @throws Exception If failed.
-     */
-    private Set<String> collectClusterCaches(GridClientConfiguration clientCfg) throws Exception {
-        try (GridClient client = Command.startClient(clientCfg)) {
-            Set<String> caches = new TreeSet<>();
-
-            for (GridClientNode node : client.compute().nodes(GridClientNode::connectable))
-                caches.addAll(node.caches().keySet());
-
-            return caches;
-        }
-    }
-}
diff --git a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/cache/CacheDistribution.java b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/cache/CacheDistribution.java
deleted file mode 100644
index df401085eb2..00000000000
--- a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/cache/CacheDistribution.java
+++ /dev/null
@@ -1,169 +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.ignite.internal.commandline.cache;
-
-import java.util.HashSet;
-import java.util.Set;
-import java.util.UUID;
-import org.apache.ignite.IgniteLogger;
-import org.apache.ignite.internal.client.GridClient;
-import org.apache.ignite.internal.client.GridClientConfiguration;
-import org.apache.ignite.internal.commandline.AbstractCommand;
-import org.apache.ignite.internal.commandline.Command;
-import org.apache.ignite.internal.commandline.CommandArgIterator;
-import org.apache.ignite.internal.commandline.CommandHandler;
-import org.apache.ignite.internal.commandline.CommandLogger;
-import org.apache.ignite.internal.commandline.argument.CommandArgUtils;
-import org.apache.ignite.internal.commandline.cache.argument.DistributionCommandArg;
-import org.apache.ignite.internal.commandline.cache.distribution.CacheDistributionTask;
-import org.apache.ignite.internal.commandline.cache.distribution.CacheDistributionTaskArg;
-import org.apache.ignite.internal.commandline.cache.distribution.CacheDistributionTaskResult;
-
-import static org.apache.ignite.internal.commandline.CommandHandler.NULL;
-import static org.apache.ignite.internal.commandline.CommandLogger.optional;
-import static org.apache.ignite.internal.commandline.CommandLogger.or;
-import static org.apache.ignite.internal.commandline.TaskExecutor.BROADCAST_UUID;
-import static org.apache.ignite.internal.commandline.TaskExecutor.executeTaskByNameOnNode;
-import static org.apache.ignite.internal.commandline.cache.CacheCommands.NODE_ID;
-import static org.apache.ignite.internal.commandline.cache.CacheSubcommands.DISTRIBUTION;
-import static org.apache.ignite.internal.commandline.cache.argument.DistributionCommandArg.USER_ATTRIBUTES;
-
-/**
- * Would collect and print info about how data is spread between nodes and partitions.
- */
-public class CacheDistribution extends AbstractCommand<CacheDistribution.Arguments> {
-    /** {@inheritDoc} */
-    @Override public void printUsage(IgniteLogger logger) {
-        String CACHES = "cacheName1,...,cacheNameN";
-        String description = "Prints the information about partition distribution.";
-
-        usageCache(logger, DISTRIBUTION, description, null,
-            or(NODE_ID, CommandHandler.NULL), optional(CACHES), optional(USER_ATTRIBUTES, "attrName1,...,attrNameN"));
-    }
-
-    /**
-     * Container for command arguments.
-     */
-    public class Arguments {
-        /** Caches. */
-        private Set<String> caches;
-
-        /** Node id. */
-        private UUID nodeId;
-
-        /** Additional user attributes in result. Set of attribute names whose values will be searched in ClusterNode.attributes(). */
-        private Set<String> userAttributes;
-
-        /**
-         *
-         */
-        public Arguments(Set<String> caches, UUID nodeId, Set<String> userAttributes) {
-            this.caches = caches;
-            this.nodeId = nodeId;
-            this.userAttributes = userAttributes;
-        }
-
-        /**
-         * @return Caches.
-         */
-        public Set<String> caches() {
-            return caches;
-        }
-
-        /**
-         * @return Node id.
-         */
-        public UUID nodeId() {
-            return nodeId;
-        }
-
-        /**
-         * @return Additional user attributes in result. Set of attribute names whose values will be searched in ClusterNode.attributes().
-         */
-        public Set<String> getUserAttributes() {
-            return userAttributes;
-        }
-    }
-
-    /** Command parsed arguments */
-    private Arguments args;
-
-    /** {@inheritDoc} */
-    @Override public Arguments arg() {
-        return args;
-    }
-
-    /** {@inheritDoc} */
-    @Override public Object execute(GridClientConfiguration clientCfg, IgniteLogger logger) throws Exception {
-        CacheDistributionTaskArg taskArg = new CacheDistributionTaskArg(args.caches(), args.getUserAttributes());
-
-        UUID nodeId = args.nodeId() == null ? BROADCAST_UUID : args.nodeId();
-
-        CacheDistributionTaskResult res;
-
-        try (GridClient client = Command.startClient(clientCfg)) {
-            res = executeTaskByNameOnNode(client, CacheDistributionTask.class.getName(), taskArg, nodeId, clientCfg);
-        }
-
-        CommandLogger.printErrors(res.exceptions(), "Cache distrubution task failed on nodes:", logger);
-
-        res.print(System.out);
-
-        return res;
-    }
-
-    /** {@inheritDoc} */
-    @Override public void parseArguments(CommandArgIterator argIter) {
-        UUID nodeId = null;
-        Set<String> caches = null;
-        Set<String> userAttributes = null;
-
-        String nodeIdStr = argIter.nextArg("Node id expected or null");
-
-        if (!NULL.equals(nodeIdStr))
-            nodeId = UUID.fromString(nodeIdStr);
-
-        while (argIter.hasNextSubArg()) {
-            String nextArg = argIter.nextArg("");
-
-            DistributionCommandArg arg = CommandArgUtils.of(nextArg, DistributionCommandArg.class);
-
-            if (arg == USER_ATTRIBUTES) {
-                nextArg = argIter.nextArg("User attributes are expected to be separated by commas");
-
-                userAttributes = new HashSet<>();
-
-                for (String userAttribute : nextArg.split(","))
-                    userAttributes.add(userAttribute.trim());
-
-                nextArg = (argIter.hasNextSubArg()) ? argIter.nextArg("") : null;
-
-            }
-
-            if (nextArg != null)
-                caches = argIter.parseStringSet(nextArg);
-        }
-
-        args = new Arguments(caches, nodeId, userAttributes);
-    }
-
-    /** {@inheritDoc} */
-    @Override public String name() {
-        return DISTRIBUTION.text().toUpperCase();
-    }
-}
diff --git a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/cache/CacheIndexesForceRebuild.java b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/cache/CacheIndexesForceRebuild.java
deleted file mode 100644
index 8474c8e0822..00000000000
--- a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/cache/CacheIndexesForceRebuild.java
+++ /dev/null
@@ -1,263 +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.ignite.internal.commandline.cache;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Map;
-import java.util.Set;
-import java.util.UUID;
-import org.apache.ignite.IgniteLogger;
-import org.apache.ignite.internal.client.GridClient;
-import org.apache.ignite.internal.client.GridClientConfiguration;
-import org.apache.ignite.internal.commandline.AbstractCommand;
-import org.apache.ignite.internal.commandline.Command;
-import org.apache.ignite.internal.commandline.CommandArgIterator;
-import org.apache.ignite.internal.commandline.TaskExecutor;
-import org.apache.ignite.internal.commandline.argument.CommandArgUtils;
-import org.apache.ignite.internal.commandline.cache.argument.IndexForceRebuildCommandArg;
-import org.apache.ignite.internal.util.typedef.F;
-import org.apache.ignite.internal.util.typedef.internal.S;
-import org.apache.ignite.internal.util.typedef.internal.U;
-import org.apache.ignite.internal.visor.cache.index.IndexForceRebuildTask;
-import org.apache.ignite.internal.visor.cache.index.IndexForceRebuildTaskArg;
-import org.apache.ignite.internal.visor.cache.index.IndexForceRebuildTaskRes;
-import org.apache.ignite.internal.visor.cache.index.IndexRebuildStatusInfoContainer;
-
-import static org.apache.ignite.internal.commandline.CommandLogger.INDENT;
-import static org.apache.ignite.internal.commandline.CommandLogger.or;
-import static org.apache.ignite.internal.commandline.cache.argument.IndexForceRebuildCommandArg.CACHE_NAMES;
-import static org.apache.ignite.internal.commandline.cache.argument.IndexForceRebuildCommandArg.GROUP_NAMES;
-import static org.apache.ignite.internal.commandline.cache.argument.IndexForceRebuildCommandArg.NODE_ID;
-
-/**
- * Cache subcommand that triggers indexes force rebuild.
- */
-public class CacheIndexesForceRebuild extends AbstractCommand<CacheIndexesForceRebuild.Arguments> {
-    /** Command parsed arguments. */
-    private Arguments args;
-
-    /** {@inheritDoc} */
-    @Override public void printUsage(IgniteLogger logger) {
-        String desc = "Triggers rebuild of all indexes for specified caches or cache groups.";
-
-        Map<String, String> map = U.newLinkedHashMap(16);
-
-        map.put(NODE_ID.argName(), "Specify node for indexes rebuild.");
-        map.put(CACHE_NAMES.argName(), "Comma-separated list of cache names for which indexes should be rebuilt.");
-        map.put(GROUP_NAMES.argName(), "Comma-separated list of cache group names for which indexes should be rebuilt.");
-
-        usageCache(
-            logger,
-            CacheSubcommands.INDEX_FORCE_REBUILD,
-            desc,
-            map,
-            NODE_ID.argName() + " nodeId",
-            or("--cache-names cacheName1,...cacheNameN", "--group-names groupName1,...groupNameN")
-        );
-    }
-
-    /** {@inheritDoc} */
-    @Override public Object execute(GridClientConfiguration clientCfg, IgniteLogger logger) throws Exception {
-        IndexForceRebuildTaskRes taskRes;
-
-        IndexForceRebuildTaskArg taskArg = new IndexForceRebuildTaskArg(args.cacheGrps, args.cacheNames);
-
-        final UUID nodeId = args.nodeId;
-
-        try (GridClient client = Command.startClient(clientCfg)) {
-            taskRes = TaskExecutor.executeTaskByNameOnNode(
-                client,
-                IndexForceRebuildTask.class.getName(),
-                taskArg,
-                nodeId,
-                clientCfg
-            );
-        }
-
-        printResult(taskRes, logger);
-
-        return taskRes;
-    }
-
-    /**
-     * @param res Rebuild task result.
-     * @param logger IgniteLogger to print to.
-     */
-    private void printResult(IndexForceRebuildTaskRes res, IgniteLogger logger) {
-        if (!F.isEmpty(res.notFoundCacheNames())) {
-            String warning = args.cacheGrps == null ?
-                "WARNING: These caches were not found:" : "WARNING: These cache groups were not found:";
-
-            logger.info(warning);
-
-            res.notFoundCacheNames()
-                .stream()
-                .sorted()
-                .forEach(name -> logger.info(INDENT + name));
-
-            logger.info("");
-        }
-
-        if (!F.isEmpty(res.cachesWithRebuildInProgress())) {
-            logger.info("WARNING: These caches have indexes rebuilding in progress:");
-
-            printInfos(res.cachesWithRebuildInProgress(), logger);
-
-            logger.info("");
-        }
-
-        if (!F.isEmpty(res.cachesWithStartedRebuild())) {
-            logger.info("Indexes rebuild was started for these caches:");
-
-            printInfos(res.cachesWithStartedRebuild(), logger);
-        }
-        else
-            logger.info("WARNING: Indexes rebuild was not started for any cache. Check command input.");
-
-        logger.info("");
-    }
-
-    /** */
-    private void printInfos(Collection<IndexRebuildStatusInfoContainer> infos, IgniteLogger logger) {
-        infos.stream()
-            .sorted(IndexRebuildStatusInfoContainer.comparator())
-            .forEach(rebuildStatusInfo -> logger.info(INDENT + rebuildStatusInfo.toString()));
-    }
-
-    /** {@inheritDoc} */
-    @Override public Arguments arg() {
-        return args;
-    }
-
-    /** {@inheritDoc} */
-    @Override public String name() {
-        return CacheSubcommands.INDEX_FORCE_REBUILD.text().toUpperCase();
-    }
-
-    /**
-     * Container for command arguments.
-     */
-    public static class Arguments {
-        /** Node id. */
-        private UUID nodeId;
-
-        /** Cache group name. */
-        private Set<String> cacheGrps;
-
-        /** Cache name. */
-        private Set<String> cacheNames;
-
-        /** */
-        public Arguments(UUID nodeId, Set<String> cacheGrps, Set<String> cacheNames) {
-            this.nodeId = nodeId;
-            this.cacheGrps = cacheGrps;
-            this.cacheNames = cacheNames;
-        }
-
-        /**
-         * @return Node id.
-         */
-        public UUID nodeId() {
-            return nodeId;
-        }
-
-        /**
-         * @return Cache group to scan for, null means scanning all groups.
-         */
-        public Set<String> cacheGrps() {
-            return cacheGrps;
-        }
-
-        /**
-         * @return List of caches names.
-         */
-        public Set<String> cacheNames() {
-            return cacheNames;
-        }
-
-        /** {@inheritDoc} */
-        @Override public String toString() {
-            return S.toString(Arguments.class, this);
-        }
-    }
-
-    /** {@inheritDoc} */
-    @Override public void parseArguments(CommandArgIterator argIterator) {
-        UUID nodeId = null;
-        Set<String> cacheGrps = null;
-        Set<String> cacheNames = null;
-
-        while (argIterator.hasNextSubArg()) {
-            String nextArg = argIterator.nextArg("");
-
-            IndexForceRebuildCommandArg arg = CommandArgUtils.of(nextArg, IndexForceRebuildCommandArg.class);
-
-            if (arg == null)
-                throw new IllegalArgumentException("Unknown argument: " + nextArg);
-
-            switch (arg) {
-                case NODE_ID:
-                    if (nodeId != null)
-                        throw new IllegalArgumentException(arg.argName() + " arg specified twice.");
-
-                    nodeId = UUID.fromString(argIterator.nextArg("Failed to read node id."));
-
-                    break;
-
-                case GROUP_NAMES:
-                    if (cacheGrps != null)
-                        throw new IllegalArgumentException(arg.argName() + " arg specified twice.");
-
-                    cacheGrps = argIterator.nextStringSet("comma-separated list of cache group names.");
-
-                    if (cacheGrps.equals(Collections.emptySet()))
-                        throw new IllegalArgumentException(arg.argName() + " not specified.");
-
-                    break;
-
-                case CACHE_NAMES:
-                    if (cacheNames != null)
-                        throw new IllegalArgumentException(arg.argName() + " arg specified twice.");
-
-                    cacheNames = argIterator.nextStringSet("comma-separated list of cache names.");
-
-                    if (cacheNames.equals(Collections.emptySet()))
-                        throw new IllegalArgumentException(arg.argName() + " not specified.");
-
-                    break;
-
-                default:
-                    throw new IllegalArgumentException("Unknown argument: " + arg.argName());
-            }
-        }
-
-        args = new Arguments(nodeId, cacheGrps, cacheNames);
-
-        validateArguments();
-    }
-
-    /** */
-    private void validateArguments() {
-        if (args.nodeId == null)
-            throw new IllegalArgumentException(NODE_ID + " must be specified.");
-
-        if ((args.cacheGrps == null) == (args.cacheNames() == null))
-            throw new IllegalArgumentException("Either " + GROUP_NAMES + " or " + CACHE_NAMES + " must be specified.");
-    }
-}
diff --git a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/cache/CacheIndexesList.java b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/cache/CacheIndexesList.java
deleted file mode 100644
index 63d870cb7ca..00000000000
--- a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/cache/CacheIndexesList.java
+++ /dev/null
@@ -1,264 +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.ignite.internal.commandline.cache;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.UUID;
-import java.util.regex.Pattern;
-import java.util.regex.PatternSyntaxException;
-import org.apache.ignite.IgniteLogger;
-import org.apache.ignite.internal.client.GridClient;
-import org.apache.ignite.internal.client.GridClientConfiguration;
-import org.apache.ignite.internal.commandline.AbstractCommand;
-import org.apache.ignite.internal.commandline.Command;
-import org.apache.ignite.internal.commandline.CommandArgIterator;
-import org.apache.ignite.internal.commandline.TaskExecutor;
-import org.apache.ignite.internal.commandline.argument.CommandArgUtils;
-import org.apache.ignite.internal.commandline.cache.argument.IndexListCommandArg;
-import org.apache.ignite.internal.util.typedef.internal.S;
-import org.apache.ignite.internal.util.typedef.internal.U;
-import org.apache.ignite.internal.visor.cache.index.IndexListInfoContainer;
-import org.apache.ignite.internal.visor.cache.index.IndexListTask;
-import org.apache.ignite.internal.visor.cache.index.IndexListTaskArg;
-
-import static org.apache.ignite.internal.commandline.CommandLogger.optional;
-import static org.apache.ignite.internal.commandline.cache.argument.IndexListCommandArg.CACHE_NAME;
-import static org.apache.ignite.internal.commandline.cache.argument.IndexListCommandArg.GRP_NAME;
-import static org.apache.ignite.internal.commandline.cache.argument.IndexListCommandArg.IDX_NAME;
-import static org.apache.ignite.internal.commandline.cache.argument.IndexListCommandArg.NODE_ID;
-
-/**
- * Cache subcommand that allows to show indexes.
- */
-public class CacheIndexesList extends AbstractCommand<CacheIndexesList.Arguments> {
-    /** Command parsed arguments. */
-    private Arguments args;
-
-    /** {@inheritDoc} */
-    @Override public void printUsage(IgniteLogger logger) {
-        String desc = "List all indexes that match specified filters.";
-
-        Map<String, String> map = U.newLinkedHashMap(16);
-
-        map.put(NODE_ID.argName() + " nodeId",
-            "Specify node for job execution. If not specified explicitly, node will be chosen by grid");
-        map.put(GRP_NAME.argName() + " regExp",
-            "Regular expression allowing filtering by cache group name");
-        map.put(CACHE_NAME.argName() + " regExp",
-            "Regular expression allowing filtering by cache name");
-        map.put(IDX_NAME.argName() + " regExp",
-            "Regular expression allowing filtering by index name");
-
-        usageCache(
-            logger,
-            CacheSubcommands.INDEX_LIST,
-            desc,
-            map,
-            optional(NODE_ID + " nodeId"),
-            optional(GRP_NAME + " grpRegExp"),
-            optional(CACHE_NAME + " cacheRegExp"),
-            optional(IDX_NAME + " idxNameRegExp")
-        );
-    }
-
-    /** {@inheritDoc} */
-    @Override public Object execute(GridClientConfiguration clientCfg, IgniteLogger logger) throws Exception {
-        Set<IndexListInfoContainer> taskRes;
-
-        final UUID nodeId = args.nodeId;
-
-        IndexListTaskArg taskArg = new IndexListTaskArg(args.groupsRegEx, args.cachesRegEx, args.indexesRegEx);
-
-        try (GridClient client = Command.startClient(clientCfg)) {
-            taskRes = TaskExecutor.executeTaskByNameOnNode(client,
-                IndexListTask.class.getName(), taskArg, nodeId, clientCfg);
-        }
-
-        printIndexes(taskRes, logger);
-
-        return taskRes;
-    }
-
-    /** {@inheritDoc} */
-    @Override public Arguments arg() {
-        return args;
-    }
-
-    /** {@inheritDoc} */
-    @Override public String name() {
-        return CacheSubcommands.INDEX_LIST.text().toUpperCase();
-    }
-
-    /** {@inheritDoc} */
-    @Override public void parseArguments(CommandArgIterator argIterator) {
-        UUID nodeId = null;
-        String groupsRegEx = null;
-        String cachesRegEx = null;
-        String indexesRegEx = null;
-
-        while (argIterator.hasNextSubArg()) {
-            String nextArg = argIterator.nextArg("");
-
-            IndexListCommandArg arg = CommandArgUtils.of(nextArg, IndexListCommandArg.class);
-
-            if (arg == null)
-                throw new IllegalArgumentException("Unknown argument: " + nextArg);
-
-            switch (arg) {
-                case NODE_ID:
-                    if (nodeId != null)
-                        throw new IllegalArgumentException(arg.argName() + " arg specified twice.");
-
-                    nodeId = UUID.fromString(argIterator.nextArg("Failed to read node id."));
-
-                    break;
-
-                case GRP_NAME:
-                    groupsRegEx = argIterator.nextArg("Failed to read group name regex.");
-
-                    if (!validateRegEx(groupsRegEx))
-                        throw new IllegalArgumentException("Invalid group name regex: " + groupsRegEx);
-
-                    break;
-
-                case CACHE_NAME:
-                    cachesRegEx = argIterator.nextArg("Failed to read cache name regex.");
-
-                    if (!validateRegEx(cachesRegEx))
-                        throw new IllegalArgumentException("Invalid cache name regex: " + cachesRegEx);
-
-                    break;
-
-                case IDX_NAME:
-                    indexesRegEx = argIterator.nextArg("Failed to read index name regex.");
-
-                    if (!validateRegEx(indexesRegEx))
-                        throw new IllegalArgumentException("Invalid index name regex: " + indexesRegEx);
-
-                    break;
-
-                default:
-                    throw new IllegalArgumentException("Unknown argument: " + arg.argName());
-            }
-        }
-
-        args = new Arguments(nodeId, groupsRegEx, cachesRegEx, indexesRegEx);
-    }
-
-    /**
-     * Container for command arguments.
-     */
-    public static class Arguments {
-        /** Node id. */
-        private UUID nodeId;
-
-        /** Cache groups regex. */
-        private String groupsRegEx;
-
-        /** Cache names regex. */
-        private String cachesRegEx;
-
-        /** Indexes names regex. */
-        private String indexesRegEx;
-
-        /** */
-        public Arguments(UUID nodeId, String groupsRegEx, String cachesRegEx, String indexesRegEx) {
-            this.nodeId = nodeId;
-            this.groupsRegEx = groupsRegEx;
-            this.indexesRegEx = indexesRegEx;
-            this.cachesRegEx = cachesRegEx;
-        }
-
-        /**
-         * @return Node id.
-         */
-        public UUID nodeId() {
-            return nodeId;
-        }
-
-        /**
-         * @return Cache groups regex filter.
-         */
-        public String groups() {
-            return groupsRegEx;
-        }
-
-        /**
-         * @return Cache names regex filter.
-         */
-        public String cachesRegEx() {
-            return cachesRegEx;
-        }
-
-        /**
-         * @return Index names regex filter.
-         */
-        public String indexesRegEx() {
-            return indexesRegEx;
-        }
-
-        /** {@inheritDoc} */
-        @Override public String toString() {
-            return S.toString(Arguments.class, this);
-        }
-    }
-
-    /**
-     * Prints indexes info.
-     *
-     * @param res Set of indexes info to print.
-     * @param logger IgniteLogger to use.
-     */
-    private void printIndexes(Set<IndexListInfoContainer> res, IgniteLogger logger) {
-        List<IndexListInfoContainer> sorted = new ArrayList<>(res);
-
-        sorted.sort(IndexListInfoContainer.comparator());
-
-        String prevGrpName = "";
-
-        for (IndexListInfoContainer container : sorted) {
-            if (!prevGrpName.equals(container.groupName())) {
-                prevGrpName = container.groupName();
-
-                logger.info("");
-            }
-
-            logger.info(container.toString());
-        }
-
-        logger.info("");
-    }
-
-    /**
-     * @param regex Regex to validate
-     * @return {@code True} if {@code regex} syntax is valid. {@code False} otherwise.
-     */
-    private boolean validateRegEx(String regex) {
-        try {
-            Pattern.compile(regex);
-
-            return true;
-        }
-        catch (PatternSyntaxException e) {
-            return false;
-        }
-    }
-}
diff --git a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/cache/CacheIndexesRebuildStatus.java b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/cache/CacheIndexesRebuildStatus.java
deleted file mode 100644
index 4664e35f5d6..00000000000
--- a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/cache/CacheIndexesRebuildStatus.java
+++ /dev/null
@@ -1,172 +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.ignite.internal.commandline.cache;
-
-import java.util.Map;
-import java.util.Set;
-import java.util.UUID;
-import org.apache.ignite.IgniteLogger;
-import org.apache.ignite.internal.client.GridClient;
-import org.apache.ignite.internal.client.GridClientConfiguration;
-import org.apache.ignite.internal.commandline.AbstractCommand;
-import org.apache.ignite.internal.commandline.Command;
-import org.apache.ignite.internal.commandline.CommandArgIterator;
-import org.apache.ignite.internal.commandline.TaskExecutor;
-import org.apache.ignite.internal.commandline.argument.CommandArgUtils;
-import org.apache.ignite.internal.commandline.cache.argument.IndexListCommandArg;
-import org.apache.ignite.internal.util.typedef.internal.S;
-import org.apache.ignite.internal.util.typedef.internal.U;
-import org.apache.ignite.internal.visor.cache.index.IndexRebuildStatusInfoContainer;
-import org.apache.ignite.internal.visor.cache.index.IndexRebuildStatusTask;
-import org.apache.ignite.internal.visor.cache.index.IndexRebuildStatusTaskArg;
-
-import static org.apache.ignite.internal.commandline.CommandLogger.optional;
-import static org.apache.ignite.internal.commandline.cache.argument.IndexListCommandArg.NODE_ID;
-
-/**
- * Cache subcommand that allows to show caches that have
- */
-public class CacheIndexesRebuildStatus extends AbstractCommand<CacheIndexesRebuildStatus.Arguments> {
-    /** Command parsed arguments. */
-    private Arguments args;
-
-    /** {@inheritDoc} */
-    @Override public void printUsage(IgniteLogger logger) {
-        String desc = "List all indexes that have index rebuild in progress.";
-
-        Map<String, String> map = U.newLinkedHashMap(8);
-
-        map.put(NODE_ID.argName() + " nodeId",
-            "Specify node for job execution. If not specified explicitly, info will be gathered from all nodes");
-
-        usageCache(
-            logger,
-            CacheSubcommands.INDEX_REBUILD_STATUS,
-            desc,
-            map,
-            optional(NODE_ID + " nodeId")
-        );
-    }
-
-    /** {@inheritDoc} */
-    @Override public Object execute(GridClientConfiguration clientCfg, IgniteLogger logger) throws Exception {
-        Map<UUID, Set<IndexRebuildStatusInfoContainer>> taskRes;
-
-        final UUID nodeId = args.nodeId;
-
-        IndexRebuildStatusTaskArg taskArg = new IndexRebuildStatusTaskArg(nodeId);
-
-        try (GridClient client = Command.startClient(clientCfg)) {
-            taskRes = TaskExecutor.executeTaskByNameOnNode(client, IndexRebuildStatusTask.class.getName(), taskArg,
-                nodeId, clientCfg);
-        }
-
-        printStatus(taskRes, logger);
-
-        return taskRes;
-    }
-
-    /** {@inheritDoc} */
-    @Override public Arguments arg() {
-        return args;
-    }
-
-    /** {@inheritDoc} */
-    @Override public String name() {
-        return CacheSubcommands.INDEX_REBUILD_STATUS.text().toUpperCase();
-    }
-
-    /** {@inheritDoc} */
-    @Override public void parseArguments(CommandArgIterator argIterator) {
-        UUID nodeId = null;
-
-        while (argIterator.hasNextSubArg()) {
-            String nextArg = argIterator.nextArg("");
-
-            IndexListCommandArg arg = CommandArgUtils.of(nextArg, IndexListCommandArg.class);
-
-            if (arg == IndexListCommandArg.NODE_ID) {
-                if (nodeId != null)
-                    throw new IllegalArgumentException(arg.argName() + " arg specified twice.");
-
-                nodeId = UUID.fromString(argIterator.nextArg("Failed to read node id"));
-            }
-            else
-                throw new IllegalArgumentException("Unknown argument: " + nextArg);
-        }
-
-        args = new Arguments(nodeId);
-    }
-
-    /**
-     * Prints caches infos grouped by node id.
-     *
-     * @param res Task result.
-     * @param logger IgniteLogger to use.
-     */
-    private void printStatus(Map<UUID, Set<IndexRebuildStatusInfoContainer>> res, IgniteLogger logger) {
-        if (!res.isEmpty())
-            logger.info("Caches that have index rebuilding in progress:");
-        else {
-            logger.info("There are no caches that have index rebuilding in progress.");
-            logger.info("");
-
-            return;
-        }
-
-        for (Map.Entry<UUID, Set<IndexRebuildStatusInfoContainer>> entry: res.entrySet()) {
-            logger.info("");
-
-            entry.getValue().stream()
-                .sorted(IndexRebuildStatusInfoContainer.comparator())
-                .forEach(container -> logger.info(constructCacheOutputString(entry.getKey(), container)));
-        }
-
-        logger.info("");
-    }
-
-    /** */
-    private String constructCacheOutputString(UUID nodeId, IndexRebuildStatusInfoContainer container) {
-        return "node_id=" + nodeId + ", " + container.toString();
-    }
-
-    /**
-     * Container for command arguments.
-     */
-    public static class Arguments {
-        /** Node id. */
-        private UUID nodeId;
-
-        /** */
-        public Arguments(UUID nodeId) {
-            this.nodeId = nodeId;
-        }
-
-        /**
-         * @return Node id.
-         */
-        public UUID nodeId() {
-            return nodeId;
-        }
-
-        /** {@inheritDoc} */
-        @Override public String toString() {
-            return S.toString(CacheIndexesRebuildStatus.Arguments.class, this);
-        }
-    }
-}
diff --git a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/cache/CacheMetrics.java b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/cache/CacheMetrics.java
deleted file mode 100644
index 167cc0ed5fe..00000000000
--- a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/cache/CacheMetrics.java
+++ /dev/null
@@ -1,133 +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.ignite.internal.commandline.cache;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeSet;
-import org.apache.ignite.IgniteLogger;
-import org.apache.ignite.internal.client.GridClient;
-import org.apache.ignite.internal.client.GridClientConfiguration;
-import org.apache.ignite.internal.commandline.AbstractCommand;
-import org.apache.ignite.internal.commandline.Command;
-import org.apache.ignite.internal.commandline.CommandArgIterator;
-import org.apache.ignite.internal.commandline.TaskExecutor;
-import org.apache.ignite.internal.commandline.systemview.SystemViewCommand;
-import org.apache.ignite.internal.util.typedef.F;
-import org.apache.ignite.internal.visor.cache.metrics.CacheMetricsOperation;
-import org.apache.ignite.internal.visor.cache.metrics.VisorCacheMetricsTask;
-import org.apache.ignite.internal.visor.cache.metrics.VisorCacheMetricsTaskArg;
-import org.apache.ignite.internal.visor.cache.metrics.VisorCacheMetricsTaskResult;
-
-import static java.util.Arrays.asList;
-import static org.apache.ignite.internal.commandline.CommandLogger.optional;
-import static org.apache.ignite.internal.commandline.CommandLogger.or;
-import static org.apache.ignite.internal.commandline.cache.CacheSubcommands.METRICS;
-import static org.apache.ignite.internal.visor.cache.metrics.CacheMetricsOperation.DISABLE;
-import static org.apache.ignite.internal.visor.cache.metrics.CacheMetricsOperation.ENABLE;
-import static org.apache.ignite.internal.visor.cache.metrics.CacheMetricsOperation.STATUS;
-import static org.apache.ignite.internal.visor.systemview.VisorSystemViewTask.SimpleType.STRING;
-
-/**
- * Cache sub-command for a cache metrics collection management. It provides an ability to enable, disable or show status.
- */
-public class CacheMetrics extends AbstractCommand<VisorCacheMetricsTaskArg> {
-    /** Argument for applying metrics command operation to explicitly specified caches. */
-    public static final String CACHES_ARGUMENT = "--caches";
-
-    /** Argument for applying metrics command operation to all user caches. */
-    public static final String ALL_CACHES_ARGUMENT = "--all-caches";
-
-    /** Incorrect metrics operation message. */
-    public static final String INCORRECT_METRICS_OPERATION_MESSAGE = "Expected correct metrics command operation.";
-
-    /** Incorrect cache argument message. */
-    public static final String INCORRECT_CACHE_ARGUMENT_MESSAGE =
-        String.format("Expected one of these arguments: '%s' or '%s'. Multiple arguments are not allowed.",
-            CACHES_ARGUMENT, ALL_CACHES_ARGUMENT);
-
-    /** Expected caches list message. */
-    public static final String EXPECTED_CACHES_LIST_MESSAGE = "comma-separated list of cache names.";
-
-    /** Task argument. */
-    private VisorCacheMetricsTaskArg arg;
-
-    /** {@inheritDoc} */
-    @Override public Object execute(GridClientConfiguration clientCfg, IgniteLogger log) throws Exception {
-        try (GridClient client = Command.startClient(clientCfg)) {
-            VisorCacheMetricsTaskResult res = TaskExecutor.executeTaskByNameOnNode(client,
-                VisorCacheMetricsTask.class.getName(), arg, null, clientCfg);
-
-            List<List<?>> values = new ArrayList<>();
-
-            for (Map.Entry<String, Boolean> e : res.result().entrySet())
-                values.add(asList(e.getKey(), e.getValue() ? "enabled" : "disabled"));
-
-            SystemViewCommand.printTable(asList("Cache Name", "Metrics Status"), asList(STRING, STRING), values, log);
-
-            return null;
-        }
-    }
-
-    /** {@inheritDoc} */
-    @Override public void printUsage(IgniteLogger log) {
-        String desc = "Manages user cache metrics collection: enables, disables it or shows status.";
-
-        String cachesArgDesc = CACHES_ARGUMENT + " cache1" + optional(",...,cacheN");
-
-        Map<String, String> paramsDesc = F.asMap(
-            cachesArgDesc, "specifies a comma-separated list of cache names to which operation should be applied.",
-            ALL_CACHES_ARGUMENT, "applies operation to all user caches.");
-
-        usageCache(log, METRICS, desc, paramsDesc, or(ENABLE, DISABLE, STATUS), or(cachesArgDesc, ALL_CACHES_ARGUMENT));
-    }
-
-    /** {@inheritDoc} */
-    @Override public VisorCacheMetricsTaskArg arg() {
-        return arg;
-    }
-
-    /** {@inheritDoc} */
-    @Override public void parseArguments(CommandArgIterator argIter) {
-        CacheMetricsOperation op = CacheMetricsOperation.of(argIter.nextArg(INCORRECT_METRICS_OPERATION_MESSAGE));
-
-        if (op == null)
-            throw new IllegalArgumentException(INCORRECT_METRICS_OPERATION_MESSAGE);
-
-        Set<String> cacheNames;
-
-        String arg = argIter.nextArg(INCORRECT_CACHE_ARGUMENT_MESSAGE);
-
-        if (CACHES_ARGUMENT.equals(arg))
-            cacheNames = new TreeSet<>(argIter.nextStringSet(EXPECTED_CACHES_LIST_MESSAGE));
-        else if (ALL_CACHES_ARGUMENT.equals(arg))
-            cacheNames = Collections.emptySet();
-        else
-            throw new IllegalArgumentException(INCORRECT_CACHE_ARGUMENT_MESSAGE);
-
-        this.arg = new VisorCacheMetricsTaskArg(op, cacheNames);
-    }
-
-    /** {@inheritDoc} */
-    @Override public String name() {
-        return METRICS.text().toUpperCase();
-    }
-}
diff --git a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/cache/CacheScan.java b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/cache/CacheScan.java
deleted file mode 100644
index 76f5195a7a1..00000000000
--- a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/cache/CacheScan.java
+++ /dev/null
@@ -1,128 +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.ignite.internal.commandline.cache;
-
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Collectors;
-import org.apache.ignite.IgniteLogger;
-import org.apache.ignite.internal.client.GridClient;
-import org.apache.ignite.internal.client.GridClientConfiguration;
-import org.apache.ignite.internal.commandline.AbstractCommand;
-import org.apache.ignite.internal.commandline.Command;
-import org.apache.ignite.internal.commandline.CommandArgIterator;
-import org.apache.ignite.internal.commandline.TaskExecutor;
-import org.apache.ignite.internal.commandline.systemview.SystemViewCommand;
-import org.apache.ignite.internal.util.typedef.F;
-import org.apache.ignite.internal.visor.cache.VisorCacheScanTask;
-import org.apache.ignite.internal.visor.cache.VisorCacheScanTaskArg;
-import org.apache.ignite.internal.visor.cache.VisorCacheScanTaskResult;
-import org.apache.ignite.internal.visor.systemview.VisorSystemViewTask;
-
-import static org.apache.ignite.internal.commandline.CommandLogger.optional;
-import static org.apache.ignite.internal.commandline.cache.CacheSubcommands.SCAN;
-
-/**
- * Command to show caches on cluster.
- */
-public class CacheScan extends AbstractCommand<CacheScan.Arguments> {
-    /** Default entries limit. */
-    private static final int DFLT_LIMIT = 1_000;
-
-    /** {@inheritDoc} */
-    @Override public void printUsage(IgniteLogger log) {
-        String description = "Show cache content.";
-
-        Map<String, String> map = F.asMap("--limit", "limit count of entries to scan (" + DFLT_LIMIT + " by default)");
-
-        usageCache(log, SCAN, description, map, "cacheName", optional("--limit", "N"));
-    }
-
-    /** Command parsed arguments */
-    private Arguments args;
-
-    /** {@inheritDoc} */
-    @Override public Arguments arg() {
-        return args;
-    }
-
-    /** {@inheritDoc} */
-    @Override public Object execute(GridClientConfiguration clientCfg, IgniteLogger log) throws Exception {
-        VisorCacheScanTaskArg taskArg = new VisorCacheScanTaskArg(args.cacheName, args.limit);
-
-        VisorCacheScanTaskResult res;
-
-        try (GridClient client = Command.startClient(clientCfg)) {
-            res = TaskExecutor.executeTask(
-                client,
-                VisorCacheScanTask.class,
-                taskArg,
-                clientCfg
-            );
-
-            List<VisorSystemViewTask.SimpleType> types = res.titles().stream()
-                .map(x -> VisorSystemViewTask.SimpleType.STRING).collect(Collectors.toList());
-
-            SystemViewCommand.printTable(res.titles(), types, res.entries(), log);
-
-            if (res.entries().size() == args.limit)
-                log.info("Result limited to " + args.limit + " rows. Limit can be changed with '--limit' argument.");
-        }
-
-        return res;
-    }
-
-    /** {@inheritDoc} */
-    @Override public void parseArguments(CommandArgIterator argIter) {
-        String cacheName = argIter.nextArg("Cache name is expected");
-        int limit = DFLT_LIMIT;
-
-        while (argIter.hasNextSubArg()) {
-            String nextArg = argIter.nextArg("").toLowerCase();
-
-            if ("--limit".equals(nextArg))
-                limit = argIter.nextIntArg("limit");
-            else
-                throw new IllegalArgumentException("Unknown argument: " + nextArg);
-        }
-
-        args = new Arguments(cacheName, limit);
-    }
-
-    /** {@inheritDoc} */
-    @Override public String name() {
-        return SCAN.text().toUpperCase();
-    }
-
-    /**
-     * Container for command arguments.
-     */
-    public static class Arguments {
-        /** Cache name. */
-        private final String cacheName;
-
-        /** Rows limit. */
-        private final int limit;
-
-        /** */
-        public Arguments(String cacheName, int limit) {
-            this.cacheName = cacheName;
-            this.limit = limit;
-        }
-    }
-}
diff --git a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/cache/CacheScheduleIndexesRebuild.java b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/cache/CacheScheduleIndexesRebuild.java
deleted file mode 100644
index f60d7c8e6f1..00000000000
--- a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/cache/CacheScheduleIndexesRebuild.java
+++ /dev/null
@@ -1,334 +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.ignite.internal.commandline.cache;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.Set;
-import java.util.UUID;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import org.apache.ignite.IgniteLogger;
-import org.apache.ignite.internal.client.GridClient;
-import org.apache.ignite.internal.client.GridClientConfiguration;
-import org.apache.ignite.internal.commandline.AbstractCommand;
-import org.apache.ignite.internal.commandline.Command;
-import org.apache.ignite.internal.commandline.CommandArgIterator;
-import org.apache.ignite.internal.commandline.TaskExecutor;
-import org.apache.ignite.internal.commandline.argument.CommandArgUtils;
-import org.apache.ignite.internal.commandline.cache.argument.IndexRebuildCommandArg;
-import org.apache.ignite.internal.util.typedef.F;
-import org.apache.ignite.internal.util.typedef.internal.S;
-import org.apache.ignite.internal.visor.cache.index.ScheduleIndexRebuildTask;
-import org.apache.ignite.internal.visor.cache.index.ScheduleIndexRebuildTaskArg;
-import org.apache.ignite.internal.visor.cache.index.ScheduleIndexRebuildTaskRes;
-import org.jetbrains.annotations.Nullable;
-
-import static java.util.stream.Collectors.toSet;
-import static org.apache.ignite.internal.commandline.CommandLogger.INDENT;
-import static org.apache.ignite.internal.commandline.cache.argument.IndexRebuildCommandArg.CACHE_GROUPS_TARGET;
-import static org.apache.ignite.internal.commandline.cache.argument.IndexRebuildCommandArg.CACHE_NAMES_TARGET;
-import static org.apache.ignite.internal.commandline.cache.argument.IndexRebuildCommandArg.NODE_ID;
-
-/**
- * Cache subcommand that schedules indexes rebuild via the maintenance mode.
- */
-public class CacheScheduleIndexesRebuild extends AbstractCommand<CacheScheduleIndexesRebuild.Arguments> {
-    /** --cache-names parameter format. */
-    private static final String CACHE_NAMES_FORMAT = "cacheName[index1,...indexN],cacheName2,cacheName3[index1]";
-
-    /** --group-names parameter format. */
-    private static final String CACHE_GROUPS_FORMAT = "groupName1,groupName2,...groupNameN";
-
-    /** Command's parsed arguments. */
-    private Arguments args;
-
-    /** {@inheritDoc} */
-    @Override public void printUsage(IgniteLogger logger) {
-        String desc = "Schedules rebuild of the indexes for specified caches via the Maintenance Mode. Schedules rebuild of specified "
-            + "caches and cache-groups";
-
-        Map<String, String> map = new LinkedHashMap<>(2);
-
-        map.put(NODE_ID.argName(), "(Optional) Specify node for indexes rebuild. If not specified, schedules rebuild on all nodes.");
-
-        map.put(
-            CACHE_NAMES_TARGET.argName(),
-            "Comma-separated list of cache names with optionally specified indexes. If indexes are not specified then all indexes "
-            + "of the cache will be scheduled for the rebuild operation. Can be used simultaneously with cache group names."
-        );
-
-        map.put(CACHE_GROUPS_TARGET.argName(), "Comma-separated list of cache group names for which indexes should be scheduled for the "
-            + "rebuild. Can be used simultaneously with cache names.");
-
-        usageCache(
-            logger,
-            CacheSubcommands.INDEX_REBUILD,
-            desc,
-            map,
-            NODE_ID.argName() + " nodeId",
-            CACHE_NAMES_TARGET + " " + CACHE_NAMES_FORMAT,
-            CACHE_GROUPS_TARGET + " " + CACHE_GROUPS_FORMAT
-        );
-    }
-
-    /** {@inheritDoc} */
-    @Override public Object execute(GridClientConfiguration clientCfg, IgniteLogger logger) throws Exception {
-        ScheduleIndexRebuildTaskRes taskRes;
-
-        try (GridClient client = Command.startClient(clientCfg)) {
-            UUID nodeId = args.nodeId;
-
-            if (nodeId == null)
-                nodeId = TaskExecutor.BROADCAST_UUID;
-
-            taskRes = TaskExecutor.executeTaskByNameOnNode(
-                client,
-                ScheduleIndexRebuildTask.class.getName(),
-                new ScheduleIndexRebuildTaskArg(args.cacheToIndexes, args.cacheGroups),
-                nodeId,
-                clientCfg
-            );
-        }
-
-        printResult(taskRes, logger);
-
-        return taskRes;
-    }
-
-    /**
-     * @param taskRes Rebuild task result.
-     * @param logger IgniteLogger to print to.
-     */
-    private void printResult(ScheduleIndexRebuildTaskRes taskRes, IgniteLogger logger) {
-        taskRes.results().forEach((nodeId, res) -> {
-            printMissed(logger, "WARNING: These caches were not found:", res.notFoundCacheNames());
-            printMissed(logger, "WARNING: These cache groups were not found:", res.notFoundGroupNames());
-
-            if (!F.isEmpty(res.notFoundIndexes()) && hasAtLeastOneIndex(res.notFoundIndexes())) {
-                String warning = "WARNING: These indexes were not found:";
-
-                logger.info(warning);
-
-                printCachesAndIndexes(res.notFoundIndexes(), logger);
-            }
-
-            if (!F.isEmpty(res.cacheToIndexes()) && hasAtLeastOneIndex(res.cacheToIndexes())) {
-                logger.info("Indexes rebuild was scheduled for these caches:");
-
-                printCachesAndIndexes(res.cacheToIndexes(), logger);
-            }
-            else
-                logger.info("WARNING: Indexes rebuild was not scheduled for any cache. Check command input.");
-
-            logger.info("");
-        });
-    }
-
-    /**
-     * Prints missed caches' or cache groups' names.
-     *
-     * @param logger Logger.
-     * @param message Message.
-     * @param missed Missed caches or cache groups' names.
-     */
-    private void printMissed(IgniteLogger logger, String message, Set<String> missed) {
-        if (!F.isEmpty(missed)) {
-            logger.info(message);
-
-            missed.stream()
-                .sorted()
-                .forEach(name -> logger.info(INDENT + name));
-
-            logger.info("");
-        }
-    }
-
-    /**
-     * Prints caches and their indexes.
-     *
-     * @param cachesToIndexes Cache -> indexes map.
-     * @param logger Logger.
-     */
-    private static void printCachesAndIndexes(Map<String, Set<String>> cachesToIndexes, IgniteLogger logger) {
-        cachesToIndexes.forEach((cacheName, indexes) -> {
-            logger.info(INDENT + cacheName + ":");
-            indexes.forEach(index -> logger.info(INDENT + INDENT + index));
-        });
-    }
-
-    /**
-     * @param cacheToIndexes Cache name -> indexes map.
-     * @return {@code true} if has at least one index in the map, {@code false} otherwise.
-     */
-    private static boolean hasAtLeastOneIndex(Map<String, Set<String>> cacheToIndexes) {
-        return cacheToIndexes.values().stream()
-            .anyMatch(indexes -> !indexes.isEmpty());
-    }
-
-    /** {@inheritDoc} */
-    @Override public Arguments arg() {
-        return args;
-    }
-
-    /** {@inheritDoc} */
-    @Override public String name() {
-        return CacheSubcommands.INDEX_REBUILD.text().toUpperCase();
-    }
-
-    /**
-     * Container for command arguments.
-     */
-    public static class Arguments {
-        /** Node id. */
-        @Nullable
-        private final UUID nodeId;
-
-        /** Cache name -> indexes. */
-        @Nullable
-        private final Map<String, Set<String>> cacheToIndexes;
-
-        /** Cache groups' names. */
-        @Nullable
-        private final Set<String> cacheGroups;
-
-        /** */
-        private Arguments(@Nullable UUID nodeId, @Nullable Map<String, Set<String>> cacheToIndexes, @Nullable Set<String> cacheGroups) {
-            this.nodeId = nodeId;
-            this.cacheToIndexes = cacheToIndexes;
-            this.cacheGroups = cacheGroups;
-        }
-
-        /**
-         * @return Cache -> indexes map.
-         */
-        @Nullable
-        public Map<String, Set<String>> cacheToIndexes() {
-            return cacheToIndexes;
-        }
-
-        /**
-         * @return Cache groups.
-         */
-        @Nullable
-        public Set<String> cacheGroups() {
-            return cacheGroups;
-        }
-
-        /** {@inheritDoc} */
-        @Override public String toString() {
-            return S.toString(Arguments.class, this);
-        }
-    }
-
-    /** {@inheritDoc} */
-    @Override public void parseArguments(CommandArgIterator argIterator) {
-        UUID nodeId = null;
-        Map<String, Set<String>> cacheToIndexes = null;
-        Set<String> cacheGroups = null;
-
-        while (argIterator.hasNextSubArg()) {
-            String nextArg = argIterator.nextArg("");
-
-            IndexRebuildCommandArg arg = CommandArgUtils.of(nextArg, IndexRebuildCommandArg.class);
-
-            if (arg == null)
-                throw new IllegalArgumentException("Unknown argument: " + nextArg);
-
-            switch (arg) {
-                case NODE_ID:
-                    if (nodeId != null)
-                        throw new IllegalArgumentException(arg.argName() + " arg specified twice.");
-
-                    nodeId = UUID.fromString(argIterator.nextArg("Failed to read node id."));
-
-                    break;
-
-                case CACHE_NAMES_TARGET:
-                    if (cacheToIndexes != null)
-                        throw new IllegalArgumentException(arg.argName() + " arg specified twice.");
-
-                    cacheToIndexes = new HashMap<>();
-
-                    String cacheNamesArg = argIterator.nextArg("Expected a comma-separated cache names (and optionally a"
-                        + " comma-separated list of index names in square brackets).");
-
-                    Pattern cacheNamesPattern = Pattern.compile("([^,\\[\\]]+)(\\[(.*?)])?");
-                    Matcher matcher = cacheNamesPattern.matcher(cacheNamesArg);
-
-                    boolean found = false;
-
-                    while (matcher.find()) {
-                        found = true;
-
-                        String cacheName = matcher.group(1);
-                        boolean specifiedIndexes = matcher.group(2) != null;
-                        String commaSeparatedIndexes = matcher.group(3);
-
-                        if (!specifiedIndexes) {
-                            cacheToIndexes.put(cacheName, Collections.emptySet());
-
-                            continue;
-                        }
-
-                        if (F.isEmpty(commaSeparatedIndexes)) {
-                            throw new IllegalArgumentException("Square brackets must contain comma-separated indexes or not be used "
-                                + "at all.");
-                        }
-
-                        Set<String> indexes = Arrays.stream(commaSeparatedIndexes.split(",")).collect(toSet());
-                        cacheToIndexes.put(cacheName, indexes);
-                    }
-
-                    if (!found)
-                        throw new IllegalArgumentException("Wrong format for --cache-names, should be: " + CACHE_NAMES_FORMAT);
-
-                    break;
-
-                case CACHE_GROUPS_TARGET:
-                    if (cacheGroups != null)
-                        throw new IllegalArgumentException(arg.argName() + " arg specified twice.");
-
-                    String cacheGroupsArg = argIterator.nextArg("Expected comma-separated cache group names");
-
-                    cacheGroups = Arrays.stream(cacheGroupsArg.split(",")).collect(toSet());
-
-                    break;
-
-                default:
-                    throw new IllegalArgumentException("Unknown argument: " + arg.argName());
-            }
-        }
-
-        args = new Arguments(nodeId, cacheToIndexes, cacheGroups);
-
-        validateArguments();
-    }
-
-    /** */
-    private void validateArguments() {
-        Set<String> cacheGroups = args.cacheGroups;
-        Map<String, Set<String>> cacheToIndexes = args.cacheToIndexes;
-
-        if ((cacheGroups == null || cacheGroups.isEmpty()) && (cacheToIndexes == null || cacheToIndexes.isEmpty()))
-            throw new IllegalArgumentException(CACHE_NAMES_TARGET + " or " + CACHE_GROUPS_TARGET + " must be specified.");
-    }
-}
diff --git a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/cache/CacheSubcommands.java b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/cache/CacheSubcommands.java
deleted file mode 100644
index 0d2b29e76f4..00000000000
--- a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/cache/CacheSubcommands.java
+++ /dev/null
@@ -1,201 +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.ignite.internal.commandline.cache;
-
-import org.apache.ignite.internal.commandline.Command;
-import org.apache.ignite.internal.commandline.argument.CommandArg;
-import org.apache.ignite.internal.commandline.cache.argument.DistributionCommandArg;
-import org.apache.ignite.internal.commandline.cache.argument.FindAndDeleteGarbageArg;
-import org.apache.ignite.internal.commandline.cache.argument.IdleVerifyCommandArg;
-import org.apache.ignite.internal.commandline.cache.argument.IndexForceRebuildCommandArg;
-import org.apache.ignite.internal.commandline.cache.argument.IndexListCommandArg;
-import org.apache.ignite.internal.commandline.cache.argument.IndexRebuildCommandArg;
-import org.apache.ignite.internal.commandline.cache.argument.IndexRebuildStatusArg;
-import org.apache.ignite.internal.commandline.cache.argument.ListCommandArg;
-import org.apache.ignite.internal.commandline.cache.argument.ValidateIndexesCommandArg;
-import org.jetbrains.annotations.Nullable;
-
-/**
- *
- */
-public enum CacheSubcommands {
-    /**
-     * Prints out help for the cache command.
-     */
-    HELP("help", null, null),
-
-    /**
-     * Checks consistency of primary and backup partitions assuming no concurrent updates are happening in the cluster.
-     */
-    IDLE_VERIFY("idle_verify", IdleVerifyCommandArg.class, new IdleVerify()),
-
-    /**
-     * Prints info regarding caches, groups or sequences.
-     */
-    LIST("list", ListCommandArg.class, new CacheViewer()),
-
-    /**
-     * Create caches.
-     */
-    CREATE("create", null, new CacheCreate()),
-
-    /**
-     * Destroy caches.
-     */
-    DESTROY("destroy", null, new CacheDestroy()),
-
-    /**
-     * Clear caches.
-     */
-    CLEAR("clear", null, new CacheClear()),
-
-    /**
-     * Validates indexes attempting to read each indexed entry.
-     */
-    VALIDATE_INDEXES("validate_indexes", ValidateIndexesCommandArg.class, new CacheValidateIndexes()),
-
-    /**
-     * Check secondary indexes inline size.
-     */
-    CHECK_INDEX_INLINE_SIZES("check_index_inline_sizes", null, new CheckIndexInlineSizes()),
-
-    /**
-     * Prints info about contended keys (the keys concurrently locked from multiple transactions).
-     */
-    CONTENTION("contention", null, new CacheContention()),
-
-    /**
-     * Collect information on the distribution of partitions.
-     */
-    DISTRIBUTION("distribution", DistributionCommandArg.class, new CacheDistribution()),
-
-    /**
-     * Reset lost partitions
-     */
-    RESET_LOST_PARTITIONS("reset_lost_partitions", null, new ResetLostPartitions()),
-
-    /**
-     * Find and remove garbage.
-     */
-    FIND_AND_DELETE_GARBAGE("find_garbage", FindAndDeleteGarbageArg.class, new FindAndDeleteGarbage()),
-
-    /**
-     * Index list.
-     */
-    INDEX_LIST("indexes_list", IndexListCommandArg.class, new CacheIndexesList()),
-
-    /**
-     * Index rebuild status.
-     */
-    INDEX_REBUILD_STATUS("indexes_rebuild_status", IndexRebuildStatusArg.class, new CacheIndexesRebuildStatus()),
-
-    /**
-     * Index force rebuild.
-     */
-    INDEX_FORCE_REBUILD("indexes_force_rebuild", IndexForceRebuildCommandArg.class, new CacheIndexesForceRebuild()),
-
-    /**
-     * Enable / disable cache metrics collection or show metrics collection status.
-     */
-    METRICS("metrics", null, new CacheMetrics()),
-
-    /**
-     * Index rebuild via the maintenance mode.
-     */
-    INDEX_REBUILD("schedule_indexes_rebuild", IndexRebuildCommandArg.class, new CacheScheduleIndexesRebuild()),
-
-    /**
-     * Scan cache entries.
-     */
-    SCAN("scan", IndexRebuildCommandArg.class, new CacheScan());
-
-    /** Enumerated values. */
-    private static final CacheSubcommands[] VALS = values();
-
-    /** Enum class with argument list for command. */
-    private final Class<? extends Enum<? extends CommandArg>> commandArgs;
-
-    /** Name. */
-    private final String name;
-
-    /** Command instance for certain type. */
-    private final Command command;
-
-    /**
-     * @param name Name.
-     * @param command Command realization.
-     */
-    CacheSubcommands(
-        String name,
-        Class<? extends Enum<? extends CommandArg>> commandArgs,
-        Command command
-    ) {
-        this.name = name;
-        this.commandArgs = commandArgs;
-        this.command = command;
-    }
-
-    /**
-     * @param text Command text.
-     * @return Command for the text.
-     */
-    public static CacheSubcommands of(String text) {
-        for (CacheSubcommands cmd : CacheSubcommands.values()) {
-            if (cmd.text().equalsIgnoreCase(text))
-                return cmd;
-        }
-
-        return null;
-    }
-
-    /**
-     * @return Name.
-     */
-    public String text() {
-        return name;
-    }
-
-    /**
-     * @return Subcommand realization.
-     */
-    public Command subcommand() {
-        return command;
-    }
-
-    /**
-     * @return Enum class with argument list for command.
-     */
-    public Class<? extends Enum<? extends CommandArg>> getCommandArgs() {
-        return commandArgs;
-    }
-
-    /**
-     * Efficiently gets enumerated value from its ordinal.
-     *
-     * @param ord Ordinal value.
-     * @return Enumerated value or {@code null} if ordinal out of range.
-     */
-    @Nullable public static CacheSubcommands fromOrdinal(int ord) {
-        return ord >= 0 && ord < VALS.length ? VALS[ord] : null;
-    }
-
-    /** {@inheritDoc} */
-    @Override public String toString() {
-        return name;
-    }
-}
diff --git a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/cache/CacheValidateIndexes.java b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/cache/CacheValidateIndexes.java
deleted file mode 100644
index 8d79fd1f7c2..00000000000
--- a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/cache/CacheValidateIndexes.java
+++ /dev/null
@@ -1,337 +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.ignite.internal.commandline.cache;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.UUID;
-import org.apache.ignite.IgniteLogger;
-import org.apache.ignite.internal.client.GridClient;
-import org.apache.ignite.internal.client.GridClientConfiguration;
-import org.apache.ignite.internal.commandline.AbstractCommand;
-import org.apache.ignite.internal.commandline.Command;
-import org.apache.ignite.internal.commandline.CommandArgIterator;
-import org.apache.ignite.internal.commandline.CommandLogger;
-import org.apache.ignite.internal.commandline.argument.CommandArgUtils;
-import org.apache.ignite.internal.commandline.cache.argument.ValidateIndexesCommandArg;
-import org.apache.ignite.internal.processors.cache.verify.PartitionKey;
-import org.apache.ignite.internal.util.typedef.internal.U;
-import org.apache.ignite.internal.visor.verify.IndexIntegrityCheckIssue;
-import org.apache.ignite.internal.visor.verify.IndexValidationIssue;
-import org.apache.ignite.internal.visor.verify.ValidateIndexesCheckSizeIssue;
-import org.apache.ignite.internal.visor.verify.ValidateIndexesCheckSizeResult;
-import org.apache.ignite.internal.visor.verify.ValidateIndexesPartitionResult;
-import org.apache.ignite.internal.visor.verify.VisorValidateIndexesJobResult;
-import org.apache.ignite.internal.visor.verify.VisorValidateIndexesTaskArg;
-import org.apache.ignite.internal.visor.verify.VisorValidateIndexesTaskResult;
-
-import static org.apache.ignite.internal.commandline.CommandLogger.DOUBLE_INDENT;
-import static org.apache.ignite.internal.commandline.CommandLogger.INDENT;
-import static org.apache.ignite.internal.commandline.CommandLogger.join;
-import static org.apache.ignite.internal.commandline.CommandLogger.optional;
-import static org.apache.ignite.internal.commandline.CommandLogger.or;
-import static org.apache.ignite.internal.commandline.TaskExecutor.executeTaskByNameOnNode;
-import static org.apache.ignite.internal.commandline.cache.CacheCommands.OP_NODE_ID;
-import static org.apache.ignite.internal.commandline.cache.CacheSubcommands.VALIDATE_INDEXES;
-import static org.apache.ignite.internal.commandline.cache.argument.ValidateIndexesCommandArg.CHECK_CRC;
-import static org.apache.ignite.internal.commandline.cache.argument.ValidateIndexesCommandArg.CHECK_FIRST;
-import static org.apache.ignite.internal.commandline.cache.argument.ValidateIndexesCommandArg.CHECK_SIZES;
-import static org.apache.ignite.internal.commandline.cache.argument.ValidateIndexesCommandArg.CHECK_THROUGH;
-
-/**
- * Validate indexes command.
- */
-public class CacheValidateIndexes extends AbstractCommand<CacheValidateIndexes.Arguments> {
-    /** {@inheritDoc} */
-    @Override public void printUsage(IgniteLogger logger) {
-        String CACHES = "cacheName1,...,cacheNameN";
-        String description = "Validates indexes for the specified caches/cache groups on an idle cluster " +
-            "on all or specified cluster nodes. " + VALIDATE_INDEXES + " checks consistence between primary/secondary " +
-            "indexes against each other and data entries.";
-
-        Map<String, String> map = U.newLinkedHashMap(16);
-
-        map.put(CHECK_FIRST + " N", "validate only the first N keys");
-        map.put(CHECK_THROUGH + " K", "validate every Kth key");
-        map.put(CHECK_CRC.toString(), "check the CRC-sum of pages stored on disk");
-        map.put(CHECK_SIZES.toString(), "check that index size and cache size are the same");
-
-        usageCache(
-            logger,
-            VALIDATE_INDEXES,
-            description,
... 40321 lines suppressed ...