You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by bb...@apache.org on 2019/06/17 12:22:25 UTC

[nifi] branch master updated: NIFI-6164 - Added CLI commands related to NiFi Registry extension bun… (#3492)

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

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


The following commit(s) were added to refs/heads/master by this push:
     new c7768c9  NIFI-6164 - Added CLI commands related to NiFi Registry extension bun… (#3492)
c7768c9 is described below

commit c7768c909a95cda591ef5c44cdabf530c508a782
Author: Bryan Bende <bb...@gmail.com>
AuthorDate: Mon Jun 17 08:22:19 2019 -0400

    NIFI-6164 - Added CLI commands related to NiFi Registry extension bun… (#3492)
    
    * NIFI-6164 - Added CLI commands related to NiFi Registry extension bundles
    - Adding CLI commands fro uploading extension bundles
    - Adding commands for listing extension bundles and their versions
    - Adding checksums to UploadNarBundles command
    - Adding sha256 to UploadExtensionBundle command, and refactoring result classes to be better organized
    - Improvements for CLI commands to interact with extension registry.
    - Added download-extension-bundle commands.
    - Refactoring ProcessGroupBox
    
    * Refactoring upload-nars command to be upload-bundles
    
    * Rename ListTagCounts to ListExtensionTags and ListExtensionsWithTags to ListExtensions
    
    * Update to catch more specific exception in UploadBundles
    
    Co-Authored-By: Kevin Doran <kd...@apache.org>
---
 nifi-toolkit/nifi-toolkit-cli/pom.xml              |   5 +
 .../cli/impl/client/nifi/ProcessGroupBox.java      |  42 +++---
 .../toolkit/cli/impl/command/CommandOption.java    |  16 +++
 .../cli/impl/command/composite/QuickImport.java    |   4 +-
 .../impl/command/nifi/cs/GetControllerService.java |   2 +-
 .../command/nifi/cs/GetControllerServices.java     |   2 +-
 .../cli/impl/command/nifi/flow/ClusterSummary.java |   2 +-
 .../cli/impl/command/nifi/flow/CurrentUser.java    |   2 +-
 .../impl/command/nifi/flow/GetReportingTask.java   |   2 +-
 .../impl/command/nifi/flow/GetReportingTasks.java  |   2 +-
 .../cli/impl/command/nifi/nodes/ConnectNode.java   |   2 +-
 .../impl/command/nifi/nodes/DisconnectNode.java    |   2 +-
 .../cli/impl/command/nifi/nodes/GetNode.java       |   2 +-
 .../cli/impl/command/nifi/nodes/GetNodes.java      |   2 +-
 .../cli/impl/command/nifi/nodes/OffloadNode.java   |   2 +-
 .../cli/impl/command/nifi/pg/PGGetAllVersions.java |   2 +-
 .../command/nifi/pg/PGGetControllerServices.java   |   2 +-
 .../cli/impl/command/nifi/pg/PGGetVars.java        |   2 +-
 .../cli/impl/command/nifi/pg/PGGetVersion.java     |   2 +-
 .../toolkit/cli/impl/command/nifi/pg/PGList.java   |   2 +-
 .../toolkit/cli/impl/command/nifi/pg/PGStatus.java |   2 +-
 .../command/nifi/policies/GetAccessPolicy.java     |   2 +-
 .../command/nifi/registry/GetRegistryClientId.java |   2 +-
 .../command/nifi/registry/ListRegistryClients.java |   2 +-
 .../command/nifi/templates/DownloadTemplate.java   |   2 +-
 .../impl/command/nifi/templates/ListTemplates.java |   2 +-
 .../impl/command/nifi/tenants/ListUserGroups.java  |   2 +-
 .../cli/impl/command/nifi/tenants/ListUsers.java   |   2 +-
 .../command/registry/NiFiRegistryCommandGroup.java |  18 +++
 .../impl/command/registry/bucket/ListBuckets.java  |   2 +-
 .../command/registry/extension/DownloadBundle.java |  67 +++++++++
 .../registry/extension/GetBundleChecksum.java      |  62 +++++++++
 .../registry/extension/ListBundleArtifacts.java    |  62 +++++++++
 .../ListBundleGroups.java}                         |  39 +++---
 .../registry/extension/ListBundleVersions.java     |  67 +++++++++
 .../ListExtensionTags.java}                        |  29 ++--
 .../command/registry/extension/ListExtensions.java | 108 ++++++++++++++
 .../command/registry/extension/UploadBundle.java   |  92 ++++++++++++
 .../command/registry/extension/UploadBundles.java  | 155 +++++++++++++++++++++
 .../command/registry/flow/ExportFlowVersion.java   |   2 +-
 .../command/registry/flow/ListFlowVersions.java    |   2 +-
 .../cli/impl/command/registry/flow/ListFlows.java  |   2 +-
 .../impl/command/registry/user/CurrentUser.java    |   2 +-
 .../impl/result/{ => nifi}/AccessPolicyResult.java |   3 +-
 .../{ => nifi}/ClusterSummaryEntityResult.java     |   3 +-
 .../result/{ => nifi}/ControllerServiceResult.java |   3 +-
 .../{ => nifi}/ControllerServicesResult.java       |   3 +-
 .../result/{ => nifi}/CurrentUserEntityResult.java |   3 +-
 .../impl/result/{ => nifi}/CurrentUserResult.java  |   3 +-
 .../cli/impl/result/{ => nifi}/NodeResult.java     |   3 +-
 .../cli/impl/result/{ => nifi}/NodesResult.java    |   3 +-
 .../impl/result/{ => nifi}/ProcessGroupResult.java |   3 +-
 .../result/{ => nifi}/ProcessGroupsResult.java     |   3 +-
 .../result/{ => nifi}/RegistryClientIDResult.java  |   3 +-
 .../result/{ => nifi}/RegistryClientsResult.java   |   3 +-
 .../result/{ => nifi}/ReportingTaskResult.java     |   3 +-
 .../result/{ => nifi}/ReportingTasksResult.java    |   3 +-
 .../cli/impl/result/{ => nifi}/TemplateResult.java |   2 +-
 .../impl/result/{ => nifi}/TemplatesResult.java    |   3 +-
 .../impl/result/{ => nifi}/UserGroupsResult.java   |   3 +-
 .../cli/impl/result/{ => nifi}/UsersResult.java    |   3 +-
 .../result/{ => nifi}/VariableRegistryResult.java  |   3 +-
 .../{ => nifi}/VersionControlInfoResult.java       |   3 +-
 .../impl/result/{ => registry}/BucketsResult.java  |   3 +-
 .../BundleVersionResult.java}                      |  32 ++---
 .../result/registry/ExtensionMetadataResult.java   |  74 ++++++++++
 .../ExtensionRepoArtifactsResult.java}             |  58 +++-----
 .../ExtensionRepoGroupsResult.java}                |  52 ++++---
 .../ExtensionRepoVersionSummariesResult.java       |  76 ++++++++++
 .../TagCountResult.java}                           |  45 +++---
 .../VersionedFlowSnapshotMetadataResult.java       |   3 +-
 .../VersionedFlowSnapshotMetadataSetResult.java    |   3 +-
 .../VersionedFlowSnapshotResult.java               |   2 +-
 .../{ => registry}/VersionedFlowsResult.java       |   3 +-
 .../cli/impl/client/nifi/TestProcessGroupBox.java  |  86 ++++++++++++
 .../toolkit/cli/impl/result/TestBucketsResult.java |   1 +
 .../cli/impl/result/TestRegistryClientResult.java  |   1 +
 .../TestVersionedFlowSnapshotMetadataResult.java   |   1 +
 .../cli/impl/result/TestVersionedFlowsResult.java  |   1 +
 pom.xml                                            |   6 +-
 80 files changed, 1118 insertions(+), 212 deletions(-)

diff --git a/nifi-toolkit/nifi-toolkit-cli/pom.xml b/nifi-toolkit/nifi-toolkit-cli/pom.xml
index c39f8cc..cdb2149 100644
--- a/nifi-toolkit/nifi-toolkit-cli/pom.xml
+++ b/nifi-toolkit/nifi-toolkit-cli/pom.xml
@@ -98,6 +98,11 @@
             <version>2.6</version>
         </dependency>
         <dependency>
+            <groupId>commons-codec</groupId>
+            <artifactId>commons-codec</artifactId>
+            <version>1.11</version>
+        </dependency>
+        <dependency>
             <groupId>org.glassfish.jersey.media</groupId>
             <artifactId>jersey-media-multipart</artifactId>
             <version>2.27</version>
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/client/nifi/ProcessGroupBox.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/client/nifi/ProcessGroupBox.java
index b671e26..a20f133 100644
--- a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/client/nifi/ProcessGroupBox.java
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/client/nifi/ProcessGroupBox.java
@@ -56,33 +56,29 @@ public class ProcessGroupBox implements Comparable<ProcessGroupBox> {
         return (int) Math.hypot(x, y);
     }
 
-
     public boolean intersects(ProcessGroupBox other) {
-        // adapted from java.awt Rectangle, we don't want to import it
-        // assume everything to be of the PG size for simplicity
-        int tw = PG_SIZE_WIDTH;
-        int th = PG_SIZE_HEIGHT;
-        // 2nd pg box includes spacers
-        int rw = PG_SIZE_WIDTH;
-        int rh = PG_SIZE_HEIGHT;
-        if (rw <= 0 || rh <= 0 || tw <= 0 || th <= 0) {
+        // this is completely left of other
+        if (this.x + PG_SIZE_WIDTH < other.x) {
+            return false;
+        }
+
+        // this is completely right of other
+        if (this.x > other.x + PG_SIZE_WIDTH) {
+            return false;
+        }
+
+        // this is completely above other
+        if (this.y + PG_SIZE_HEIGHT < other.y) {
+            return false;
+        }
+
+        // this is completely below other
+        if (this.y > other.y + PG_SIZE_HEIGHT) {
             return false;
         }
-        double tx = this.x;
-        double ty = this.y;
-        double rx = other.x;
-        double ry = other.y;
-        rw += rx;
-        rh += ry;
-        tw += tx;
-        th += ty;
-        //      overflow || intersect
-        return ((rw < rx || rw > tx)
-                && (rh < ry || rh > ty)
-                && (tw < tx || tw > rx)
-                && (th < ty || th > ry));
-    }
 
+        return true;
+    }
 
     public ProcessGroupBox findFreeSpace(List<ProcessGroupBox> allCoords) {
         // sort by distance to (0.0)
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/CommandOption.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/CommandOption.java
index fced121..ab74cfe 100644
--- a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/CommandOption.java
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/CommandOption.java
@@ -27,8 +27,10 @@ public enum CommandOption {
     URL("u", "baseUrl", "The URL to execute the command against", true),
     INPUT_SOURCE("i", "input", "A local file to read as input contents, or a public URL to fetch", true, true),
     OUTPUT_FILE("o", "outputFile", "A file to write output to, must contain full path and filename", true, true),
+    OUTPUT_DIR("od", "outputDirectory", "A directory to write output to", true, true),
     PROPERTIES("p", "properties", "A properties file to load arguments from, " +
             "command line values will override anything in the properties file, must contain full path to file", true, true),
+    FILE_EXTENSION("fe", "fileExtension", "A file extension such as '.nar'", true, false),
 
     NIFI_PROPS("nifiProps", "nifiProps", "A properties file to load for NiFi config", true, true),
     NIFI_REG_PROPS("nifiRegProps", "nifiRegProps", "A properties file to load for NiFi Registry config", true, true),
@@ -49,6 +51,19 @@ public enum CommandOption {
     SRC_FLOW_ID("sf", "sourceFlowIdentifier", "A flow identifier from the source registry", true),
     SRC_FLOW_VERSION("sfv", "sourceFlowVersion", "A version of a flow from the source registry", true),
 
+    // Registry - Extensions
+    EXT_BUNDLE_GROUP("gr", "group", "The group id of a bundle", true),
+    EXT_BUNDLE_ARTIFACT("ar", "artifact", "The artifact id of a bundle", true),
+    EXT_BUNDLE_VERSION("ver", "version", "The version of the bundle", true),
+
+    EXT_TYPE("et", "extensionType", "The type of extension, one of 'PROCESSOR', 'CONTROLLER_SERVICE', or 'REPORTING_TASK'.", true),
+    EXT_BUNDLE_TYPE("ebt", "extensionBundleType", "The type of extension bundle, either nifi-nar or minifi-cpp", true),
+    EXT_BUNDLE_FILE("ebf", "extensionBundleFile", "An extension bundle file, such as a NAR or MiNiFi CPP binary", true, true),
+    EXT_BUNDLE_DIR("ebd", "extensionBundleDir", "A directory where extension bundles are located", true, true),
+    SKIP_SHA_256("skipSha256", "skipSha256", "Skips the client side calculation of the SHA-256 when uploading an extension bundle", false),
+
+    EXT_TAGS("tags", "tags", "A comma separated list of one or more extension tags", true),
+
     // NiFi - Nodes
     NIFI_NODE_ID("nnid", "nifiNodeId", "The ID of a node in the NiFi cluster", true),
 
@@ -102,6 +117,7 @@ public enum CommandOption {
     FORCE("force", "force", "Indicates to force a delete operation", false),
     OUTPUT_TYPE("ot", "outputType", "The type of output to produce (json or simple)", true),
     VERBOSE("verbose", "verbose", "Indicates that verbose output should be provided", false),
+    RECURSIVE("r", "recursive", "Indicates the command should perform the action recursively", false),
     HELP("h", "help", "Help", false)
     ;
 
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/composite/QuickImport.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/composite/QuickImport.java
index 5c504a4..e096e88 100644
--- a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/composite/QuickImport.java
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/composite/QuickImport.java
@@ -34,8 +34,8 @@ import org.apache.nifi.toolkit.cli.impl.command.registry.bucket.CreateBucket;
 import org.apache.nifi.toolkit.cli.impl.command.registry.bucket.ListBuckets;
 import org.apache.nifi.toolkit.cli.impl.command.registry.flow.CreateFlow;
 import org.apache.nifi.toolkit.cli.impl.command.registry.flow.ImportFlowVersion;
-import org.apache.nifi.toolkit.cli.impl.result.BucketsResult;
-import org.apache.nifi.toolkit.cli.impl.result.RegistryClientIDResult;
+import org.apache.nifi.toolkit.cli.impl.result.registry.BucketsResult;
+import org.apache.nifi.toolkit.cli.impl.result.nifi.RegistryClientIDResult;
 import org.apache.nifi.toolkit.cli.impl.result.StringResult;
 
 import java.io.IOException;
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/cs/GetControllerService.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/cs/GetControllerService.java
index c777a53..4324e71 100644
--- a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/cs/GetControllerService.java
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/cs/GetControllerService.java
@@ -23,7 +23,7 @@ import org.apache.nifi.toolkit.cli.impl.client.nifi.NiFiClient;
 import org.apache.nifi.toolkit.cli.impl.client.nifi.NiFiClientException;
 import org.apache.nifi.toolkit.cli.impl.command.CommandOption;
 import org.apache.nifi.toolkit.cli.impl.command.nifi.AbstractNiFiCommand;
-import org.apache.nifi.toolkit.cli.impl.result.ControllerServiceResult;
+import org.apache.nifi.toolkit.cli.impl.result.nifi.ControllerServiceResult;
 import org.apache.nifi.web.api.entity.ControllerServiceEntity;
 
 import java.io.IOException;
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/cs/GetControllerServices.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/cs/GetControllerServices.java
index e28a883..1d9a319 100644
--- a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/cs/GetControllerServices.java
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/cs/GetControllerServices.java
@@ -22,7 +22,7 @@ import org.apache.nifi.toolkit.cli.impl.client.nifi.FlowClient;
 import org.apache.nifi.toolkit.cli.impl.client.nifi.NiFiClient;
 import org.apache.nifi.toolkit.cli.impl.client.nifi.NiFiClientException;
 import org.apache.nifi.toolkit.cli.impl.command.nifi.AbstractNiFiCommand;
-import org.apache.nifi.toolkit.cli.impl.result.ControllerServicesResult;
+import org.apache.nifi.toolkit.cli.impl.result.nifi.ControllerServicesResult;
 import org.apache.nifi.web.api.entity.ControllerServicesEntity;
 
 import java.io.IOException;
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/flow/ClusterSummary.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/flow/ClusterSummary.java
index dfe3898..98c6453 100644
--- a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/flow/ClusterSummary.java
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/flow/ClusterSummary.java
@@ -20,7 +20,7 @@ import org.apache.nifi.toolkit.cli.impl.client.nifi.FlowClient;
 import org.apache.nifi.toolkit.cli.impl.client.nifi.NiFiClient;
 import org.apache.nifi.toolkit.cli.impl.client.nifi.NiFiClientException;
 import org.apache.nifi.toolkit.cli.impl.command.nifi.AbstractNiFiCommand;
-import org.apache.nifi.toolkit.cli.impl.result.ClusterSummaryEntityResult;
+import org.apache.nifi.toolkit.cli.impl.result.nifi.ClusterSummaryEntityResult;
 import org.apache.nifi.web.api.entity.ClusteSummaryEntity;
 
 import java.io.IOException;
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/flow/CurrentUser.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/flow/CurrentUser.java
index 3f21dea..9b43801 100644
--- a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/flow/CurrentUser.java
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/flow/CurrentUser.java
@@ -20,7 +20,7 @@ import org.apache.nifi.toolkit.cli.impl.client.nifi.FlowClient;
 import org.apache.nifi.toolkit.cli.impl.client.nifi.NiFiClient;
 import org.apache.nifi.toolkit.cli.impl.client.nifi.NiFiClientException;
 import org.apache.nifi.toolkit.cli.impl.command.nifi.AbstractNiFiCommand;
-import org.apache.nifi.toolkit.cli.impl.result.CurrentUserEntityResult;
+import org.apache.nifi.toolkit.cli.impl.result.nifi.CurrentUserEntityResult;
 import org.apache.nifi.web.api.entity.CurrentUserEntity;
 
 import java.io.IOException;
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/flow/GetReportingTask.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/flow/GetReportingTask.java
index 763decc..7acd854 100644
--- a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/flow/GetReportingTask.java
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/flow/GetReportingTask.java
@@ -25,7 +25,7 @@ import org.apache.nifi.toolkit.cli.impl.client.nifi.NiFiClientException;
 import org.apache.nifi.toolkit.cli.impl.client.nifi.ReportingTasksClient;
 import org.apache.nifi.toolkit.cli.impl.command.CommandOption;
 import org.apache.nifi.toolkit.cli.impl.command.nifi.AbstractNiFiCommand;
-import org.apache.nifi.toolkit.cli.impl.result.ReportingTaskResult;
+import org.apache.nifi.toolkit.cli.impl.result.nifi.ReportingTaskResult;
 import org.apache.nifi.web.api.entity.ReportingTaskEntity;
 
 import java.io.IOException;
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/flow/GetReportingTasks.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/flow/GetReportingTasks.java
index 6573601..427e31c 100644
--- a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/flow/GetReportingTasks.java
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/flow/GetReportingTasks.java
@@ -22,7 +22,7 @@ import org.apache.nifi.toolkit.cli.impl.client.nifi.FlowClient;
 import org.apache.nifi.toolkit.cli.impl.client.nifi.NiFiClient;
 import org.apache.nifi.toolkit.cli.impl.client.nifi.NiFiClientException;
 import org.apache.nifi.toolkit.cli.impl.command.nifi.AbstractNiFiCommand;
-import org.apache.nifi.toolkit.cli.impl.result.ReportingTasksResult;
+import org.apache.nifi.toolkit.cli.impl.result.nifi.ReportingTasksResult;
 import org.apache.nifi.web.api.entity.ReportingTasksEntity;
 
 import java.io.IOException;
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/nodes/ConnectNode.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/nodes/ConnectNode.java
index 8ec0066..c2e2714 100644
--- a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/nodes/ConnectNode.java
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/nodes/ConnectNode.java
@@ -24,7 +24,7 @@ import org.apache.nifi.toolkit.cli.impl.client.nifi.NiFiClient;
 import org.apache.nifi.toolkit.cli.impl.client.nifi.NiFiClientException;
 import org.apache.nifi.toolkit.cli.impl.command.CommandOption;
 import org.apache.nifi.toolkit.cli.impl.command.nifi.AbstractNiFiCommand;
-import org.apache.nifi.toolkit.cli.impl.result.NodeResult;
+import org.apache.nifi.toolkit.cli.impl.result.nifi.NodeResult;
 import org.apache.nifi.web.api.dto.NodeDTO;
 import org.apache.nifi.web.api.entity.NodeEntity;
 
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/nodes/DisconnectNode.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/nodes/DisconnectNode.java
index 65a7e72..029eb0e 100644
--- a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/nodes/DisconnectNode.java
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/nodes/DisconnectNode.java
@@ -24,7 +24,7 @@ import org.apache.nifi.toolkit.cli.impl.client.nifi.NiFiClient;
 import org.apache.nifi.toolkit.cli.impl.client.nifi.NiFiClientException;
 import org.apache.nifi.toolkit.cli.impl.command.CommandOption;
 import org.apache.nifi.toolkit.cli.impl.command.nifi.AbstractNiFiCommand;
-import org.apache.nifi.toolkit.cli.impl.result.NodeResult;
+import org.apache.nifi.toolkit.cli.impl.result.nifi.NodeResult;
 import org.apache.nifi.web.api.dto.NodeDTO;
 import org.apache.nifi.web.api.entity.NodeEntity;
 
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/nodes/GetNode.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/nodes/GetNode.java
index 54687bd..4d643c2 100644
--- a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/nodes/GetNode.java
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/nodes/GetNode.java
@@ -23,7 +23,7 @@ import org.apache.nifi.toolkit.cli.impl.client.nifi.NiFiClient;
 import org.apache.nifi.toolkit.cli.impl.client.nifi.NiFiClientException;
 import org.apache.nifi.toolkit.cli.impl.command.CommandOption;
 import org.apache.nifi.toolkit.cli.impl.command.nifi.AbstractNiFiCommand;
-import org.apache.nifi.toolkit.cli.impl.result.NodeResult;
+import org.apache.nifi.toolkit.cli.impl.result.nifi.NodeResult;
 import org.apache.nifi.web.api.entity.NodeEntity;
 
 import java.io.IOException;
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/nodes/GetNodes.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/nodes/GetNodes.java
index 368fb4d..c2449f9 100644
--- a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/nodes/GetNodes.java
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/nodes/GetNodes.java
@@ -22,7 +22,7 @@ import org.apache.nifi.toolkit.cli.impl.client.nifi.ControllerClient;
 import org.apache.nifi.toolkit.cli.impl.client.nifi.NiFiClient;
 import org.apache.nifi.toolkit.cli.impl.client.nifi.NiFiClientException;
 import org.apache.nifi.toolkit.cli.impl.command.nifi.AbstractNiFiCommand;
-import org.apache.nifi.toolkit.cli.impl.result.NodesResult;
+import org.apache.nifi.toolkit.cli.impl.result.nifi.NodesResult;
 import org.apache.nifi.web.api.entity.ClusterEntity;
 
 import java.io.IOException;
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/nodes/OffloadNode.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/nodes/OffloadNode.java
index aa759b1..8f43f25 100644
--- a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/nodes/OffloadNode.java
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/nodes/OffloadNode.java
@@ -24,7 +24,7 @@ import org.apache.nifi.toolkit.cli.impl.client.nifi.NiFiClient;
 import org.apache.nifi.toolkit.cli.impl.client.nifi.NiFiClientException;
 import org.apache.nifi.toolkit.cli.impl.command.CommandOption;
 import org.apache.nifi.toolkit.cli.impl.command.nifi.AbstractNiFiCommand;
-import org.apache.nifi.toolkit.cli.impl.result.NodeResult;
+import org.apache.nifi.toolkit.cli.impl.result.nifi.NodeResult;
 import org.apache.nifi.web.api.dto.NodeDTO;
 import org.apache.nifi.web.api.entity.NodeEntity;
 
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/pg/PGGetAllVersions.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/pg/PGGetAllVersions.java
index b3cd36c..e9a3d71 100644
--- a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/pg/PGGetAllVersions.java
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/pg/PGGetAllVersions.java
@@ -24,7 +24,7 @@ import org.apache.nifi.toolkit.cli.impl.client.nifi.NiFiClientException;
 import org.apache.nifi.toolkit.cli.impl.client.nifi.VersionsClient;
 import org.apache.nifi.toolkit.cli.impl.command.CommandOption;
 import org.apache.nifi.toolkit.cli.impl.command.nifi.AbstractNiFiCommand;
-import org.apache.nifi.toolkit.cli.impl.result.VersionedFlowSnapshotMetadataSetResult;
+import org.apache.nifi.toolkit.cli.impl.result.registry.VersionedFlowSnapshotMetadataSetResult;
 import org.apache.nifi.web.api.dto.VersionControlInformationDTO;
 import org.apache.nifi.web.api.entity.VersionControlInformationEntity;
 import org.apache.nifi.web.api.entity.VersionedFlowSnapshotMetadataSetEntity;
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/pg/PGGetControllerServices.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/pg/PGGetControllerServices.java
index f4178aa..e247f8f 100644
--- a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/pg/PGGetControllerServices.java
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/pg/PGGetControllerServices.java
@@ -24,7 +24,7 @@ import org.apache.nifi.toolkit.cli.impl.client.nifi.NiFiClient;
 import org.apache.nifi.toolkit.cli.impl.client.nifi.NiFiClientException;
 import org.apache.nifi.toolkit.cli.impl.command.CommandOption;
 import org.apache.nifi.toolkit.cli.impl.command.nifi.AbstractNiFiCommand;
-import org.apache.nifi.toolkit.cli.impl.result.ControllerServicesResult;
+import org.apache.nifi.toolkit.cli.impl.result.nifi.ControllerServicesResult;
 import org.apache.nifi.web.api.entity.ControllerServicesEntity;
 
 import java.io.IOException;
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/pg/PGGetVars.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/pg/PGGetVars.java
index dfd1a1c..b309f86 100644
--- a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/pg/PGGetVars.java
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/pg/PGGetVars.java
@@ -24,7 +24,7 @@ import org.apache.nifi.toolkit.cli.impl.client.nifi.NiFiClientException;
 import org.apache.nifi.toolkit.cli.impl.client.nifi.ProcessGroupClient;
 import org.apache.nifi.toolkit.cli.impl.command.CommandOption;
 import org.apache.nifi.toolkit.cli.impl.command.nifi.AbstractNiFiCommand;
-import org.apache.nifi.toolkit.cli.impl.result.VariableRegistryResult;
+import org.apache.nifi.toolkit.cli.impl.result.nifi.VariableRegistryResult;
 import org.apache.nifi.web.api.entity.VariableRegistryEntity;
 
 import java.io.IOException;
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/pg/PGGetVersion.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/pg/PGGetVersion.java
index 6c9da87..4df6448 100644
--- a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/pg/PGGetVersion.java
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/pg/PGGetVersion.java
@@ -23,7 +23,7 @@ import org.apache.nifi.toolkit.cli.impl.client.nifi.NiFiClient;
 import org.apache.nifi.toolkit.cli.impl.client.nifi.NiFiClientException;
 import org.apache.nifi.toolkit.cli.impl.command.CommandOption;
 import org.apache.nifi.toolkit.cli.impl.command.nifi.AbstractNiFiCommand;
-import org.apache.nifi.toolkit.cli.impl.result.VersionControlInfoResult;
+import org.apache.nifi.toolkit.cli.impl.result.nifi.VersionControlInfoResult;
 import org.apache.nifi.web.api.entity.VersionControlInformationEntity;
 
 import java.io.IOException;
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/pg/PGList.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/pg/PGList.java
index f980d9c..5ba8272 100644
--- a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/pg/PGList.java
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/pg/PGList.java
@@ -23,7 +23,7 @@ import org.apache.nifi.toolkit.cli.impl.client.nifi.NiFiClient;
 import org.apache.nifi.toolkit.cli.impl.client.nifi.NiFiClientException;
 import org.apache.nifi.toolkit.cli.impl.command.CommandOption;
 import org.apache.nifi.toolkit.cli.impl.command.nifi.AbstractNiFiCommand;
-import org.apache.nifi.toolkit.cli.impl.result.ProcessGroupsResult;
+import org.apache.nifi.toolkit.cli.impl.result.nifi.ProcessGroupsResult;
 import org.apache.nifi.web.api.dto.ProcessGroupDTO;
 import org.apache.nifi.web.api.dto.flow.FlowDTO;
 import org.apache.nifi.web.api.dto.flow.ProcessGroupFlowDTO;
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/pg/PGStatus.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/pg/PGStatus.java
index 0ffcd37..6dc153f 100644
--- a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/pg/PGStatus.java
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/pg/PGStatus.java
@@ -23,7 +23,7 @@ import org.apache.nifi.toolkit.cli.impl.client.nifi.NiFiClient;
 import org.apache.nifi.toolkit.cli.impl.client.nifi.NiFiClientException;
 import org.apache.nifi.toolkit.cli.impl.command.CommandOption;
 import org.apache.nifi.toolkit.cli.impl.command.nifi.AbstractNiFiCommand;
-import org.apache.nifi.toolkit.cli.impl.result.ProcessGroupResult;
+import org.apache.nifi.toolkit.cli.impl.result.nifi.ProcessGroupResult;
 import org.apache.nifi.web.api.entity.ProcessGroupEntity;
 
 import java.io.IOException;
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/policies/GetAccessPolicy.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/policies/GetAccessPolicy.java
index 4d44414..55ae445 100644
--- a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/policies/GetAccessPolicy.java
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/policies/GetAccessPolicy.java
@@ -25,7 +25,7 @@ import org.apache.nifi.toolkit.cli.impl.client.nifi.NiFiClientException;
 import org.apache.nifi.toolkit.cli.impl.client.nifi.PoliciesClient;
 import org.apache.nifi.toolkit.cli.impl.command.CommandOption;
 import org.apache.nifi.toolkit.cli.impl.command.nifi.AbstractNiFiCommand;
-import org.apache.nifi.toolkit.cli.impl.result.AccessPolicyResult;
+import org.apache.nifi.toolkit.cli.impl.result.nifi.AccessPolicyResult;
 
 import java.io.IOException;
 import java.util.Properties;
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/registry/GetRegistryClientId.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/registry/GetRegistryClientId.java
index c2dd7a1..1fd68a0 100644
--- a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/registry/GetRegistryClientId.java
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/registry/GetRegistryClientId.java
@@ -23,7 +23,7 @@ import org.apache.nifi.toolkit.cli.impl.client.nifi.NiFiClient;
 import org.apache.nifi.toolkit.cli.impl.client.nifi.NiFiClientException;
 import org.apache.nifi.toolkit.cli.impl.command.CommandOption;
 import org.apache.nifi.toolkit.cli.impl.command.nifi.AbstractNiFiCommand;
-import org.apache.nifi.toolkit.cli.impl.result.RegistryClientIDResult;
+import org.apache.nifi.toolkit.cli.impl.result.nifi.RegistryClientIDResult;
 import org.apache.nifi.web.api.dto.RegistryDTO;
 import org.apache.nifi.web.api.entity.RegistryClientsEntity;
 
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/registry/ListRegistryClients.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/registry/ListRegistryClients.java
index 96264c5..1308061 100644
--- a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/registry/ListRegistryClients.java
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/registry/ListRegistryClients.java
@@ -19,7 +19,7 @@ package org.apache.nifi.toolkit.cli.impl.command.nifi.registry;
 import org.apache.nifi.toolkit.cli.impl.client.nifi.NiFiClient;
 import org.apache.nifi.toolkit.cli.impl.client.nifi.NiFiClientException;
 import org.apache.nifi.toolkit.cli.impl.command.nifi.AbstractNiFiCommand;
-import org.apache.nifi.toolkit.cli.impl.result.RegistryClientsResult;
+import org.apache.nifi.toolkit.cli.impl.result.nifi.RegistryClientsResult;
 import org.apache.nifi.web.api.entity.RegistryClientsEntity;
 
 import java.io.IOException;
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/templates/DownloadTemplate.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/templates/DownloadTemplate.java
index 8c346b4..4657c50 100644
--- a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/templates/DownloadTemplate.java
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/templates/DownloadTemplate.java
@@ -24,7 +24,7 @@ import org.apache.nifi.toolkit.cli.impl.client.nifi.NiFiClientException;
 import org.apache.nifi.toolkit.cli.impl.client.nifi.TemplatesClient;
 import org.apache.nifi.toolkit.cli.impl.command.CommandOption;
 import org.apache.nifi.toolkit.cli.impl.command.nifi.AbstractNiFiCommand;
-import org.apache.nifi.toolkit.cli.impl.result.TemplateResult;
+import org.apache.nifi.toolkit.cli.impl.result.nifi.TemplateResult;
 import org.apache.nifi.web.api.dto.TemplateDTO;
 
 import java.io.IOException;
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/templates/ListTemplates.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/templates/ListTemplates.java
index c28a635..c9cd75c 100644
--- a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/templates/ListTemplates.java
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/templates/ListTemplates.java
@@ -22,7 +22,7 @@ import org.apache.nifi.toolkit.cli.api.CommandException;
 import org.apache.nifi.toolkit.cli.impl.client.nifi.NiFiClient;
 import org.apache.nifi.toolkit.cli.impl.client.nifi.NiFiClientException;
 import org.apache.nifi.toolkit.cli.impl.command.nifi.AbstractNiFiCommand;
-import org.apache.nifi.toolkit.cli.impl.result.TemplatesResult;
+import org.apache.nifi.toolkit.cli.impl.result.nifi.TemplatesResult;
 import org.apache.nifi.web.api.entity.TemplatesEntity;
 
 import java.io.IOException;
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/tenants/ListUserGroups.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/tenants/ListUserGroups.java
index bea8d5c..d5ea9d6 100644
--- a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/tenants/ListUserGroups.java
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/tenants/ListUserGroups.java
@@ -22,7 +22,7 @@ import org.apache.nifi.toolkit.cli.impl.client.nifi.NiFiClient;
 import org.apache.nifi.toolkit.cli.impl.client.nifi.NiFiClientException;
 import org.apache.nifi.toolkit.cli.impl.client.nifi.TenantsClient;
 import org.apache.nifi.toolkit.cli.impl.command.nifi.AbstractNiFiCommand;
-import org.apache.nifi.toolkit.cli.impl.result.UserGroupsResult;
+import org.apache.nifi.toolkit.cli.impl.result.nifi.UserGroupsResult;
 import org.apache.nifi.web.api.entity.UserGroupsEntity;
 
 import java.io.IOException;
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/tenants/ListUsers.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/tenants/ListUsers.java
index e18fc80..e7d722d 100644
--- a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/tenants/ListUsers.java
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/tenants/ListUsers.java
@@ -22,7 +22,7 @@ import org.apache.nifi.toolkit.cli.impl.client.nifi.NiFiClient;
 import org.apache.nifi.toolkit.cli.impl.client.nifi.NiFiClientException;
 import org.apache.nifi.toolkit.cli.impl.client.nifi.TenantsClient;
 import org.apache.nifi.toolkit.cli.impl.command.nifi.AbstractNiFiCommand;
-import org.apache.nifi.toolkit.cli.impl.result.UsersResult;
+import org.apache.nifi.toolkit.cli.impl.result.nifi.UsersResult;
 import org.apache.nifi.web.api.entity.UsersEntity;
 
 import java.io.IOException;
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/NiFiRegistryCommandGroup.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/NiFiRegistryCommandGroup.java
index 6b2f059..bb077d9 100644
--- a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/NiFiRegistryCommandGroup.java
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/NiFiRegistryCommandGroup.java
@@ -21,6 +21,15 @@ import org.apache.nifi.toolkit.cli.impl.command.AbstractCommandGroup;
 import org.apache.nifi.toolkit.cli.impl.command.registry.bucket.CreateBucket;
 import org.apache.nifi.toolkit.cli.impl.command.registry.bucket.DeleteBucket;
 import org.apache.nifi.toolkit.cli.impl.command.registry.bucket.ListBuckets;
+import org.apache.nifi.toolkit.cli.impl.command.registry.extension.DownloadBundle;
+import org.apache.nifi.toolkit.cli.impl.command.registry.extension.GetBundleChecksum;
+import org.apache.nifi.toolkit.cli.impl.command.registry.extension.ListExtensions;
+import org.apache.nifi.toolkit.cli.impl.command.registry.extension.ListExtensionTags;
+import org.apache.nifi.toolkit.cli.impl.command.registry.extension.ListBundleArtifacts;
+import org.apache.nifi.toolkit.cli.impl.command.registry.extension.ListBundleGroups;
+import org.apache.nifi.toolkit.cli.impl.command.registry.extension.ListBundleVersions;
+import org.apache.nifi.toolkit.cli.impl.command.registry.extension.UploadBundle;
+import org.apache.nifi.toolkit.cli.impl.command.registry.extension.UploadBundles;
 import org.apache.nifi.toolkit.cli.impl.command.registry.flow.CreateFlow;
 import org.apache.nifi.toolkit.cli.impl.command.registry.flow.DeleteFlow;
 import org.apache.nifi.toolkit.cli.impl.command.registry.flow.ExportFlowVersion;
@@ -60,6 +69,15 @@ public class NiFiRegistryCommandGroup extends AbstractCommandGroup {
         commandList.add(new ImportFlowVersion());
         commandList.add(new SyncFlowVersions());
         commandList.add(new TransferFlowVersion());
+        commandList.add(new UploadBundle());
+        commandList.add(new UploadBundles());
+        commandList.add(new ListBundleGroups());
+        commandList.add(new ListBundleArtifacts());
+        commandList.add(new ListBundleVersions());
+        commandList.add(new DownloadBundle());
+        commandList.add(new GetBundleChecksum());
+        commandList.add(new ListExtensionTags());
+        commandList.add(new ListExtensions());
         return new ArrayList<>(commandList);
     }
 }
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/bucket/ListBuckets.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/bucket/ListBuckets.java
index 7454cf1..82e9589 100644
--- a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/bucket/ListBuckets.java
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/bucket/ListBuckets.java
@@ -20,7 +20,7 @@ import org.apache.nifi.registry.bucket.Bucket;
 import org.apache.nifi.registry.client.NiFiRegistryClient;
 import org.apache.nifi.registry.client.NiFiRegistryException;
 import org.apache.nifi.toolkit.cli.impl.command.registry.AbstractNiFiRegistryCommand;
-import org.apache.nifi.toolkit.cli.impl.result.BucketsResult;
+import org.apache.nifi.toolkit.cli.impl.result.registry.BucketsResult;
 
 import java.io.IOException;
 import java.util.List;
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/extension/DownloadBundle.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/extension/DownloadBundle.java
new file mode 100644
index 0000000..297331d
--- /dev/null
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/extension/DownloadBundle.java
@@ -0,0 +1,67 @@
+/*
+ * 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.nifi.toolkit.cli.impl.command.registry.extension;
+
+import org.apache.commons.cli.ParseException;
+import org.apache.nifi.registry.client.ExtensionRepoClient;
+import org.apache.nifi.registry.client.NiFiRegistryClient;
+import org.apache.nifi.registry.client.NiFiRegistryException;
+import org.apache.nifi.toolkit.cli.api.Context;
+import org.apache.nifi.toolkit.cli.impl.command.CommandOption;
+import org.apache.nifi.toolkit.cli.impl.command.registry.AbstractNiFiRegistryCommand;
+import org.apache.nifi.toolkit.cli.impl.result.VoidResult;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Properties;
+
+public class DownloadBundle extends AbstractNiFiRegistryCommand<VoidResult> {
+
+    public DownloadBundle() {
+        super("download-bundle", VoidResult.class);
+    }
+
+    @Override
+    public String getDescription() {
+        return "Downloads the binary content of the given version of the extension bundle.";
+    }
+
+    @Override
+    public void doInitialize(final Context context) {
+        addOption(CommandOption.BUCKET_NAME.createOption());
+        addOption(CommandOption.EXT_BUNDLE_GROUP.createOption());
+        addOption(CommandOption.EXT_BUNDLE_ARTIFACT.createOption());
+        addOption(CommandOption.EXT_BUNDLE_VERSION.createOption());
+        addOption(CommandOption.OUTPUT_DIR.createOption());
+    }
+
+    @Override
+    public VoidResult doExecute(final NiFiRegistryClient client, final Properties properties)
+            throws IOException, NiFiRegistryException, ParseException {
+
+        final String bucketName = getRequiredArg(properties, CommandOption.BUCKET_NAME);
+        final String groupId = getRequiredArg(properties, CommandOption.EXT_BUNDLE_GROUP);
+        final String artifactId = getRequiredArg(properties, CommandOption.EXT_BUNDLE_ARTIFACT);
+        final String version = getRequiredArg(properties, CommandOption.EXT_BUNDLE_VERSION);
+        final File outputDir = new File(getRequiredArg(properties, CommandOption.OUTPUT_DIR));
+
+        final ExtensionRepoClient repoClient = client.getExtensionRepoClient();
+        repoClient.writeBundleVersionContent(bucketName, groupId, artifactId, version, outputDir);
+        return VoidResult.getInstance();
+    }
+
+}
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/extension/GetBundleChecksum.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/extension/GetBundleChecksum.java
new file mode 100644
index 0000000..ffd6bf5
--- /dev/null
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/extension/GetBundleChecksum.java
@@ -0,0 +1,62 @@
+/*
+ * 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.nifi.toolkit.cli.impl.command.registry.extension;
+
+import org.apache.commons.cli.ParseException;
+import org.apache.nifi.registry.client.ExtensionRepoClient;
+import org.apache.nifi.registry.client.NiFiRegistryClient;
+import org.apache.nifi.registry.client.NiFiRegistryException;
+import org.apache.nifi.toolkit.cli.api.Context;
+import org.apache.nifi.toolkit.cli.impl.command.CommandOption;
+import org.apache.nifi.toolkit.cli.impl.command.registry.AbstractNiFiRegistryCommand;
+import org.apache.nifi.toolkit.cli.impl.result.StringResult;
+
+import java.io.IOException;
+import java.util.Properties;
+
+public class GetBundleChecksum extends AbstractNiFiRegistryCommand<StringResult> {
+
+    public GetBundleChecksum() {
+        super("get-bundle-checksum", StringResult.class);
+    }
+
+    @Override
+    protected void doInitialize(Context context) {
+        addOption(CommandOption.BUCKET_NAME.createOption());
+        addOption(CommandOption.EXT_BUNDLE_GROUP.createOption());
+        addOption(CommandOption.EXT_BUNDLE_ARTIFACT.createOption());
+        addOption(CommandOption.EXT_BUNDLE_VERSION.createOption());
+    }
+
+    @Override
+    public String getDescription() {
+        return "Retrieves the SHA-256 checksum for the given bundle.";
+    }
+
+    @Override
+    public StringResult doExecute(final NiFiRegistryClient client, final Properties properties)
+            throws IOException, NiFiRegistryException, ParseException {
+        final String bucketName = getRequiredArg(properties, CommandOption.BUCKET_NAME);
+        final String groupId = getRequiredArg(properties, CommandOption.EXT_BUNDLE_GROUP);
+        final String artifactId = getRequiredArg(properties, CommandOption.EXT_BUNDLE_ARTIFACT);
+        final String version = getRequiredArg(properties, CommandOption.EXT_BUNDLE_VERSION);
+
+        final ExtensionRepoClient repoClient = client.getExtensionRepoClient();
+        final String checksum = repoClient.getVersionSha256(bucketName, groupId, artifactId, version);
+        return new StringResult(checksum, isInteractive());
+    }
+}
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/extension/ListBundleArtifacts.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/extension/ListBundleArtifacts.java
new file mode 100644
index 0000000..c0eb3e3
--- /dev/null
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/extension/ListBundleArtifacts.java
@@ -0,0 +1,62 @@
+/*
+ * 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.nifi.toolkit.cli.impl.command.registry.extension;
+
+import org.apache.commons.cli.ParseException;
+import org.apache.nifi.registry.client.ExtensionRepoClient;
+import org.apache.nifi.registry.client.NiFiRegistryClient;
+import org.apache.nifi.registry.client.NiFiRegistryException;
+import org.apache.nifi.registry.extension.repo.ExtensionRepoArtifact;
+import org.apache.nifi.toolkit.cli.api.Context;
+import org.apache.nifi.toolkit.cli.impl.command.CommandOption;
+import org.apache.nifi.toolkit.cli.impl.command.registry.AbstractNiFiRegistryCommand;
+import org.apache.nifi.toolkit.cli.impl.result.registry.ExtensionRepoArtifactsResult;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Properties;
+
+public class ListBundleArtifacts extends AbstractNiFiRegistryCommand<ExtensionRepoArtifactsResult> {
+
+    public ListBundleArtifacts() {
+        super("list-bundle-artifacts", ExtensionRepoArtifactsResult.class);
+    }
+
+    @Override
+    protected void doInitialize(final Context context) {
+        addOption(CommandOption.BUCKET_NAME.createOption());
+        addOption(CommandOption.EXT_BUNDLE_GROUP.createOption());
+    }
+
+    @Override
+    public String getDescription() {
+        return "List the bundle artifacts in the given bucket and group.";
+    }
+
+    @Override
+    public ExtensionRepoArtifactsResult doExecute(final NiFiRegistryClient client, final Properties properties)
+            throws IOException, NiFiRegistryException, ParseException {
+
+        final String bucketName = getRequiredArg(properties, CommandOption.BUCKET_NAME);
+        final String groupId = getRequiredArg(properties, CommandOption.EXT_BUNDLE_GROUP);
+
+        final ExtensionRepoClient extensionRepoClient = client.getExtensionRepoClient();
+        final List<ExtensionRepoArtifact> artifacts = extensionRepoClient.getArtifacts(bucketName, groupId);
+
+        return new ExtensionRepoArtifactsResult(getResultType(properties), artifacts);
+    }
+}
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/flow/ListFlowVersions.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/extension/ListBundleGroups.java
similarity index 51%
copy from nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/flow/ListFlowVersions.java
copy to nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/extension/ListBundleGroups.java
index a40b04b..0f30f8e 100644
--- a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/flow/ListFlowVersions.java
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/extension/ListBundleGroups.java
@@ -14,49 +14,50 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.nifi.toolkit.cli.impl.command.registry.flow;
+package org.apache.nifi.toolkit.cli.impl.command.registry.extension;
 
 import org.apache.commons.cli.ParseException;
-import org.apache.nifi.registry.client.FlowSnapshotClient;
+import org.apache.nifi.registry.client.ExtensionRepoClient;
 import org.apache.nifi.registry.client.NiFiRegistryClient;
 import org.apache.nifi.registry.client.NiFiRegistryException;
-import org.apache.nifi.registry.flow.VersionedFlowSnapshotMetadata;
+import org.apache.nifi.registry.extension.repo.ExtensionRepoGroup;
 import org.apache.nifi.toolkit.cli.api.Context;
 import org.apache.nifi.toolkit.cli.impl.command.CommandOption;
 import org.apache.nifi.toolkit.cli.impl.command.registry.AbstractNiFiRegistryCommand;
-import org.apache.nifi.toolkit.cli.impl.result.VersionedFlowSnapshotMetadataResult;
+import org.apache.nifi.toolkit.cli.impl.result.registry.ExtensionRepoGroupsResult;
 
 import java.io.IOException;
 import java.util.List;
 import java.util.Properties;
 
 /**
- * Lists the metadata for the versions of a specific flow in a specific bucket.
+ * List the bundle groups in the given bucket.
  */
-public class ListFlowVersions extends AbstractNiFiRegistryCommand<VersionedFlowSnapshotMetadataResult> {
+public class ListBundleGroups extends AbstractNiFiRegistryCommand<ExtensionRepoGroupsResult> {
 
-    public ListFlowVersions() {
-        super("list-flow-versions", VersionedFlowSnapshotMetadataResult.class);
+    public ListBundleGroups() {
+        super("list-bundle-groups", ExtensionRepoGroupsResult.class);
     }
 
     @Override
-    public String getDescription() {
-        return "Lists all of the flows for the given bucket.";
+    protected void doInitialize(final Context context) {
+        addOption(CommandOption.BUCKET_NAME.createOption());
     }
 
     @Override
-    public void doInitialize(final Context context) {
-        addOption(CommandOption.FLOW_ID.createOption());
+    public String getDescription() {
+        return "Lists the bundle groups in the bucket with the given name. If a bucket name contains spaces, the argument must be wrapped in quotes.";
     }
 
     @Override
-    public VersionedFlowSnapshotMetadataResult doExecute(final NiFiRegistryClient client, final Properties properties)
-            throws ParseException, IOException, NiFiRegistryException {
-        final String flow = getRequiredArg(properties, CommandOption.FLOW_ID);
+    public ExtensionRepoGroupsResult doExecute(final NiFiRegistryClient client, final Properties properties)
+            throws IOException, NiFiRegistryException, ParseException {
 
-        final FlowSnapshotClient snapshotClient = client.getFlowSnapshotClient();
-        final List<VersionedFlowSnapshotMetadata> snapshotMetadata = snapshotClient.getSnapshotMetadata(flow);
-        return new VersionedFlowSnapshotMetadataResult(getResultType(properties), snapshotMetadata);
-    }
+        final String bucketName = getRequiredArg(properties, CommandOption.BUCKET_NAME);
 
+        final ExtensionRepoClient extensionRepoClient = client.getExtensionRepoClient();
+        final List<ExtensionRepoGroup> groups = extensionRepoClient.getGroups(bucketName);
+
+        return new ExtensionRepoGroupsResult(getResultType(properties), groups);
+    }
 }
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/extension/ListBundleVersions.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/extension/ListBundleVersions.java
new file mode 100644
index 0000000..716b475
--- /dev/null
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/extension/ListBundleVersions.java
@@ -0,0 +1,67 @@
+/*
+ * 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.nifi.toolkit.cli.impl.command.registry.extension;
+
+import org.apache.commons.cli.ParseException;
+import org.apache.nifi.registry.client.ExtensionRepoClient;
+import org.apache.nifi.registry.client.NiFiRegistryClient;
+import org.apache.nifi.registry.client.NiFiRegistryException;
+import org.apache.nifi.registry.extension.repo.ExtensionRepoVersionSummary;
+import org.apache.nifi.toolkit.cli.api.Context;
+import org.apache.nifi.toolkit.cli.impl.command.CommandOption;
+import org.apache.nifi.toolkit.cli.impl.command.registry.AbstractNiFiRegistryCommand;
+import org.apache.nifi.toolkit.cli.impl.result.registry.ExtensionRepoVersionSummariesResult;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Properties;
+
+/**
+ * Lists the versions of an extension bundle.
+ */
+public class ListBundleVersions extends AbstractNiFiRegistryCommand<ExtensionRepoVersionSummariesResult> {
+
+    public ListBundleVersions() {
+        super("list-bundle-versions", ExtensionRepoVersionSummariesResult.class);
+    }
+
+    @Override
+    public String getDescription() {
+        return "Lists the versions of the specified extension bundle.";
+    }
+
+    @Override
+    public void doInitialize(final Context context) {
+        addOption(CommandOption.BUCKET_NAME.createOption());
+        addOption(CommandOption.EXT_BUNDLE_GROUP.createOption());
+        addOption(CommandOption.EXT_BUNDLE_ARTIFACT.createOption());
+    }
+
+    @Override
+    public ExtensionRepoVersionSummariesResult doExecute(final NiFiRegistryClient client, final Properties properties)
+            throws IOException, NiFiRegistryException, ParseException {
+
+        final String bucketName = getRequiredArg(properties, CommandOption.BUCKET_NAME);
+        final String groupId = getRequiredArg(properties, CommandOption.EXT_BUNDLE_GROUP);
+        final String artifactId = getRequiredArg(properties, CommandOption.EXT_BUNDLE_ARTIFACT);
+
+        final ExtensionRepoClient repoClient = client.getExtensionRepoClient();
+        final List<ExtensionRepoVersionSummary> bundleVersions =  repoClient.getVersions(bucketName, groupId, artifactId);
+        return new ExtensionRepoVersionSummariesResult(getResultType(properties), bundleVersions);
+    }
+
+}
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/bucket/ListBuckets.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/extension/ListExtensionTags.java
similarity index 54%
copy from nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/bucket/ListBuckets.java
copy to nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/extension/ListExtensionTags.java
index 7454cf1..2bc433a 100644
--- a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/bucket/ListBuckets.java
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/extension/ListExtensionTags.java
@@ -14,37 +14,36 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.nifi.toolkit.cli.impl.command.registry.bucket;
+package org.apache.nifi.toolkit.cli.impl.command.registry.extension;
 
-import org.apache.nifi.registry.bucket.Bucket;
+import org.apache.commons.cli.ParseException;
+import org.apache.nifi.registry.client.ExtensionClient;
 import org.apache.nifi.registry.client.NiFiRegistryClient;
 import org.apache.nifi.registry.client.NiFiRegistryException;
+import org.apache.nifi.registry.extension.component.TagCount;
 import org.apache.nifi.toolkit.cli.impl.command.registry.AbstractNiFiRegistryCommand;
-import org.apache.nifi.toolkit.cli.impl.result.BucketsResult;
+import org.apache.nifi.toolkit.cli.impl.result.registry.TagCountResult;
 
 import java.io.IOException;
 import java.util.List;
 import java.util.Properties;
 
-/**
- * Command to list all buckets in the registry instance.
- */
-public class ListBuckets extends AbstractNiFiRegistryCommand<BucketsResult> {
+public class ListExtensionTags extends AbstractNiFiRegistryCommand<TagCountResult> {
 
-    public ListBuckets() {
-        super("list-buckets", BucketsResult.class);
+    public ListExtensionTags() {
+        super("list-extension-tags", TagCountResult.class);
     }
 
     @Override
     public String getDescription() {
-        return "Lists the buckets that the current user has access to.";
+        return "Lists the tag counts for all extensions located in buckets the current user is authorized for.";
     }
 
     @Override
-    public BucketsResult doExecute(final NiFiRegistryClient client, final Properties properties)
-            throws IOException, NiFiRegistryException {
-        final List<Bucket> buckets = client.getBucketClient().getAll();
-        return new BucketsResult(getResultType(properties), buckets);
+    public TagCountResult doExecute(final NiFiRegistryClient client, final Properties properties)
+            throws IOException, NiFiRegistryException, ParseException {
+        final ExtensionClient extensionClient = client.getExtensionClient();
+        final List<TagCount> tagCounts = extensionClient.getTagCounts();
+        return new TagCountResult(getResultType(properties), tagCounts);
     }
-
 }
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/extension/ListExtensions.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/extension/ListExtensions.java
new file mode 100644
index 0000000..8ac20f8
--- /dev/null
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/extension/ListExtensions.java
@@ -0,0 +1,108 @@
+/*
+ * 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.nifi.toolkit.cli.impl.command.registry.extension;
+
+import org.apache.commons.cli.ParseException;
+import org.apache.nifi.registry.client.ExtensionClient;
+import org.apache.nifi.registry.client.NiFiRegistryClient;
+import org.apache.nifi.registry.client.NiFiRegistryException;
+import org.apache.nifi.registry.extension.component.ExtensionFilterParams;
+import org.apache.nifi.registry.extension.component.ExtensionMetadata;
+import org.apache.nifi.registry.extension.component.ExtensionMetadataContainer;
+import org.apache.nifi.registry.extension.component.manifest.ExtensionType;
+import org.apache.nifi.toolkit.cli.api.Context;
+import org.apache.nifi.toolkit.cli.impl.command.CommandOption;
+import org.apache.nifi.toolkit.cli.impl.command.registry.AbstractNiFiRegistryCommand;
+import org.apache.nifi.toolkit.cli.impl.result.registry.ExtensionMetadataResult;
+import org.apache.nifi.util.StringUtils;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Properties;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+public class ListExtensions extends AbstractNiFiRegistryCommand<ExtensionMetadataResult> {
+
+    public ListExtensions() {
+        super("list-extensions", ExtensionMetadataResult.class);
+    }
+
+    @Override
+    protected void doInitialize(Context context) {
+        addOption(CommandOption.EXT_TAGS.createOption());
+        addOption(CommandOption.EXT_TYPE.createOption());
+    }
+
+    @Override
+    public String getDescription() {
+        return "Lists info for extensions, optionally filtering by one or more tags. If specifying tags, multiple tags can " +
+                "be specified with a comma-separated list, and each tag will be OR'd together.";
+    }
+
+    @Override
+    public ExtensionMetadataResult doExecute(final NiFiRegistryClient client, final Properties properties)
+            throws IOException, NiFiRegistryException, ParseException {
+
+        final String tags = getArg(properties, CommandOption.EXT_TAGS);
+        final String extensionType = getArg(properties, CommandOption.EXT_TYPE);
+
+        final ExtensionClient extensionClient = client.getExtensionClient();
+        final ExtensionFilterParams filterParams = getFilterParams(tags, extensionType);
+        final ExtensionMetadataContainer metadataContainer = extensionClient.findExtensions(filterParams);
+
+        final List<ExtensionMetadata> metadataList = new ArrayList<>(metadataContainer.getExtensions());
+        return new ExtensionMetadataResult(getResultType(properties), metadataList);
+    }
+
+    // NOTE: There is a bug in the nifi-registry-client that sends bundleType from filter params using the name() instead of toString().
+    // When that is resolved we can update this command to have an optional argument for bundle type and set it in the filter params.
+
+    private ExtensionFilterParams getFilterParams(final String tagsArg, final String extensionTypeArg) throws NiFiRegistryException {
+        final ExtensionFilterParams.Builder builder = new ExtensionFilterParams.Builder();
+
+        if (!StringUtils.isBlank(tagsArg)) {
+            final String[] splitTags = tagsArg.split("[,]");
+
+            final Set<String> cleanedTags = Arrays.stream(splitTags)
+                    .map(t -> t.trim())
+                    .collect(Collectors.toSet());
+
+            if (cleanedTags.isEmpty()) {
+                throw new IllegalArgumentException("Invalid tag argument");
+            }
+
+            builder.addTags(cleanedTags).build();
+        }
+
+        if (!StringUtils.isEmpty(extensionTypeArg)) {
+            try {
+                final ExtensionType extensionType = ExtensionType.valueOf(extensionTypeArg);
+                builder.extensionType(extensionType);
+            } catch (Exception e) {
+                throw new NiFiRegistryException("Invalid extension type, should be one of "
+                        + ExtensionType.PROCESSOR.toString() + ", "
+                        + ExtensionType.CONTROLLER_SERVICE.toString() + ", or "
+                        + ExtensionType.REPORTING_TASK.toString());
+            }
+        }
+
+        return builder.build();
+    }
+}
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/extension/UploadBundle.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/extension/UploadBundle.java
new file mode 100644
index 0000000..a993fa3
--- /dev/null
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/extension/UploadBundle.java
@@ -0,0 +1,92 @@
+/*
+ * 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.nifi.toolkit.cli.impl.command.registry.extension;
+
+import org.apache.commons.cli.ParseException;
+import org.apache.commons.codec.binary.Hex;
+import org.apache.commons.codec.digest.DigestUtils;
+import org.apache.nifi.registry.client.BundleVersionClient;
+import org.apache.nifi.registry.client.NiFiRegistryClient;
+import org.apache.nifi.registry.client.NiFiRegistryException;
+import org.apache.nifi.registry.extension.bundle.BundleType;
+import org.apache.nifi.registry.extension.bundle.BundleVersion;
+import org.apache.nifi.toolkit.cli.api.Context;
+import org.apache.nifi.toolkit.cli.impl.command.CommandOption;
+import org.apache.nifi.toolkit.cli.impl.command.registry.AbstractNiFiRegistryCommand;
+import org.apache.nifi.toolkit.cli.impl.result.registry.BundleVersionResult;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Properties;
+
+/**
+ * Uploads an extension bundle binary to the registry.
+ */
+public class UploadBundle extends AbstractNiFiRegistryCommand<BundleVersionResult> {
+
+    public UploadBundle() {
+        super("upload-bundle", BundleVersionResult.class);
+    }
+
+    @Override
+    public String getDescription() {
+        return "Uploads an extension bundle binary to the specified bucket in the registry.";
+    }
+
+    @Override
+    public void doInitialize(final Context context) {
+        addOption(CommandOption.BUCKET_ID.createOption());
+        addOption(CommandOption.EXT_BUNDLE_TYPE.createOption());
+        addOption(CommandOption.EXT_BUNDLE_FILE.createOption());
+        addOption(CommandOption.SKIP_SHA_256.createOption());
+    }
+
+    @Override
+    public BundleVersionResult doExecute(final NiFiRegistryClient client, final Properties properties)
+            throws IOException, NiFiRegistryException, ParseException {
+        final String bucketId = getRequiredArg(properties, CommandOption.BUCKET_ID);
+
+        final BundleType bundleType;
+        try {
+            bundleType = BundleType.fromString(getRequiredArg(properties, CommandOption.EXT_BUNDLE_TYPE));
+        } catch (Exception e) {
+            throw new NiFiRegistryException("Invalid bundle type, should be one of "
+                    + BundleType.NIFI_NAR.toString() + " or " + BundleType.MINIFI_CPP.toString());
+        }
+
+        final File bundleFile = new File(getRequiredArg(properties, CommandOption.EXT_BUNDLE_FILE));
+        final BundleVersionClient bundleVersionClient = client.getBundleVersionClient();
+        final boolean skipSha256 = properties.containsKey(CommandOption.SKIP_SHA_256.getLongName());
+
+        // calculate the sha256 unless we were told to skip it
+        String sha256 = null;
+        if (!skipSha256) {
+            try (final InputStream inputStream = new FileInputStream(bundleFile)) {
+                sha256 = Hex.encodeHexString(DigestUtils.sha256(inputStream));
+            }
+        }
+
+        // upload the bundle...
+        try (final InputStream bundleInputStream = new FileInputStream(bundleFile)) {
+            final BundleVersion createdBundleVersion = bundleVersionClient.create(bucketId, bundleType, bundleInputStream, sha256);
+            return new BundleVersionResult(getResultType(properties), createdBundleVersion);
+        }
+    }
+
+}
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/extension/UploadBundles.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/extension/UploadBundles.java
new file mode 100644
index 0000000..b17eedd
--- /dev/null
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/extension/UploadBundles.java
@@ -0,0 +1,155 @@
+/*
+ * 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.nifi.toolkit.cli.impl.command.registry.extension;
+
+import org.apache.commons.cli.ParseException;
+import org.apache.commons.codec.binary.Hex;
+import org.apache.commons.codec.digest.DigestUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.nifi.registry.client.BundleVersionClient;
+import org.apache.nifi.registry.client.NiFiRegistryClient;
+import org.apache.nifi.registry.client.NiFiRegistryException;
+import org.apache.nifi.registry.extension.bundle.BundleType;
+import org.apache.nifi.registry.extension.bundle.BundleVersion;
+import org.apache.nifi.toolkit.cli.api.Context;
+import org.apache.nifi.toolkit.cli.impl.command.CommandOption;
+import org.apache.nifi.toolkit.cli.impl.command.registry.AbstractNiFiRegistryCommand;
+import org.apache.nifi.toolkit.cli.impl.result.StringResult;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Properties;
+import java.util.concurrent.atomic.AtomicInteger;
+
+public class UploadBundles extends AbstractNiFiRegistryCommand<StringResult> {
+
+    public UploadBundles() {
+        super("upload-bundles", StringResult.class);
+    }
+
+    @Override
+    public String getDescription() {
+        return "Performs a bulk upload of multiple bundles to the specified bucket in the registry. This command will look for " +
+                "files in the specified directory, and if recurse (-r) is specified then it will search child directories recursively. " +
+                "If fileExtension is specified then it will only consider files that have the specified extension, such as '.nar'";
+    }
+
+    @Override
+    public void doInitialize(final Context context) {
+        addOption(CommandOption.BUCKET_ID.createOption());
+        addOption(CommandOption.EXT_BUNDLE_TYPE.createOption());
+        addOption(CommandOption.EXT_BUNDLE_DIR.createOption());
+        addOption(CommandOption.FILE_EXTENSION.createOption());
+        addOption(CommandOption.RECURSIVE.createOption());
+        addOption(CommandOption.SKIP_SHA_256.createOption());
+    }
+
+    @Override
+    public StringResult doExecute(final NiFiRegistryClient client, final Properties properties)
+            throws IOException, NiFiRegistryException, ParseException {
+        final String bucketId = getRequiredArg(properties, CommandOption.BUCKET_ID);
+        final String bundleDir = getRequiredArg(properties, CommandOption.EXT_BUNDLE_DIR);
+        final String fileExtension = getArg(properties, CommandOption.FILE_EXTENSION);
+        final boolean recursive = properties.containsKey(CommandOption.RECURSIVE);
+        final boolean skipSha256 = properties.containsKey(CommandOption.SKIP_SHA_256.getLongName());
+        final boolean verbose = isVerbose(properties);
+
+        final BundleType bundleType;
+        try {
+            bundleType = BundleType.fromString(getRequiredArg(properties, CommandOption.EXT_BUNDLE_TYPE));
+        } catch (IllegalArgumentException e) {
+            throw new NiFiRegistryException("Invalid bundle type, should be one of "
+                    + BundleType.NIFI_NAR.toString() + " or " + BundleType.MINIFI_CPP.toString());
+        }
+
+        final BundleVersionClient bundleVersionClient = client.getBundleVersionClient();
+
+        final File startDir = new File(bundleDir);
+        if (!startDir.exists()) {
+            throw new NiFiRegistryException("The specified directory does not exist: " + startDir.getAbsolutePath());
+        }
+        if (!startDir.isDirectory()) {
+            throw new NiFiRegistryException("The specified directory is not a directory: " + startDir.getAbsolutePath());
+        }
+
+        final AtomicInteger counter = new AtomicInteger(0);
+        uploadBundle(bundleVersionClient, bucketId, bundleType, startDir, fileExtension, recursive, skipSha256, verbose, counter);
+
+        return new StringResult("Uploaded " + counter.get() + " bundles successfully", getContext().isInteractive());
+    }
+
+    private void uploadBundle(final BundleVersionClient bundleVersionClient, final String bucketId, final BundleType bundleType,
+                              final File directory, final String fileExtension, final boolean recurse, final boolean skipSha256,
+                              final boolean verbose, final AtomicInteger counter) {
+
+        for (final File file : directory.listFiles()) {
+            if (file.isDirectory() && recurse) {
+                uploadBundle(bundleVersionClient, bucketId, bundleType, file, fileExtension, recurse, skipSha256, verbose, counter);
+            } else {
+                // if a file extension was provided then skip anything that doesn't end in the extension
+                if (!StringUtils.isBlank(fileExtension) && !file.getName().endsWith(fileExtension)) {
+                    continue;
+                }
+
+                // calculate the sha256 unless we were told to skip it
+                String sha256 = null;
+                if (!skipSha256) {
+                    sha256 = calculateSha256(file, verbose);
+                    // if we weren't skipping sha256 and we got null, then an error happened so don't upload the bundle
+                    if (sha256 == null) {
+                        continue;
+                    }
+                }
+
+                // upload the binary bundle
+                try (final InputStream bundleInputStream = new FileInputStream(file)) {
+                    final BundleVersion createdVersion = bundleVersionClient.create(bucketId, bundleType, bundleInputStream, sha256);
+                    counter.incrementAndGet();
+
+                    if (getContext().isInteractive()) {
+                        println("Successfully uploaded "
+                                + createdVersion.getBundle().getGroupId() + "::"
+                                + createdVersion.getBundle().getArtifactId() + "::"
+                                + createdVersion.getVersionMetadata().getVersion());
+                    }
+
+                } catch (Exception e) {
+                    println("Error uploading bundle from " + file.getAbsolutePath());
+                    if (verbose) {
+                        e.printStackTrace(getContext().getOutput());
+                    }
+                }
+            }
+        }
+
+    }
+
+    private String calculateSha256(final File file, final boolean verbose) {
+        try (final InputStream inputStream = new FileInputStream(file)) {
+            return Hex.encodeHexString(DigestUtils.sha256(inputStream));
+        } catch (Exception e) {
+            println("Error calculating SHA-256 for " + file.getAbsolutePath());
+            if (verbose) {
+                e.printStackTrace(getContext().getOutput());
+            }
+            return null;
+        }
+    }
+
+}
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/flow/ExportFlowVersion.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/flow/ExportFlowVersion.java
index 10b2b45..78fab7b 100644
--- a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/flow/ExportFlowVersion.java
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/flow/ExportFlowVersion.java
@@ -23,7 +23,7 @@ import org.apache.nifi.registry.flow.VersionedFlowSnapshot;
 import org.apache.nifi.toolkit.cli.api.Context;
 import org.apache.nifi.toolkit.cli.impl.command.CommandOption;
 import org.apache.nifi.toolkit.cli.impl.command.registry.AbstractNiFiRegistryCommand;
-import org.apache.nifi.toolkit.cli.impl.result.VersionedFlowSnapshotResult;
+import org.apache.nifi.toolkit.cli.impl.result.registry.VersionedFlowSnapshotResult;
 
 import java.io.IOException;
 import java.util.Properties;
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/flow/ListFlowVersions.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/flow/ListFlowVersions.java
index a40b04b..4c3cc4f 100644
--- a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/flow/ListFlowVersions.java
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/flow/ListFlowVersions.java
@@ -24,7 +24,7 @@ import org.apache.nifi.registry.flow.VersionedFlowSnapshotMetadata;
 import org.apache.nifi.toolkit.cli.api.Context;
 import org.apache.nifi.toolkit.cli.impl.command.CommandOption;
 import org.apache.nifi.toolkit.cli.impl.command.registry.AbstractNiFiRegistryCommand;
-import org.apache.nifi.toolkit.cli.impl.result.VersionedFlowSnapshotMetadataResult;
+import org.apache.nifi.toolkit.cli.impl.result.registry.VersionedFlowSnapshotMetadataResult;
 
 import java.io.IOException;
 import java.util.List;
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/flow/ListFlows.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/flow/ListFlows.java
index 22db2ff..edd702d 100644
--- a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/flow/ListFlows.java
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/flow/ListFlows.java
@@ -24,7 +24,7 @@ import org.apache.nifi.registry.flow.VersionedFlow;
 import org.apache.nifi.toolkit.cli.api.Context;
 import org.apache.nifi.toolkit.cli.impl.command.CommandOption;
 import org.apache.nifi.toolkit.cli.impl.command.registry.AbstractNiFiRegistryCommand;
-import org.apache.nifi.toolkit.cli.impl.result.VersionedFlowsResult;
+import org.apache.nifi.toolkit.cli.impl.result.registry.VersionedFlowsResult;
 
 import java.io.IOException;
 import java.util.List;
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/user/CurrentUser.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/user/CurrentUser.java
index 6b7896e..a8600ae 100644
--- a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/user/CurrentUser.java
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/user/CurrentUser.java
@@ -20,7 +20,7 @@ import org.apache.nifi.registry.client.NiFiRegistryClient;
 import org.apache.nifi.registry.client.NiFiRegistryException;
 import org.apache.nifi.registry.client.UserClient;
 import org.apache.nifi.toolkit.cli.impl.command.registry.AbstractNiFiRegistryCommand;
-import org.apache.nifi.toolkit.cli.impl.result.CurrentUserResult;
+import org.apache.nifi.toolkit.cli.impl.result.nifi.CurrentUserResult;
 
 import java.io.IOException;
 import java.util.Properties;
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/AccessPolicyResult.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/nifi/AccessPolicyResult.java
similarity index 95%
rename from nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/AccessPolicyResult.java
rename to nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/nifi/AccessPolicyResult.java
index 6d74425..c66e4d1 100644
--- a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/AccessPolicyResult.java
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/nifi/AccessPolicyResult.java
@@ -14,10 +14,11 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.nifi.toolkit.cli.impl.result;
+package org.apache.nifi.toolkit.cli.impl.result.nifi;
 
 import org.apache.commons.lang3.Validate;
 import org.apache.nifi.toolkit.cli.api.ResultType;
+import org.apache.nifi.toolkit.cli.impl.result.AbstractWritableResult;
 import org.apache.nifi.web.api.dto.AccessPolicyDTO;
 import org.apache.nifi.web.api.entity.AccessPolicyEntity;
 import org.apache.nifi.web.api.entity.TenantEntity;
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/ClusterSummaryEntityResult.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/nifi/ClusterSummaryEntityResult.java
similarity index 94%
rename from nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/ClusterSummaryEntityResult.java
rename to nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/nifi/ClusterSummaryEntityResult.java
index 53d9601..53ea737 100644
--- a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/ClusterSummaryEntityResult.java
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/nifi/ClusterSummaryEntityResult.java
@@ -14,10 +14,11 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.nifi.toolkit.cli.impl.result;
+package org.apache.nifi.toolkit.cli.impl.result.nifi;
 
 import org.apache.commons.lang3.Validate;
 import org.apache.nifi.toolkit.cli.api.ResultType;
+import org.apache.nifi.toolkit.cli.impl.result.AbstractWritableResult;
 import org.apache.nifi.web.api.entity.ClusteSummaryEntity;
 
 import java.io.PrintStream;
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/ControllerServiceResult.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/nifi/ControllerServiceResult.java
similarity index 94%
rename from nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/ControllerServiceResult.java
rename to nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/nifi/ControllerServiceResult.java
index e883ca2..444f391 100644
--- a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/ControllerServiceResult.java
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/nifi/ControllerServiceResult.java
@@ -14,10 +14,11 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.nifi.toolkit.cli.impl.result;
+package org.apache.nifi.toolkit.cli.impl.result.nifi;
 
 import org.apache.commons.lang3.Validate;
 import org.apache.nifi.toolkit.cli.api.ResultType;
+import org.apache.nifi.toolkit.cli.impl.result.AbstractWritableResult;
 import org.apache.nifi.web.api.dto.BundleDTO;
 import org.apache.nifi.web.api.dto.ControllerServiceDTO;
 import org.apache.nifi.web.api.entity.ControllerServiceEntity;
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/ControllerServicesResult.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/nifi/ControllerServicesResult.java
similarity index 96%
rename from nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/ControllerServicesResult.java
rename to nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/nifi/ControllerServicesResult.java
index e75dcbb..559db93 100644
--- a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/ControllerServicesResult.java
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/nifi/ControllerServicesResult.java
@@ -14,10 +14,11 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.nifi.toolkit.cli.impl.result;
+package org.apache.nifi.toolkit.cli.impl.result.nifi;
 
 import org.apache.commons.lang3.Validate;
 import org.apache.nifi.toolkit.cli.api.ResultType;
+import org.apache.nifi.toolkit.cli.impl.result.AbstractWritableResult;
 import org.apache.nifi.toolkit.cli.impl.result.writer.DynamicTableWriter;
 import org.apache.nifi.toolkit.cli.impl.result.writer.Table;
 import org.apache.nifi.toolkit.cli.impl.result.writer.TableWriter;
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/CurrentUserEntityResult.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/nifi/CurrentUserEntityResult.java
similarity index 93%
rename from nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/CurrentUserEntityResult.java
rename to nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/nifi/CurrentUserEntityResult.java
index 853535f..71fee66 100644
--- a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/CurrentUserEntityResult.java
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/nifi/CurrentUserEntityResult.java
@@ -14,10 +14,11 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.nifi.toolkit.cli.impl.result;
+package org.apache.nifi.toolkit.cli.impl.result.nifi;
 
 import org.apache.commons.lang3.Validate;
 import org.apache.nifi.toolkit.cli.api.ResultType;
+import org.apache.nifi.toolkit.cli.impl.result.AbstractWritableResult;
 import org.apache.nifi.web.api.entity.CurrentUserEntity;
 
 import java.io.PrintStream;
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/CurrentUserResult.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/nifi/CurrentUserResult.java
similarity index 92%
rename from nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/CurrentUserResult.java
rename to nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/nifi/CurrentUserResult.java
index 11100ff..df7b3e7 100644
--- a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/CurrentUserResult.java
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/nifi/CurrentUserResult.java
@@ -14,11 +14,12 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.nifi.toolkit.cli.impl.result;
+package org.apache.nifi.toolkit.cli.impl.result.nifi;
 
 import org.apache.commons.lang3.Validate;
 import org.apache.nifi.registry.authorization.CurrentUser;
 import org.apache.nifi.toolkit.cli.api.ResultType;
+import org.apache.nifi.toolkit.cli.impl.result.AbstractWritableResult;
 
 import java.io.PrintStream;
 
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/NodeResult.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/nifi/NodeResult.java
similarity index 93%
rename from nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/NodeResult.java
rename to nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/nifi/NodeResult.java
index 3e1efdf..004025b 100644
--- a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/NodeResult.java
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/nifi/NodeResult.java
@@ -14,10 +14,11 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.nifi.toolkit.cli.impl.result;
+package org.apache.nifi.toolkit.cli.impl.result.nifi;
 
 import org.apache.commons.lang3.Validate;
 import org.apache.nifi.toolkit.cli.api.ResultType;
+import org.apache.nifi.toolkit.cli.impl.result.AbstractWritableResult;
 import org.apache.nifi.web.api.dto.NodeDTO;
 import org.apache.nifi.web.api.entity.NodeEntity;
 
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/NodesResult.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/nifi/NodesResult.java
similarity index 95%
copy from nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/NodesResult.java
copy to nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/nifi/NodesResult.java
index daab27f..e997dd3 100644
--- a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/NodesResult.java
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/nifi/NodesResult.java
@@ -14,10 +14,11 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.nifi.toolkit.cli.impl.result;
+package org.apache.nifi.toolkit.cli.impl.result.nifi;
 
 import org.apache.commons.lang3.Validate;
 import org.apache.nifi.toolkit.cli.api.ResultType;
+import org.apache.nifi.toolkit.cli.impl.result.AbstractWritableResult;
 import org.apache.nifi.toolkit.cli.impl.result.writer.DynamicTableWriter;
 import org.apache.nifi.toolkit.cli.impl.result.writer.Table;
 import org.apache.nifi.toolkit.cli.impl.result.writer.TableWriter;
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/ProcessGroupResult.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/nifi/ProcessGroupResult.java
similarity index 93%
copy from nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/ProcessGroupResult.java
copy to nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/nifi/ProcessGroupResult.java
index ae2f105..8def19c 100644
--- a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/ProcessGroupResult.java
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/nifi/ProcessGroupResult.java
@@ -14,10 +14,11 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.nifi.toolkit.cli.impl.result;
+package org.apache.nifi.toolkit.cli.impl.result.nifi;
 
 import org.apache.commons.lang3.Validate;
 import org.apache.nifi.toolkit.cli.api.ResultType;
+import org.apache.nifi.toolkit.cli.impl.result.AbstractWritableResult;
 import org.apache.nifi.web.api.entity.ProcessGroupEntity;
 
 import java.io.IOException;
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/ProcessGroupsResult.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/nifi/ProcessGroupsResult.java
similarity index 97%
rename from nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/ProcessGroupsResult.java
rename to nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/nifi/ProcessGroupsResult.java
index 05ac056..8d27513 100644
--- a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/ProcessGroupsResult.java
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/nifi/ProcessGroupsResult.java
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.nifi.toolkit.cli.impl.result;
+package org.apache.nifi.toolkit.cli.impl.result.nifi;
 
 import org.apache.commons.lang3.Validate;
 import org.apache.nifi.toolkit.cli.api.Context;
@@ -23,6 +23,7 @@ import org.apache.nifi.toolkit.cli.api.Referenceable;
 import org.apache.nifi.toolkit.cli.api.ResolvedReference;
 import org.apache.nifi.toolkit.cli.api.ResultType;
 import org.apache.nifi.toolkit.cli.impl.command.CommandOption;
+import org.apache.nifi.toolkit.cli.impl.result.AbstractWritableResult;
 import org.apache.nifi.toolkit.cli.impl.result.writer.DynamicTableWriter;
 import org.apache.nifi.toolkit.cli.impl.result.writer.Table;
 import org.apache.nifi.toolkit.cli.impl.result.writer.TableWriter;
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/RegistryClientIDResult.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/nifi/RegistryClientIDResult.java
similarity index 92%
rename from nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/RegistryClientIDResult.java
rename to nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/nifi/RegistryClientIDResult.java
index e221318..2f0b106 100644
--- a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/RegistryClientIDResult.java
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/nifi/RegistryClientIDResult.java
@@ -14,10 +14,11 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.nifi.toolkit.cli.impl.result;
+package org.apache.nifi.toolkit.cli.impl.result.nifi;
 
 import org.apache.commons.lang3.Validate;
 import org.apache.nifi.toolkit.cli.api.ResultType;
+import org.apache.nifi.toolkit.cli.impl.result.AbstractWritableResult;
 import org.apache.nifi.web.api.dto.RegistryDTO;
 
 import java.io.PrintStream;
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/RegistryClientsResult.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/nifi/RegistryClientsResult.java
similarity index 95%
rename from nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/RegistryClientsResult.java
rename to nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/nifi/RegistryClientsResult.java
index 7ca9122..8654fdf 100644
--- a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/RegistryClientsResult.java
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/nifi/RegistryClientsResult.java
@@ -14,10 +14,11 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.nifi.toolkit.cli.impl.result;
+package org.apache.nifi.toolkit.cli.impl.result.nifi;
 
 import org.apache.commons.lang3.Validate;
 import org.apache.nifi.toolkit.cli.api.ResultType;
+import org.apache.nifi.toolkit.cli.impl.result.AbstractWritableResult;
 import org.apache.nifi.toolkit.cli.impl.result.writer.DynamicTableWriter;
 import org.apache.nifi.toolkit.cli.impl.result.writer.Table;
 import org.apache.nifi.toolkit.cli.impl.result.writer.TableWriter;
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/ReportingTaskResult.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/nifi/ReportingTaskResult.java
similarity index 94%
rename from nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/ReportingTaskResult.java
rename to nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/nifi/ReportingTaskResult.java
index fe67a36..324b95f 100644
--- a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/ReportingTaskResult.java
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/nifi/ReportingTaskResult.java
@@ -15,10 +15,11 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.nifi.toolkit.cli.impl.result;
+package org.apache.nifi.toolkit.cli.impl.result.nifi;
 
 import org.apache.commons.lang3.Validate;
 import org.apache.nifi.toolkit.cli.api.ResultType;
+import org.apache.nifi.toolkit.cli.impl.result.AbstractWritableResult;
 import org.apache.nifi.web.api.dto.BundleDTO;
 import org.apache.nifi.web.api.dto.ReportingTaskDTO;
 import org.apache.nifi.web.api.entity.ReportingTaskEntity;
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/ReportingTasksResult.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/nifi/ReportingTasksResult.java
similarity index 96%
rename from nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/ReportingTasksResult.java
rename to nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/nifi/ReportingTasksResult.java
index cf80a7a..abb4147 100644
--- a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/ReportingTasksResult.java
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/nifi/ReportingTasksResult.java
@@ -14,10 +14,11 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.nifi.toolkit.cli.impl.result;
+package org.apache.nifi.toolkit.cli.impl.result.nifi;
 
 import org.apache.commons.lang3.Validate;
 import org.apache.nifi.toolkit.cli.api.ResultType;
+import org.apache.nifi.toolkit.cli.impl.result.AbstractWritableResult;
 import org.apache.nifi.toolkit.cli.impl.result.writer.DynamicTableWriter;
 import org.apache.nifi.toolkit.cli.impl.result.writer.Table;
 import org.apache.nifi.toolkit.cli.impl.result.writer.TableWriter;
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/TemplateResult.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/nifi/TemplateResult.java
similarity index 97%
rename from nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/TemplateResult.java
rename to nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/nifi/TemplateResult.java
index 65be1c8..866058a 100644
--- a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/TemplateResult.java
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/nifi/TemplateResult.java
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.nifi.toolkit.cli.impl.result;
+package org.apache.nifi.toolkit.cli.impl.result.nifi;
 
 import org.apache.commons.lang3.Validate;
 import org.apache.nifi.persistence.TemplateSerializer;
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/TemplatesResult.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/nifi/TemplatesResult.java
similarity index 96%
rename from nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/TemplatesResult.java
rename to nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/nifi/TemplatesResult.java
index 1c1c1e4..973b61c 100644
--- a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/TemplatesResult.java
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/nifi/TemplatesResult.java
@@ -15,10 +15,11 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.nifi.toolkit.cli.impl.result;
+package org.apache.nifi.toolkit.cli.impl.result.nifi;
 
 import org.apache.commons.lang3.Validate;
 import org.apache.nifi.toolkit.cli.api.ResultType;
+import org.apache.nifi.toolkit.cli.impl.result.AbstractWritableResult;
 import org.apache.nifi.toolkit.cli.impl.result.writer.DynamicTableWriter;
 import org.apache.nifi.toolkit.cli.impl.result.writer.Table;
 import org.apache.nifi.toolkit.cli.impl.result.writer.TableWriter;
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/UserGroupsResult.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/nifi/UserGroupsResult.java
similarity index 96%
rename from nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/UserGroupsResult.java
rename to nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/nifi/UserGroupsResult.java
index 71abc29..0a1a8c5 100644
--- a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/UserGroupsResult.java
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/nifi/UserGroupsResult.java
@@ -14,10 +14,11 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.nifi.toolkit.cli.impl.result;
+package org.apache.nifi.toolkit.cli.impl.result.nifi;
 
 import org.apache.commons.lang3.Validate;
 import org.apache.nifi.toolkit.cli.api.ResultType;
+import org.apache.nifi.toolkit.cli.impl.result.AbstractWritableResult;
 import org.apache.nifi.toolkit.cli.impl.result.writer.DynamicTableWriter;
 import org.apache.nifi.toolkit.cli.impl.result.writer.Table;
 import org.apache.nifi.toolkit.cli.impl.result.writer.TableWriter;
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/UsersResult.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/nifi/UsersResult.java
similarity index 96%
copy from nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/UsersResult.java
copy to nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/nifi/UsersResult.java
index 9aee5b5..74ad327 100644
--- a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/UsersResult.java
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/nifi/UsersResult.java
@@ -14,10 +14,11 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.nifi.toolkit.cli.impl.result;
+package org.apache.nifi.toolkit.cli.impl.result.nifi;
 
 import org.apache.commons.lang3.Validate;
 import org.apache.nifi.toolkit.cli.api.ResultType;
+import org.apache.nifi.toolkit.cli.impl.result.AbstractWritableResult;
 import org.apache.nifi.toolkit.cli.impl.result.writer.DynamicTableWriter;
 import org.apache.nifi.toolkit.cli.impl.result.writer.Table;
 import org.apache.nifi.toolkit.cli.impl.result.writer.TableWriter;
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/VariableRegistryResult.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/nifi/VariableRegistryResult.java
similarity index 96%
rename from nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/VariableRegistryResult.java
rename to nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/nifi/VariableRegistryResult.java
index 237f2c4..ec8430b 100644
--- a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/VariableRegistryResult.java
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/nifi/VariableRegistryResult.java
@@ -14,10 +14,11 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.nifi.toolkit.cli.impl.result;
+package org.apache.nifi.toolkit.cli.impl.result.nifi;
 
 import org.apache.commons.lang3.Validate;
 import org.apache.nifi.toolkit.cli.api.ResultType;
+import org.apache.nifi.toolkit.cli.impl.result.AbstractWritableResult;
 import org.apache.nifi.toolkit.cli.impl.result.writer.DynamicTableWriter;
 import org.apache.nifi.toolkit.cli.impl.result.writer.Table;
 import org.apache.nifi.toolkit.cli.impl.result.writer.TableWriter;
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/VersionControlInfoResult.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/nifi/VersionControlInfoResult.java
similarity index 95%
rename from nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/VersionControlInfoResult.java
rename to nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/nifi/VersionControlInfoResult.java
index 46adef6..7566538 100644
--- a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/VersionControlInfoResult.java
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/nifi/VersionControlInfoResult.java
@@ -14,10 +14,11 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.nifi.toolkit.cli.impl.result;
+package org.apache.nifi.toolkit.cli.impl.result.nifi;
 
 import org.apache.commons.lang3.Validate;
 import org.apache.nifi.toolkit.cli.api.ResultType;
+import org.apache.nifi.toolkit.cli.impl.result.AbstractWritableResult;
 import org.apache.nifi.toolkit.cli.impl.result.writer.DynamicTableWriter;
 import org.apache.nifi.toolkit.cli.impl.result.writer.Table;
 import org.apache.nifi.toolkit.cli.impl.result.writer.TableWriter;
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/BucketsResult.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/registry/BucketsResult.java
similarity index 96%
rename from nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/BucketsResult.java
rename to nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/registry/BucketsResult.java
index 8fbd71f..6f8eac7 100644
--- a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/BucketsResult.java
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/registry/BucketsResult.java
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.nifi.toolkit.cli.impl.result;
+package org.apache.nifi.toolkit.cli.impl.result.registry;
 
 import org.apache.commons.lang3.Validate;
 import org.apache.nifi.registry.bucket.Bucket;
@@ -24,6 +24,7 @@ import org.apache.nifi.toolkit.cli.api.Referenceable;
 import org.apache.nifi.toolkit.cli.api.ResolvedReference;
 import org.apache.nifi.toolkit.cli.api.ResultType;
 import org.apache.nifi.toolkit.cli.impl.command.CommandOption;
+import org.apache.nifi.toolkit.cli.impl.result.AbstractWritableResult;
 import org.apache.nifi.toolkit.cli.impl.result.writer.DynamicTableWriter;
 import org.apache.nifi.toolkit.cli.impl.result.writer.Table;
 import org.apache.nifi.toolkit.cli.impl.result.writer.TableWriter;
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/ProcessGroupResult.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/registry/BundleVersionResult.java
similarity index 53%
rename from nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/ProcessGroupResult.java
rename to nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/registry/BundleVersionResult.java
index ae2f105..f5733a7 100644
--- a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/ProcessGroupResult.java
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/registry/BundleVersionResult.java
@@ -14,37 +14,37 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.nifi.toolkit.cli.impl.result;
+package org.apache.nifi.toolkit.cli.impl.result.registry;
 
-import org.apache.commons.lang3.Validate;
+import org.apache.nifi.registry.extension.bundle.BundleVersion;
 import org.apache.nifi.toolkit.cli.api.ResultType;
-import org.apache.nifi.web.api.entity.ProcessGroupEntity;
+import org.apache.nifi.toolkit.cli.impl.result.AbstractWritableResult;
 
 import java.io.IOException;
 import java.io.PrintStream;
-import java.util.Collections;
 
-public class ProcessGroupResult extends AbstractWritableResult<ProcessGroupEntity> {
+public class BundleVersionResult extends AbstractWritableResult<BundleVersion> {
 
-    private final ProcessGroupEntity entity;
+    private BundleVersion extensionBundleVersion;
 
-    public ProcessGroupResult(final ResultType resultType, final ProcessGroupEntity entity) {
+    public BundleVersionResult(final ResultType resultType, final BundleVersion extensionBundleVersion) {
         super(resultType);
-        this.entity = entity;
-        Validate.notNull(entity);
+        this.extensionBundleVersion = extensionBundleVersion;
     }
 
     @Override
-    public ProcessGroupEntity getResult() {
-        return entity;
+    public BundleVersion getResult() {
+        return extensionBundleVersion;
     }
 
     @Override
     protected void writeSimpleResult(final PrintStream output) throws IOException {
-        final ProcessGroupsResult result = new ProcessGroupsResult(
-                ResultType.SIMPLE,
-                Collections.singletonList(entity.getComponent())
-        );
-        result.writeSimpleResult(output);
+        final String artifactId = extensionBundleVersion.getBundle().getArtifactId();
+        final String groupId = extensionBundleVersion.getBundle().getGroupId();
+        final String version = extensionBundleVersion.getVersionMetadata().getVersion();
+
+        final String bundleCoordinate = groupId + "::" + artifactId + "::" + version;
+        output.println(bundleCoordinate);
     }
+
 }
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/registry/ExtensionMetadataResult.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/registry/ExtensionMetadataResult.java
new file mode 100644
index 0000000..2c0cd4f
--- /dev/null
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/registry/ExtensionMetadataResult.java
@@ -0,0 +1,74 @@
+/*
+ * 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.nifi.toolkit.cli.impl.result.registry;
+
+import org.apache.commons.lang3.Validate;
+import org.apache.nifi.registry.extension.component.ExtensionMetadata;
+import org.apache.nifi.toolkit.cli.api.ResultType;
+import org.apache.nifi.toolkit.cli.impl.result.AbstractWritableResult;
+import org.apache.nifi.toolkit.cli.impl.result.writer.DynamicTableWriter;
+import org.apache.nifi.toolkit.cli.impl.result.writer.Table;
+import org.apache.nifi.toolkit.cli.impl.result.writer.TableWriter;
+
+import java.io.IOException;
+import java.io.PrintStream;
+import java.util.List;
+
+public class ExtensionMetadataResult extends AbstractWritableResult<List<ExtensionMetadata>> {
+
+    private List<ExtensionMetadata> extensionMetadata;
+
+    public ExtensionMetadataResult(final ResultType resultType, final List<ExtensionMetadata> extensionMetadata) {
+        super(resultType);
+        this.extensionMetadata = extensionMetadata;
+        Validate.notNull(this.extensionMetadata);
+    }
+
+    @Override
+    protected void writeSimpleResult(final PrintStream output) throws IOException {
+        if (extensionMetadata.isEmpty()) {
+            return;
+        }
+
+        final Table table = new Table.Builder()
+                .column("Name", 20, 100, false)
+                .column("Bucket", 20, 200, false)
+                .column("Group", 20, 200, false)
+                .column("Artifact", 20, 200, false)
+                .column("Version", 8, 40, false)
+                .build();
+
+        for (int i = 0; i < extensionMetadata.size(); ++i) {
+            final ExtensionMetadata metadata = extensionMetadata.get(i);
+            table.addRow(
+                    metadata.getDisplayName(),
+                    metadata.getBundleInfo().getBucketName(),
+                    metadata.getBundleInfo().getGroupId(),
+                    metadata.getBundleInfo().getArtifactId(),
+                    metadata.getBundleInfo().getVersion()
+            );
+        }
+
+        final TableWriter tableWriter = new DynamicTableWriter();
+        tableWriter.write(table, output);
+    }
+
+    @Override
+    public List<ExtensionMetadata> getResult() {
+        return extensionMetadata;
+    }
+}
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/UsersResult.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/registry/ExtensionRepoArtifactsResult.java
similarity index 51%
rename from nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/UsersResult.java
rename to nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/registry/ExtensionRepoArtifactsResult.java
index 9aee5b5..2bad238 100644
--- a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/UsersResult.java
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/registry/ExtensionRepoArtifactsResult.java
@@ -14,67 +14,55 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.nifi.toolkit.cli.impl.result;
+package org.apache.nifi.toolkit.cli.impl.result.registry;
 
 import org.apache.commons.lang3.Validate;
+import org.apache.nifi.registry.extension.repo.ExtensionRepoArtifact;
 import org.apache.nifi.toolkit.cli.api.ResultType;
+import org.apache.nifi.toolkit.cli.impl.result.AbstractWritableResult;
 import org.apache.nifi.toolkit.cli.impl.result.writer.DynamicTableWriter;
 import org.apache.nifi.toolkit.cli.impl.result.writer.Table;
 import org.apache.nifi.toolkit.cli.impl.result.writer.TableWriter;
-import org.apache.nifi.web.api.dto.UserDTO;
-import org.apache.nifi.web.api.entity.UserEntity;
-import org.apache.nifi.web.api.entity.UsersEntity;
 
 import java.io.IOException;
 import java.io.PrintStream;
-import java.util.Collection;
-import java.util.Collections;
 import java.util.Comparator;
 import java.util.List;
-import java.util.stream.Collectors;
 
 /**
- * Result for UsersEntity.
+ * Result for list of bundle artifacts.
  */
-public class UsersResult extends AbstractWritableResult<UsersEntity> {
+public class ExtensionRepoArtifactsResult extends AbstractWritableResult<List<ExtensionRepoArtifact>> {
 
-    private final UsersEntity usersEntity;
+    private final List<ExtensionRepoArtifact> bundleArtifacts;
 
-    public UsersResult(final ResultType resultType, final UsersEntity usersEntity) {
+    public ExtensionRepoArtifactsResult(final ResultType resultType, final List<ExtensionRepoArtifact> bundleArtifacts) {
         super(resultType);
-        this.usersEntity = usersEntity;
-        Validate.notNull(this.usersEntity);
+        this.bundleArtifacts = bundleArtifacts;
+        Validate.notNull(this.bundleArtifacts);
+
+        this.bundleArtifacts.sort(
+                Comparator.comparing(ExtensionRepoArtifact::getBucketName)
+                        .thenComparing(ExtensionRepoArtifact::getGroupId)
+                        .thenComparing(ExtensionRepoArtifact::getArtifactId));
     }
 
     @Override
     protected void writeSimpleResult(final PrintStream output) throws IOException {
-        final Collection<UserEntity> userEntities = usersEntity.getUsers();
-        if (userEntities == null) {
+        if (bundleArtifacts.isEmpty()) {
             return;
         }
 
-        final List<UserDTO> userDTOS = userEntities.stream()
-                .map(s -> s.getComponent())
-                .collect(Collectors.toList());
-
-        Collections.sort(userDTOS, Comparator.comparing(UserDTO::getIdentity));
-
         final Table table = new Table.Builder()
                 .column("#", 3, 3, false)
-                .column("Name", 5, 40, false)
-                .column("ID", 36, 36, false)
-                .column("Member of", 20, 40, true)
+                .column("Bucket", 40, 400, false)
+                .column("Group", 40, 200, false)
+                .column("Artifact", 40, 200, false)
                 .build();
 
-        for (int i = 0; i < userDTOS.size(); i++) {
-            final UserDTO userDTO = userDTOS.get(i);
-            table.addRow(
-                    String.valueOf(i + 1),
-                    userDTO.getIdentity(),
-                    userDTO.getId(),
-                    userDTO.getUserGroups().stream().map(u -> u.getComponent().getIdentity())
-                            .collect(Collectors.joining(", "))
-            );
+        for (int i = 0; i < bundleArtifacts.size(); ++i) {
+            final ExtensionRepoArtifact artifact = bundleArtifacts.get(i);
+            table.addRow(String.valueOf(i + 1), artifact.getBucketName(), artifact.getGroupId(), artifact.getArtifactId());
         }
 
         final TableWriter tableWriter = new DynamicTableWriter();
@@ -82,7 +70,7 @@ public class UsersResult extends AbstractWritableResult<UsersEntity> {
     }
 
     @Override
-    public UsersEntity getResult() {
-        return usersEntity;
+    public List<ExtensionRepoArtifact> getResult() {
+        return this.bundleArtifacts;
     }
 }
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/NodesResult.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/registry/ExtensionRepoGroupsResult.java
similarity index 52%
copy from nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/NodesResult.java
copy to nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/registry/ExtensionRepoGroupsResult.java
index daab27f..c3ccddd 100644
--- a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/NodesResult.java
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/registry/ExtensionRepoGroupsResult.java
@@ -14,53 +14,61 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.nifi.toolkit.cli.impl.result;
+package org.apache.nifi.toolkit.cli.impl.result.registry;
 
 import org.apache.commons.lang3.Validate;
+import org.apache.nifi.registry.extension.repo.ExtensionRepoGroup;
 import org.apache.nifi.toolkit.cli.api.ResultType;
+import org.apache.nifi.toolkit.cli.impl.result.AbstractWritableResult;
 import org.apache.nifi.toolkit.cli.impl.result.writer.DynamicTableWriter;
 import org.apache.nifi.toolkit.cli.impl.result.writer.Table;
 import org.apache.nifi.toolkit.cli.impl.result.writer.TableWriter;
-import org.apache.nifi.web.api.dto.NodeDTO;
-import org.apache.nifi.web.api.entity.ClusterEntity;
-import org.glassfish.jersey.internal.guava.Lists;
 
 import java.io.IOException;
 import java.io.PrintStream;
+import java.util.Comparator;
 import java.util.List;
 
-public class NodesResult extends AbstractWritableResult<ClusterEntity> {
+/**
+ * Result for list of bundle groups.
+ */
+public class ExtensionRepoGroupsResult extends AbstractWritableResult<List<ExtensionRepoGroup>> {
 
-    private final ClusterEntity clusterEntity;
+    private final List<ExtensionRepoGroup> bundleGroups;
 
-    public NodesResult(ResultType resultType, ClusterEntity clusterEntity) {
+    public ExtensionRepoGroupsResult(final ResultType resultType, final List<ExtensionRepoGroup> bundleGroups) {
         super(resultType);
-        this.clusterEntity = clusterEntity;
-        Validate.notNull(clusterEntity);
-    }
+        this.bundleGroups = bundleGroups;
+        Validate.notNull(this.bundleGroups);
 
-    @Override
-    public ClusterEntity getResult() {
-        return clusterEntity;
+        this.bundleGroups.sort(
+                Comparator.comparing(ExtensionRepoGroup::getBucketName)
+                        .thenComparing(ExtensionRepoGroup::getGroupId));
     }
 
     @Override
-    protected void writeSimpleResult(PrintStream output) throws IOException {
+    protected void writeSimpleResult(final PrintStream output) throws IOException {
+        if (bundleGroups.isEmpty()) {
+            return;
+        }
+
         final Table table = new Table.Builder()
                 .column("#", 3, 3, false)
-                .column("Node ID", 36, 36, false)
-                .column("Node Address", 36, 36, true)
-                .column("API Port", 8, 8, false)
-                .column("Node Status", 13, 13, false)
+                .column("Bucket", 40, 400, false)
+                .column("Group", 40, 200, false)
                 .build();
 
-        List<NodeDTO> nodes = Lists.newArrayList(clusterEntity.getCluster().getNodes());
-        for (int i = 0; i < nodes.size(); ++i) {
-            NodeDTO nodeDTO = nodes.get(i);
-            table.addRow(String.valueOf(i), nodeDTO.getNodeId(), nodeDTO.getAddress(), String.valueOf(nodeDTO.getApiPort()), nodeDTO.getStatus());
+        for (int i = 0; i < bundleGroups.size(); ++i) {
+            final ExtensionRepoGroup group = bundleGroups.get(i);
+            table.addRow(String.valueOf(i + 1), group.getBucketName(), group.getGroupId());
         }
 
         final TableWriter tableWriter = new DynamicTableWriter();
         tableWriter.write(table, output);
     }
+
+    @Override
+    public List<ExtensionRepoGroup> getResult() {
+        return this.bundleGroups;
+    }
 }
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/registry/ExtensionRepoVersionSummariesResult.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/registry/ExtensionRepoVersionSummariesResult.java
new file mode 100644
index 0000000..655705a
--- /dev/null
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/registry/ExtensionRepoVersionSummariesResult.java
@@ -0,0 +1,76 @@
+/*
+ * 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.nifi.toolkit.cli.impl.result.registry;
+
+import org.apache.commons.lang3.Validate;
+import org.apache.nifi.registry.extension.repo.ExtensionRepoVersionSummary;
+import org.apache.nifi.toolkit.cli.api.ResultType;
+import org.apache.nifi.toolkit.cli.impl.result.AbstractWritableResult;
+import org.apache.nifi.toolkit.cli.impl.result.writer.DynamicTableWriter;
+import org.apache.nifi.toolkit.cli.impl.result.writer.Table;
+import org.apache.nifi.toolkit.cli.impl.result.writer.TableWriter;
+
+import java.io.PrintStream;
+import java.util.Comparator;
+import java.util.List;
+
+public class ExtensionRepoVersionSummariesResult extends AbstractWritableResult<List<ExtensionRepoVersionSummary>> {
+
+    private final List<ExtensionRepoVersionSummary> bundleVersions;
+
+    public ExtensionRepoVersionSummariesResult(final ResultType resultType, final List<ExtensionRepoVersionSummary> bundleVersions) {
+        super(resultType);
+        this.bundleVersions = bundleVersions;
+        Validate.notNull(this.bundleVersions);
+
+        this.bundleVersions.sort(
+                Comparator.comparing(ExtensionRepoVersionSummary::getBucketName)
+                        .thenComparing(ExtensionRepoVersionSummary::getGroupId)
+                        .thenComparing(ExtensionRepoVersionSummary::getArtifactId)
+                        .thenComparing(ExtensionRepoVersionSummary::getVersion)
+        );
+    }
+
+    @Override
+    protected void writeSimpleResult(final PrintStream output) {
+        if (bundleVersions.isEmpty()) {
+            return;
+        }
+
+        final Table table = new Table.Builder()
+                .column("#", 3, 3, false)
+                .column("Bucket", 40, 400, false)
+                .column("Group", 40, 200, false)
+                .column("Artifact", 40, 200, false)
+                .column("Version", 8, 100, false)
+                .build();
+
+        for (int i = 0; i < bundleVersions.size(); ++i) {
+            final ExtensionRepoVersionSummary version = bundleVersions.get(i);
+            table.addRow(String.valueOf(i + 1), version.getBucketName(), version.getGroupId(), version.getArtifactId(), version.getVersion());
+        }
+
+        final TableWriter tableWriter = new DynamicTableWriter();
+        tableWriter.write(table, output);
+    }
+
+    @Override
+    public List<ExtensionRepoVersionSummary> getResult() {
+        return bundleVersions;
+    }
+
+}
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/NodesResult.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/registry/TagCountResult.java
similarity index 54%
rename from nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/NodesResult.java
rename to nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/registry/TagCountResult.java
index daab27f..b035cf2 100644
--- a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/NodesResult.java
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/registry/TagCountResult.java
@@ -14,53 +14,52 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.nifi.toolkit.cli.impl.result;
+package org.apache.nifi.toolkit.cli.impl.result.registry;
 
 import org.apache.commons.lang3.Validate;
+import org.apache.nifi.registry.extension.component.TagCount;
 import org.apache.nifi.toolkit.cli.api.ResultType;
+import org.apache.nifi.toolkit.cli.impl.result.AbstractWritableResult;
 import org.apache.nifi.toolkit.cli.impl.result.writer.DynamicTableWriter;
 import org.apache.nifi.toolkit.cli.impl.result.writer.Table;
 import org.apache.nifi.toolkit.cli.impl.result.writer.TableWriter;
-import org.apache.nifi.web.api.dto.NodeDTO;
-import org.apache.nifi.web.api.entity.ClusterEntity;
-import org.glassfish.jersey.internal.guava.Lists;
 
 import java.io.IOException;
 import java.io.PrintStream;
 import java.util.List;
 
-public class NodesResult extends AbstractWritableResult<ClusterEntity> {
+public class TagCountResult extends AbstractWritableResult<List<TagCount>> {
 
-    private final ClusterEntity clusterEntity;
+    private final List<TagCount> tagCounts;
 
-    public NodesResult(ResultType resultType, ClusterEntity clusterEntity) {
+    public TagCountResult(ResultType resultType, final List<TagCount> tagCounts) {
         super(resultType);
-        this.clusterEntity = clusterEntity;
-        Validate.notNull(clusterEntity);
+        this.tagCounts = tagCounts;
+        Validate.notNull(this.tagCounts);
     }
 
     @Override
-    public ClusterEntity getResult() {
-        return clusterEntity;
-    }
+    protected void writeSimpleResult(final PrintStream output) throws IOException {
+        if (tagCounts.isEmpty()) {
+            return;
+        }
 
-    @Override
-    protected void writeSimpleResult(PrintStream output) throws IOException {
         final Table table = new Table.Builder()
-                .column("#", 3, 3, false)
-                .column("Node ID", 36, 36, false)
-                .column("Node Address", 36, 36, true)
-                .column("API Port", 8, 8, false)
-                .column("Node Status", 13, 13, false)
+                .column("Tag", 20, 200, false)
+                .column("Count", 5, 20, false)
                 .build();
 
-        List<NodeDTO> nodes = Lists.newArrayList(clusterEntity.getCluster().getNodes());
-        for (int i = 0; i < nodes.size(); ++i) {
-            NodeDTO nodeDTO = nodes.get(i);
-            table.addRow(String.valueOf(i), nodeDTO.getNodeId(), nodeDTO.getAddress(), String.valueOf(nodeDTO.getApiPort()), nodeDTO.getStatus());
+        for (int i = 0; i < tagCounts.size(); ++i) {
+            final TagCount tagCount = tagCounts.get(i);
+            table.addRow(tagCount.getTag(), String.valueOf(tagCount.getCount()));
         }
 
         final TableWriter tableWriter = new DynamicTableWriter();
         tableWriter.write(table, output);
     }
+
+    @Override
+    public List<TagCount> getResult() {
+        return tagCounts;
+    }
 }
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/VersionedFlowSnapshotMetadataResult.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/registry/VersionedFlowSnapshotMetadataResult.java
similarity index 95%
rename from nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/VersionedFlowSnapshotMetadataResult.java
rename to nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/registry/VersionedFlowSnapshotMetadataResult.java
index 554097a..9241e29 100644
--- a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/VersionedFlowSnapshotMetadataResult.java
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/registry/VersionedFlowSnapshotMetadataResult.java
@@ -14,11 +14,12 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.nifi.toolkit.cli.impl.result;
+package org.apache.nifi.toolkit.cli.impl.result.registry;
 
 import org.apache.commons.lang3.Validate;
 import org.apache.nifi.registry.flow.VersionedFlowSnapshotMetadata;
 import org.apache.nifi.toolkit.cli.api.ResultType;
+import org.apache.nifi.toolkit.cli.impl.result.AbstractWritableResult;
 import org.apache.nifi.toolkit.cli.impl.result.writer.DynamicTableWriter;
 import org.apache.nifi.toolkit.cli.impl.result.writer.Table;
 import org.apache.nifi.toolkit.cli.impl.result.writer.TableWriter;
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/VersionedFlowSnapshotMetadataSetResult.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/registry/VersionedFlowSnapshotMetadataSetResult.java
similarity index 95%
rename from nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/VersionedFlowSnapshotMetadataSetResult.java
rename to nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/registry/VersionedFlowSnapshotMetadataSetResult.java
index deabd3a..c5859b5 100644
--- a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/VersionedFlowSnapshotMetadataSetResult.java
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/registry/VersionedFlowSnapshotMetadataSetResult.java
@@ -14,12 +14,13 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.nifi.toolkit.cli.impl.result;
+package org.apache.nifi.toolkit.cli.impl.result.registry;
 
 import org.apache.commons.lang3.Validate;
 import org.apache.nifi.registry.flow.VersionedFlowSnapshotMetadata;
 import org.apache.nifi.toolkit.cli.api.ResultType;
 import org.apache.nifi.toolkit.cli.api.WritableResult;
+import org.apache.nifi.toolkit.cli.impl.result.AbstractWritableResult;
 import org.apache.nifi.web.api.entity.VersionedFlowSnapshotMetadataEntity;
 import org.apache.nifi.web.api.entity.VersionedFlowSnapshotMetadataSetEntity;
 
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/VersionedFlowSnapshotResult.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/registry/VersionedFlowSnapshotResult.java
similarity index 97%
rename from nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/VersionedFlowSnapshotResult.java
rename to nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/registry/VersionedFlowSnapshotResult.java
index f8c7453..3957d09 100644
--- a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/VersionedFlowSnapshotResult.java
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/registry/VersionedFlowSnapshotResult.java
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.nifi.toolkit.cli.impl.result;
+package org.apache.nifi.toolkit.cli.impl.result.registry;
 
 import org.apache.commons.lang3.Validate;
 import org.apache.nifi.registry.flow.VersionedFlowSnapshot;
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/VersionedFlowsResult.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/registry/VersionedFlowsResult.java
similarity index 97%
rename from nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/VersionedFlowsResult.java
rename to nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/registry/VersionedFlowsResult.java
index 678db73..facfa29 100644
--- a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/VersionedFlowsResult.java
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/registry/VersionedFlowsResult.java
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.nifi.toolkit.cli.impl.result;
+package org.apache.nifi.toolkit.cli.impl.result.registry;
 
 import org.apache.commons.lang3.Validate;
 import org.apache.nifi.registry.flow.VersionedFlow;
@@ -24,6 +24,7 @@ import org.apache.nifi.toolkit.cli.api.Referenceable;
 import org.apache.nifi.toolkit.cli.api.ResolvedReference;
 import org.apache.nifi.toolkit.cli.api.ResultType;
 import org.apache.nifi.toolkit.cli.impl.command.CommandOption;
+import org.apache.nifi.toolkit.cli.impl.result.AbstractWritableResult;
 import org.apache.nifi.toolkit.cli.impl.result.writer.DynamicTableWriter;
 import org.apache.nifi.toolkit.cli.impl.result.writer.Table;
 import org.apache.nifi.toolkit.cli.impl.result.writer.TableWriter;
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/test/java/org/apache/nifi/toolkit/cli/impl/client/nifi/TestProcessGroupBox.java b/nifi-toolkit/nifi-toolkit-cli/src/test/java/org/apache/nifi/toolkit/cli/impl/client/nifi/TestProcessGroupBox.java
new file mode 100644
index 0000000..762c9e7
--- /dev/null
+++ b/nifi-toolkit/nifi-toolkit-cli/src/test/java/org/apache/nifi/toolkit/cli/impl/client/nifi/TestProcessGroupBox.java
@@ -0,0 +1,86 @@
+/*
+ * 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.nifi.toolkit.cli.impl.client.nifi;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class TestProcessGroupBox {
+
+    @Test
+    public void testIntersectsWhenCompletelyAbove() {
+        final ProcessGroupBox pg1 = new ProcessGroupBox(0, 0);
+        final ProcessGroupBox pg2 = new ProcessGroupBox(0, ProcessGroupBox.PG_SIZE_HEIGHT * 2 + 10);
+        Assert.assertFalse(pg1.intersects(pg2));
+    }
+
+    @Test
+    public void testIntersectsWhenCompletelyBelow() {
+        final ProcessGroupBox pg1 = new ProcessGroupBox(0, ProcessGroupBox.PG_SIZE_HEIGHT * 2 + 10);
+        final ProcessGroupBox pg2 = new ProcessGroupBox(0, 0);
+        Assert.assertFalse(pg1.intersects(pg2));
+    }
+
+    @Test
+    public void testIntersectsWhenCompletelyLeft() {
+        final ProcessGroupBox pg1 = new ProcessGroupBox(0, 0);
+        final ProcessGroupBox pg2 = new ProcessGroupBox(ProcessGroupBox.PG_SIZE_WIDTH * 2 + 10,0);
+        Assert.assertFalse(pg1.intersects(pg2));
+    }
+
+    @Test
+    public void testIntersectsWhenCompletelyRight() {
+        final ProcessGroupBox pg1 = new ProcessGroupBox(ProcessGroupBox.PG_SIZE_WIDTH * 2 + 10,0);
+        final ProcessGroupBox pg2 = new ProcessGroupBox(0,0);
+        Assert.assertFalse(pg1.intersects(pg2));
+    }
+
+    @Test
+    public void testIntersectsWhenCompletelyOverlapping() {
+        final ProcessGroupBox pg1 = new ProcessGroupBox(0,0);
+        final ProcessGroupBox pg2 = new ProcessGroupBox(0,0);
+        Assert.assertTrue(pg1.intersects(pg2));
+    }
+
+    @Test
+    public void testIntersectsWhenPartiallyOverlappingVertically() {
+        final ProcessGroupBox pg1 = new ProcessGroupBox(0,0);
+        final ProcessGroupBox pg2 = new ProcessGroupBox(0,ProcessGroupBox.PG_SIZE_HEIGHT / 2);
+        Assert.assertTrue(pg1.intersects(pg2));
+    }
+
+    @Test
+    public void testIntersectsWhenBottomAndTopSame() {
+        final ProcessGroupBox pg1 = new ProcessGroupBox(0,0);
+        final ProcessGroupBox pg2 = new ProcessGroupBox(0,ProcessGroupBox.PG_SIZE_HEIGHT);
+        Assert.assertTrue(pg1.intersects(pg2));
+    }
+
+    @Test
+    public void testIntersectsWhenPartiallyOverlappingHorizontally() {
+        final ProcessGroupBox pg1 = new ProcessGroupBox(0,0);
+        final ProcessGroupBox pg2 = new ProcessGroupBox(ProcessGroupBox.PG_SIZE_WIDTH / 2,0);
+        Assert.assertTrue(pg1.intersects(pg2));
+    }
+
+    @Test
+    public void testIntersectsWhenRightAndLeftSame() {
+        final ProcessGroupBox pg1 = new ProcessGroupBox(0,0);
+        final ProcessGroupBox pg2 = new ProcessGroupBox(ProcessGroupBox.PG_SIZE_WIDTH,0);
+        Assert.assertTrue(pg1.intersects(pg2));
+    }
+}
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/test/java/org/apache/nifi/toolkit/cli/impl/result/TestBucketsResult.java b/nifi-toolkit/nifi-toolkit-cli/src/test/java/org/apache/nifi/toolkit/cli/impl/result/TestBucketsResult.java
index 1bb9582..f535f64 100644
--- a/nifi-toolkit/nifi-toolkit-cli/src/test/java/org/apache/nifi/toolkit/cli/impl/result/TestBucketsResult.java
+++ b/nifi-toolkit/nifi-toolkit-cli/src/test/java/org/apache/nifi/toolkit/cli/impl/result/TestBucketsResult.java
@@ -18,6 +18,7 @@ package org.apache.nifi.toolkit.cli.impl.result;
 
 import org.apache.nifi.registry.bucket.Bucket;
 import org.apache.nifi.toolkit.cli.api.ResultType;
+import org.apache.nifi.toolkit.cli.impl.result.registry.BucketsResult;
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/test/java/org/apache/nifi/toolkit/cli/impl/result/TestRegistryClientResult.java b/nifi-toolkit/nifi-toolkit-cli/src/test/java/org/apache/nifi/toolkit/cli/impl/result/TestRegistryClientResult.java
index 17acacd..5421ea4 100644
--- a/nifi-toolkit/nifi-toolkit-cli/src/test/java/org/apache/nifi/toolkit/cli/impl/result/TestRegistryClientResult.java
+++ b/nifi-toolkit/nifi-toolkit-cli/src/test/java/org/apache/nifi/toolkit/cli/impl/result/TestRegistryClientResult.java
@@ -17,6 +17,7 @@
 package org.apache.nifi.toolkit.cli.impl.result;
 
 import org.apache.nifi.toolkit.cli.api.ResultType;
+import org.apache.nifi.toolkit.cli.impl.result.nifi.RegistryClientsResult;
 import org.apache.nifi.web.api.dto.RegistryDTO;
 import org.apache.nifi.web.api.entity.RegistryClientEntity;
 import org.apache.nifi.web.api.entity.RegistryClientsEntity;
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/test/java/org/apache/nifi/toolkit/cli/impl/result/TestVersionedFlowSnapshotMetadataResult.java b/nifi-toolkit/nifi-toolkit-cli/src/test/java/org/apache/nifi/toolkit/cli/impl/result/TestVersionedFlowSnapshotMetadataResult.java
index c364096..3fb98d2 100644
--- a/nifi-toolkit/nifi-toolkit-cli/src/test/java/org/apache/nifi/toolkit/cli/impl/result/TestVersionedFlowSnapshotMetadataResult.java
+++ b/nifi-toolkit/nifi-toolkit-cli/src/test/java/org/apache/nifi/toolkit/cli/impl/result/TestVersionedFlowSnapshotMetadataResult.java
@@ -18,6 +18,7 @@ package org.apache.nifi.toolkit.cli.impl.result;
 
 import org.apache.nifi.registry.flow.VersionedFlowSnapshotMetadata;
 import org.apache.nifi.toolkit.cli.api.ResultType;
+import org.apache.nifi.toolkit.cli.impl.result.registry.VersionedFlowSnapshotMetadataResult;
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/test/java/org/apache/nifi/toolkit/cli/impl/result/TestVersionedFlowsResult.java b/nifi-toolkit/nifi-toolkit-cli/src/test/java/org/apache/nifi/toolkit/cli/impl/result/TestVersionedFlowsResult.java
index dc5abbb..f6951b7 100644
--- a/nifi-toolkit/nifi-toolkit-cli/src/test/java/org/apache/nifi/toolkit/cli/impl/result/TestVersionedFlowsResult.java
+++ b/nifi-toolkit/nifi-toolkit-cli/src/test/java/org/apache/nifi/toolkit/cli/impl/result/TestVersionedFlowsResult.java
@@ -21,6 +21,7 @@ import org.apache.nifi.toolkit.cli.api.Context;
 import org.apache.nifi.toolkit.cli.api.ReferenceResolver;
 import org.apache.nifi.toolkit.cli.api.ResultType;
 import org.apache.nifi.toolkit.cli.impl.command.CommandOption;
+import org.apache.nifi.toolkit.cli.impl.result.registry.VersionedFlowsResult;
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
diff --git a/pom.xml b/pom.xml
index 30f0f7b..569f597 100644
--- a/pom.xml
+++ b/pom.xml
@@ -705,9 +705,9 @@
             </build>
         </profile>
         <profile>
-            <!-- This profile will disable DocLint which performs strict 
-                JavaDoc processing which was introduced in JDK 8. These are technically errors 
-                in the JavaDoc which we need to eventually address. However, if a release 
+            <!-- This profile will disable DocLint which performs strict
+                JavaDoc processing which was introduced in JDK 8. These are technically errors
+                in the JavaDoc which we need to eventually address. However, if a release
                 is performed using JDK 8 or newer, the JavaDoc generation would fail. By activating
                 this profile when running on JDK 8 or newer we can ensure the JavaDocs continue to
                 generate successfully -->