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

jensdeppe pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/geode.git


The following commit(s) were added to refs/heads/develop by this push:
     new 8bcb04e  GEODE-5971 Refactor Lucene Index commands to support 
ResultModel and GfshCommand (#3323)
8bcb04e is described below

commit 8bcb04ef40377a317c688b43102bc60645a8440d
Author: Jens Deppe <jde...@pivotal.io>
AuthorDate: Tue Mar 26 11:15:24 2019 -0700

    GEODE-5971 Refactor Lucene Index commands to support ResultModel and 
GfshCommand (#3323)
---
 .../geode/test/dunit/internal/ProcessManager.java  |   1 +
 .../lucene/internal/cli/LuceneCommandBase.java     | 114 +++++
 .../internal/cli/LuceneCreateIndexCommand.java     | 127 ++++++
 .../internal/cli/LuceneDescribeIndexCommand.java   |  53 +++
 .../internal/cli/LuceneDestroyIndexCommand.java    | 133 ++++++
 .../lucene/internal/cli/LuceneIndexCommands.java   | 487 ---------------------
 .../internal/cli/LuceneListIndexCommand.java       |  80 ++++
 .../internal/cli/LuceneSearchIndexCommand.java     | 207 +++++++++
 .../lucene/internal/cli/LuceneSearchResults.java   |   2 +-
 .../org.springframework.shell.core.CommandMarker   |   6 +-
 .../internal/cli/LuceneIndexCommandsJUnitTest.java | 317 +++++++++-----
 11 files changed, 919 insertions(+), 608 deletions(-)

diff --git 
a/geode-dunit/src/main/java/org/apache/geode/test/dunit/internal/ProcessManager.java
 
b/geode-dunit/src/main/java/org/apache/geode/test/dunit/internal/ProcessManager.java
index c0e1237..4401497 100755
--- 
a/geode-dunit/src/main/java/org/apache/geode/test/dunit/internal/ProcessManager.java
+++ 
b/geode-dunit/src/main/java/org/apache/geode/test/dunit/internal/ProcessManager.java
@@ -235,6 +235,7 @@ class ProcessManager implements ChildVMLauncher {
       // remove current-version product classes and resources from the 
classpath
       dunitClasspath =
           removeModulesFromPath(dunitClasspath, "geode-core", "geode-cq", 
"geode-common",
+              "geode-json", "geode-lucene",
               "geode-wan");
       classPath = versionManager.getClasspath(version) + File.pathSeparator + 
dunitClasspath;
     }
diff --git 
a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/cli/LuceneCommandBase.java
 
b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/cli/LuceneCommandBase.java
new file mode 100644
index 0000000..bc9cc56
--- /dev/null
+++ 
b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/cli/LuceneCommandBase.java
@@ -0,0 +1,114 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more 
contributor license
+ * agreements. See the NOTICE file distributed with this work for additional 
information regarding
+ * copyright ownership. The ASF licenses this file to You under the Apache 
License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the 
License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software 
distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 
KIND, either express
+ * or implied. See the License for the specific language governing permissions 
and limitations under
+ * the License.
+ */
+
+package org.apache.geode.cache.lucene.internal.cli;
+
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import org.apache.geode.cache.execute.Function;
+import org.apache.geode.cache.execute.ResultCollector;
+import 
org.apache.geode.cache.lucene.internal.cli.functions.LuceneDescribeIndexFunction;
+import org.apache.geode.distributed.DistributedMember;
+import org.apache.geode.internal.cache.InternalCache;
+import org.apache.geode.management.cli.GfshCommand;
+import org.apache.geode.management.internal.cli.CliUtil;
+import org.apache.geode.management.internal.cli.exceptions.UserErrorException;
+import org.apache.geode.management.internal.cli.i18n.CliStrings;
+import org.apache.geode.management.internal.cli.result.model.ResultModel;
+import 
org.apache.geode.management.internal.cli.result.model.TabularResultModel;
+import org.apache.geode.management.internal.cli.shell.Gfsh;
+
+public abstract class LuceneCommandBase extends GfshCommand {
+
+  private static final LuceneDescribeIndexFunction describeIndexFunction =
+      new LuceneDescribeIndexFunction();
+
+  protected ResultModel toTabularResult(final List<LuceneIndexDetails> 
indexDetailsList,
+      boolean stats) {
+    if (!indexDetailsList.isEmpty()) {
+      ResultModel result = new ResultModel();
+      TabularResultModel indexData = result.addTable("lucene-indexes");
+
+      for (final LuceneIndexDetails indexDetails : indexDetailsList) {
+        indexData.accumulate("Index Name", indexDetails.getIndexName());
+        indexData.accumulate("Region Path", indexDetails.getRegionPath());
+        indexData.accumulate("Server Name", indexDetails.getServerName());
+        indexData.accumulate("Indexed Fields", 
indexDetails.getSearchableFieldNamesString());
+        indexData.accumulate("Field Analyzer", 
indexDetails.getFieldAnalyzersString());
+        indexData.accumulate("Serializer", indexDetails.getSerializerString());
+        indexData.accumulate("Status", indexDetails.getStatus().toString());
+
+        if (stats) {
+          LuceneIndexStatus luceneIndexStatus = indexDetails.getStatus();
+          if (luceneIndexStatus == LuceneIndexStatus.NOT_INITIALIZED
+              || luceneIndexStatus == LuceneIndexStatus.INDEXING_IN_PROGRESS) {
+            indexData.accumulate("Query Executions", "NA");
+            indexData.accumulate("Updates", "NA");
+            indexData.accumulate("Commits", "NA");
+            indexData.accumulate("Documents", "NA");
+          } else {
+            indexData.accumulate("Query Executions",
+                
indexDetails.getIndexStats().get("queryExecutions").toString());
+            indexData.accumulate("Updates",
+                indexDetails.getIndexStats().get("updates").toString());
+            indexData.accumulate("Commits",
+                indexDetails.getIndexStats().get("commits").toString());
+            indexData.accumulate("Documents",
+                indexDetails.getIndexStats().get("documents").toString());
+          }
+        }
+      }
+      return result;
+    } else {
+      return ResultModel
+          
.createInfo(LuceneCliStrings.LUCENE_LIST_INDEX__INDEXES_NOT_FOUND_MESSAGE);
+    }
+  }
+
+  @SuppressWarnings("unchecked")
+  protected List<LuceneIndexDetails> getIndexDetails(LuceneIndexInfo 
indexInfo) throws Exception {
+    final ResultCollector<?, ?> rc =
+        executeFunctionOnRegion(describeIndexFunction, indexInfo, true);
+    final List<LuceneIndexDetails> funcResults = (List<LuceneIndexDetails>) 
rc.getResult();
+    return 
funcResults.stream().filter(Objects::nonNull).collect(Collectors.toList());
+  }
+
+  protected ResultCollector<?, ?> executeFunctionOnRegion(Function function,
+      LuceneFunctionSerializable functionArguments, boolean returnAllMembers) {
+    Set<DistributedMember> targetMembers = CliUtil.getRegionAssociatedMembers(
+        functionArguments.getRegionPath(), (InternalCache) getCache(), 
returnAllMembers);
+    if (targetMembers.isEmpty()) {
+      throw new UserErrorException(CliStrings.format(
+          
LuceneCliStrings.LUCENE_DESTROY_INDEX__MSG__COULDNOT_FIND_MEMBERS_FOR_REGION_0,
+          new Object[] {functionArguments.getRegionPath()}));
+    }
+    return executeFunction(function, functionArguments, targetMembers);
+  }
+
+  protected boolean indexCommandsAvailable() {
+    Gfsh gfsh = Gfsh.getCurrentInstance();
+
+    // command should always be available on the server
+    if (gfsh == null) {
+      return true;
+    }
+
+    // if in gfshVM, only when gfsh is connected and ready
+    return gfsh.isConnectedAndReady();
+  }
+}
diff --git 
a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/cli/LuceneCreateIndexCommand.java
 
b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/cli/LuceneCreateIndexCommand.java
new file mode 100755
index 0000000..b1d307d
--- /dev/null
+++ 
b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/cli/LuceneCreateIndexCommand.java
@@ -0,0 +1,127 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more 
contributor license
+ * agreements. See the NOTICE file distributed with this work for additional 
information regarding
+ * copyright ownership. The ASF licenses this file to You under the Apache 
License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the 
License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software 
distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 
KIND, either express
+ * or implied. See the License for the specific language governing permissions 
and limitations under
+ * the License.
+ */
+package org.apache.geode.cache.lucene.internal.cli;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+
+import org.springframework.shell.core.annotation.CliAvailabilityIndicator;
+import org.springframework.shell.core.annotation.CliCommand;
+import org.springframework.shell.core.annotation.CliOption;
+
+import org.apache.geode.cache.execute.Function;
+import org.apache.geode.cache.execute.ResultCollector;
+import 
org.apache.geode.cache.lucene.internal.cli.functions.LuceneCreateIndexFunction;
+import org.apache.geode.cache.lucene.internal.security.LucenePermission;
+import org.apache.geode.distributed.DistributedMember;
+import 
org.apache.geode.distributed.internal.InternalConfigurationPersistenceService;
+import org.apache.geode.internal.cache.InternalCache;
+import org.apache.geode.management.cli.CliMetaData;
+import org.apache.geode.management.cli.ConverterHint;
+import org.apache.geode.management.internal.cli.functions.CliFunctionResult;
+import org.apache.geode.management.internal.cli.i18n.CliStrings;
+import org.apache.geode.management.internal.cli.remote.CommandExecutor;
+import org.apache.geode.management.internal.cli.result.CommandResultException;
+import org.apache.geode.management.internal.cli.result.model.ResultModel;
+import 
org.apache.geode.management.internal.cli.result.model.TabularResultModel;
+import org.apache.geode.management.internal.configuration.domain.XmlEntity;
+import org.apache.geode.security.ResourcePermission.Operation;
+import org.apache.geode.security.ResourcePermission.Resource;
+
+@SuppressWarnings("unused")
+public class LuceneCreateIndexCommand extends LuceneCommandBase {
+
+  private static final LuceneCreateIndexFunction createIndexFunction =
+      new LuceneCreateIndexFunction();
+
+  /**
+   * On the server, we also verify the resource operation permissions 
CLUSTER:WRITE:DISK
+   */
+  @CliCommand(value = LuceneCliStrings.LUCENE_CREATE_INDEX,
+      help = LuceneCliStrings.LUCENE_CREATE_INDEX__HELP)
+  @CliMetaData(relatedTopic = {CliStrings.TOPIC_GEODE_REGION, 
CliStrings.TOPIC_GEODE_DATA})
+  // TODO : Add optionContext for indexName
+  public ResultModel createIndex(
+      @CliOption(key = LuceneCliStrings.LUCENE__INDEX_NAME, mandatory = true,
+          help = LuceneCliStrings.LUCENE_CREATE_INDEX__NAME__HELP) final 
String indexName,
+
+      @CliOption(key = LuceneCliStrings.LUCENE__REGION_PATH, mandatory = true,
+          optionContext = ConverterHint.REGION_PATH,
+          help = LuceneCliStrings.LUCENE_CREATE_INDEX__REGION_HELP) final 
String regionPath,
+
+      @CliOption(key = LuceneCliStrings.LUCENE_CREATE_INDEX__FIELD, mandatory 
= true,
+          help = LuceneCliStrings.LUCENE_CREATE_INDEX__FIELD_HELP) final 
String[] fields,
+
+      @CliOption(key = LuceneCliStrings.LUCENE_CREATE_INDEX__ANALYZER,
+          help = LuceneCliStrings.LUCENE_CREATE_INDEX__ANALYZER_HELP) final 
String[] analyzers,
+      @CliOption(key = LuceneCliStrings.LUCENE_CREATE_INDEX__SERIALIZER,
+          help = LuceneCliStrings.LUCENE_CREATE_INDEX__SERIALIZER_HELP) final 
String serializer)
+      throws CommandResultException {
+
+    // Every lucene index potentially writes to disk.
+    authorize(Resource.CLUSTER, Operation.MANAGE, LucenePermission.TARGET);
+
+    final InternalCache cache = (InternalCache) getCache();
+
+    // trim fields for any leading trailing spaces.
+    String[] trimmedFields = 
Arrays.stream(fields).map(String::trim).toArray(String[]::new);
+    LuceneIndexInfo indexInfo =
+        new LuceneIndexInfo(indexName, regionPath, trimmedFields, analyzers, 
serializer);
+
+    final ResultCollector<?, ?> rc =
+        this.executeFunctionOnAllMembers(createIndexFunction, indexInfo);
+    final List<CliFunctionResult> funcResults = (List<CliFunctionResult>) 
rc.getResult();
+    final XmlEntity xmlEntity = 
funcResults.stream().filter(CliFunctionResult::isSuccessful)
+        
.map(CliFunctionResult::getXmlEntity).filter(Objects::nonNull).findFirst().orElse(null);
+    final ResultModel result = new ResultModel();
+    final TabularResultModel tabularResult = result.addTable("lucene-indexes");
+    for (final CliFunctionResult cliFunctionResult : funcResults) {
+      tabularResult.accumulate("Member", 
cliFunctionResult.getMemberIdOrName());
+
+      if (cliFunctionResult.isSuccessful()) {
+        tabularResult.accumulate("Status", "Successfully created lucene 
index");
+      } else {
+        tabularResult.accumulate("Status", "Failed: " + 
cliFunctionResult.getMessage());
+      }
+    }
+
+    // if at least one member returns with successful deletion, we will need 
to update cc
+    InternalConfigurationPersistenceService configurationPersistenceService =
+        getConfigurationPersistenceService();
+    if (xmlEntity != null) {
+      if (configurationPersistenceService == null) {
+        
result.addInfo().addLine(CommandExecutor.SERVICE_NOT_RUNNING_CHANGE_NOT_PERSISTED);
+      } else {
+        configurationPersistenceService.addXmlEntity(xmlEntity, null);
+      }
+    }
+
+    return result;
+  }
+
+  protected ResultCollector<?, ?> executeFunctionOnAllMembers(Function 
function,
+      final LuceneFunctionSerializable functionArguments)
+      throws IllegalArgumentException {
+    Set<DistributedMember> targetMembers = getAllNormalMembers();
+    return executeFunction(function, functionArguments, targetMembers);
+  }
+
+  @CliAvailabilityIndicator(LuceneCliStrings.LUCENE_CREATE_INDEX)
+  public boolean indexCommandsAvailable() {
+    return super.indexCommandsAvailable();
+  }
+}
diff --git 
a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/cli/LuceneDescribeIndexCommand.java
 
b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/cli/LuceneDescribeIndexCommand.java
new file mode 100644
index 0000000..59278ab
--- /dev/null
+++ 
b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/cli/LuceneDescribeIndexCommand.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more 
contributor license
+ * agreements. See the NOTICE file distributed with this work for additional 
information regarding
+ * copyright ownership. The ASF licenses this file to You under the Apache 
License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the 
License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software 
distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 
KIND, either express
+ * or implied. See the License for the specific language governing permissions 
and limitations under
+ * the License.
+ */
+
+package org.apache.geode.cache.lucene.internal.cli;
+
+import org.springframework.shell.core.annotation.CliAvailabilityIndicator;
+import org.springframework.shell.core.annotation.CliCommand;
+import org.springframework.shell.core.annotation.CliOption;
+
+import org.apache.geode.cache.lucene.internal.security.LucenePermission;
+import org.apache.geode.management.cli.CliMetaData;
+import org.apache.geode.management.cli.ConverterHint;
+import org.apache.geode.management.internal.cli.i18n.CliStrings;
+import org.apache.geode.management.internal.cli.result.model.ResultModel;
+import org.apache.geode.security.ResourcePermission;
+
+public class LuceneDescribeIndexCommand extends LuceneCommandBase {
+
+  @CliCommand(value = LuceneCliStrings.LUCENE_DESCRIBE_INDEX,
+      help = LuceneCliStrings.LUCENE_DESCRIBE_INDEX__HELP)
+  @CliMetaData(relatedTopic = {CliStrings.TOPIC_GEODE_REGION, 
CliStrings.TOPIC_GEODE_DATA})
+  public ResultModel describeIndex(
+      @CliOption(key = LuceneCliStrings.LUCENE__INDEX_NAME, mandatory = true,
+          help = LuceneCliStrings.LUCENE_DESCRIBE_INDEX__NAME__HELP) final 
String indexName,
+
+      @CliOption(key = LuceneCliStrings.LUCENE__REGION_PATH, mandatory = true,
+          optionContext = ConverterHint.REGION_PATH,
+          help = LuceneCliStrings.LUCENE_DESCRIBE_INDEX__REGION_HELP) final 
String regionPath)
+      throws Exception {
+
+    authorize(ResourcePermission.Resource.CLUSTER, 
ResourcePermission.Operation.READ,
+        LucenePermission.TARGET);
+    LuceneIndexInfo indexInfo = new LuceneIndexInfo(indexName, regionPath);
+    return toTabularResult(getIndexDetails(indexInfo), true);
+  }
+
+  @CliAvailabilityIndicator(LuceneCliStrings.LUCENE_DESCRIBE_INDEX)
+  public boolean indexCommandsAvailable() {
+    return super.indexCommandsAvailable();
+  }
+}
diff --git 
a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/cli/LuceneDestroyIndexCommand.java
 
b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/cli/LuceneDestroyIndexCommand.java
new file mode 100644
index 0000000..2fae4c1
--- /dev/null
+++ 
b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/cli/LuceneDestroyIndexCommand.java
@@ -0,0 +1,133 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more 
contributor license
+ * agreements. See the NOTICE file distributed with this work for additional 
information regarding
+ * copyright ownership. The ASF licenses this file to You under the Apache 
License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the 
License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software 
distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 
KIND, either express
+ * or implied. See the License for the specific language governing permissions 
and limitations under
+ * the License.
+ */
+
+package org.apache.geode.cache.lucene.internal.cli;
+
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.shell.core.annotation.CliAvailabilityIndicator;
+import org.springframework.shell.core.annotation.CliCommand;
+import org.springframework.shell.core.annotation.CliOption;
+
+import org.apache.geode.cache.execute.ResultCollector;
+import 
org.apache.geode.cache.lucene.internal.cli.functions.LuceneDestroyIndexFunction;
+import org.apache.geode.cache.lucene.internal.security.LucenePermission;
+import org.apache.geode.distributed.DistributedMember;
+import 
org.apache.geode.distributed.internal.InternalConfigurationPersistenceService;
+import org.apache.geode.internal.Version;
+import org.apache.geode.management.cli.CliMetaData;
+import org.apache.geode.management.cli.ConverterHint;
+import org.apache.geode.management.internal.cli.functions.CliFunctionResult;
+import org.apache.geode.management.internal.cli.i18n.CliStrings;
+import org.apache.geode.management.internal.cli.remote.CommandExecutor;
+import org.apache.geode.management.internal.cli.result.model.ResultModel;
+import 
org.apache.geode.management.internal.cli.result.model.TabularResultModel;
+import org.apache.geode.management.internal.configuration.domain.XmlEntity;
+import org.apache.geode.security.ResourcePermission;
+
+public class LuceneDestroyIndexCommand extends LuceneCommandBase {
+
+  private static final LuceneDestroyIndexFunction destroyIndexFunction =
+      new LuceneDestroyIndexFunction();
+
+  @CliCommand(value = LuceneCliStrings.LUCENE_DESTROY_INDEX,
+      help = LuceneCliStrings.LUCENE_DESTROY_INDEX__HELP)
+  @CliMetaData(relatedTopic = {CliStrings.TOPIC_GEODE_REGION, 
CliStrings.TOPIC_GEODE_DATA})
+  public ResultModel destroyIndex(@CliOption(key = 
LuceneCliStrings.LUCENE__INDEX_NAME,
+      help = LuceneCliStrings.LUCENE_DESTROY_INDEX__NAME__HELP) final String 
indexName,
+
+      @CliOption(key = LuceneCliStrings.LUCENE__REGION_PATH, mandatory = true,
+          optionContext = ConverterHint.REGION_PATH,
+          help = LuceneCliStrings.LUCENE_DESTROY_INDEX__REGION_HELP) final 
String regionPath) {
+
+    if (indexName != null && StringUtils.isEmpty(indexName)) {
+      return ResultModel.createInfo(
+          
CliStrings.format(LuceneCliStrings.LUCENE_DESTROY_INDEX__MSG__INDEX_CANNOT_BE_EMPTY));
+    }
+
+    authorize(ResourcePermission.Resource.CLUSTER, 
ResourcePermission.Operation.MANAGE,
+        LucenePermission.TARGET);
+
+    // Get members >= Geode 1.8 (when the new destroy code path went into the 
product)
+    Set<DistributedMember> validVersionMembers =
+        getNormalMembersWithSameOrNewerVersion(Version.GEODE_1_7_0);
+    if (validVersionMembers.isEmpty()) {
+      return ResultModel.createInfo(CliStrings.format(
+          
LuceneCliStrings.LUCENE_DESTROY_INDEX__MSG__COULD_NOT_FIND__MEMBERS_GREATER_THAN_VERSION_0,
+          Version.GEODE_1_7_0));
+    }
+
+    // Execute the destroy index function
+    LuceneDestroyIndexInfo indexInfo = new LuceneDestroyIndexInfo(indexName, 
regionPath);
+    ResultCollector<?, ?> rc =
+        executeFunction(destroyIndexFunction, indexInfo, validVersionMembers);
+
+    // Get the result
+    List<CliFunctionResult> cliFunctionResults = (List<CliFunctionResult>) 
rc.getResult();
+    ResultModel result = getDestroyIndexResult(cliFunctionResults, indexName, 
regionPath);
+
+    // Get and process the xml entity
+    XmlEntity xmlEntity = findXmlEntity(cliFunctionResults);
+
+    // if at least one member returns with successful deletion, we will need 
to update cc
+    InternalConfigurationPersistenceService configurationPersistenceService =
+        getConfigurationPersistenceService();
+    if (xmlEntity != null) {
+      if (configurationPersistenceService == null) {
+        
result.addInfo().addLine(CommandExecutor.SERVICE_NOT_RUNNING_CHANGE_NOT_PERSISTED);
+      } else {
+        configurationPersistenceService.deleteXmlEntity(xmlEntity, null);
+      }
+    }
+
+    return result;
+  }
+
+  private ResultModel getDestroyIndexResult(List<CliFunctionResult> 
cliFunctionResults,
+      String indexName, String regionPath) {
+
+    ResultModel result = new ResultModel();
+    TabularResultModel tabularResult = result.addTable("lucene-indexes");
+    for (CliFunctionResult cliFunctionResult : cliFunctionResults) {
+      tabularResult.accumulate("Member", 
cliFunctionResult.getMemberIdOrName());
+      if (cliFunctionResult.isSuccessful()) {
+        tabularResult.accumulate("Status",
+            indexName == null
+                ? CliStrings.format(
+                    
LuceneCliStrings.LUCENE_DESTROY_INDEX__MSG__SUCCESSFULLY_DESTROYED_INDEXES_FROM_REGION_0,
+                    new Object[] {regionPath})
+                : CliStrings.format(
+                    
LuceneCliStrings.LUCENE_DESTROY_INDEX__MSG__SUCCESSFULLY_DESTROYED_INDEX_0_FROM_REGION_1,
+                    new Object[] {indexName, regionPath}));
+      } else {
+        tabularResult.accumulate("Status", cliFunctionResult.getMessage());
+      }
+    }
+    return result;
+  }
+
+  private XmlEntity findXmlEntity(List<CliFunctionResult> functionResults) {
+    return functionResults.stream().filter(CliFunctionResult::isSuccessful)
+        
.map(CliFunctionResult::getXmlEntity).filter(Objects::nonNull).findFirst().orElse(null);
+  }
+
+  @CliAvailabilityIndicator(LuceneCliStrings.LUCENE_DESTROY_INDEX)
+  public boolean indexCommandsAvailable() {
+    return super.indexCommandsAvailable();
+  }
+}
diff --git 
a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/cli/LuceneIndexCommands.java
 
b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/cli/LuceneIndexCommands.java
deleted file mode 100755
index 0e25672..0000000
--- 
a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/cli/LuceneIndexCommands.java
+++ /dev/null
@@ -1,487 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more 
contributor license
- * agreements. See the NOTICE file distributed with this work for additional 
information regarding
- * copyright ownership. The ASF licenses this file to You under the Apache 
License, Version 2.0 (the
- * "License"); you may not use this file except in compliance with the 
License. You may obtain a
- * copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software 
distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 
KIND, either express
- * or implied. See the License for the specific language governing permissions 
and limitations under
- * the License.
- */
-package org.apache.geode.cache.lucene.internal.cli;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Objects;
-import java.util.Set;
-import java.util.stream.Collectors;
-
-import org.apache.commons.lang3.StringUtils;
-import org.springframework.shell.core.annotation.CliAvailabilityIndicator;
-import org.springframework.shell.core.annotation.CliCommand;
-import org.springframework.shell.core.annotation.CliOption;
-
-import org.apache.geode.cache.execute.Execution;
-import org.apache.geode.cache.execute.Function;
-import org.apache.geode.cache.execute.ResultCollector;
-import 
org.apache.geode.cache.lucene.internal.cli.functions.LuceneCreateIndexFunction;
-import 
org.apache.geode.cache.lucene.internal.cli.functions.LuceneDescribeIndexFunction;
-import 
org.apache.geode.cache.lucene.internal.cli.functions.LuceneDestroyIndexFunction;
-import 
org.apache.geode.cache.lucene.internal.cli.functions.LuceneListIndexFunction;
-import 
org.apache.geode.cache.lucene.internal.cli.functions.LuceneSearchIndexFunction;
-import org.apache.geode.cache.lucene.internal.security.LucenePermission;
-import org.apache.geode.distributed.DistributedMember;
-import 
org.apache.geode.distributed.internal.InternalConfigurationPersistenceService;
-import org.apache.geode.internal.Version;
-import org.apache.geode.internal.cache.InternalCache;
-import org.apache.geode.internal.cache.execute.AbstractExecution;
-import org.apache.geode.management.cli.CliMetaData;
-import org.apache.geode.management.cli.ConverterHint;
-import org.apache.geode.management.cli.Result;
-import org.apache.geode.management.internal.cli.CliUtil;
-import org.apache.geode.management.internal.cli.commands.InternalGfshCommand;
-import org.apache.geode.management.internal.cli.exceptions.UserErrorException;
-import org.apache.geode.management.internal.cli.functions.CliFunctionResult;
-import org.apache.geode.management.internal.cli.i18n.CliStrings;
-import org.apache.geode.management.internal.cli.result.CommandResult;
-import org.apache.geode.management.internal.cli.result.CommandResultException;
-import org.apache.geode.management.internal.cli.result.ResultBuilder;
-import org.apache.geode.management.internal.cli.result.TabularResultData;
-import org.apache.geode.management.internal.cli.shell.Gfsh;
-import org.apache.geode.management.internal.configuration.domain.XmlEntity;
-import org.apache.geode.security.ResourcePermission.Operation;
-import org.apache.geode.security.ResourcePermission.Resource;
-
-/**
- * The LuceneIndexCommands class encapsulates all Geode shell (Gfsh) commands 
related to Lucene
- * indexes defined in Geode.
- *
- * @see InternalGfshCommand
- * @see LuceneIndexDetails
- * @see LuceneListIndexFunction
- */
-@SuppressWarnings("unused")
-public class LuceneIndexCommands extends InternalGfshCommand {
-  private static final LuceneCreateIndexFunction createIndexFunction =
-      new LuceneCreateIndexFunction();
-  private static final LuceneDescribeIndexFunction describeIndexFunction =
-      new LuceneDescribeIndexFunction();
-  private static final LuceneSearchIndexFunction searchIndexFunction =
-      new LuceneSearchIndexFunction();
-  private static final LuceneDestroyIndexFunction destroyIndexFunction =
-      new LuceneDestroyIndexFunction();
-  private List<LuceneSearchResults> searchResults = null;
-
-  @CliCommand(value = LuceneCliStrings.LUCENE_LIST_INDEX,
-      help = LuceneCliStrings.LUCENE_LIST_INDEX__HELP)
-  @CliMetaData(relatedTopic = {CliStrings.TOPIC_GEODE_REGION, 
CliStrings.TOPIC_GEODE_DATA})
-  public Result listIndex(@CliOption(key = 
LuceneCliStrings.LUCENE_LIST_INDEX__STATS,
-      specifiedDefaultValue = "true", unspecifiedDefaultValue = "false",
-      help = LuceneCliStrings.LUCENE_LIST_INDEX__STATS__HELP) final boolean 
stats) {
-
-    authorize(Resource.CLUSTER, Operation.READ, LucenePermission.TARGET);
-    return toTabularResult(getIndexListing(), stats);
-  }
-
-  @SuppressWarnings("unchecked")
-  protected List<LuceneIndexDetails> getIndexListing() {
-    final Execution functionExecutor = 
getMembersFunctionExecutor(getAllMembers());
-
-    if (functionExecutor instanceof AbstractExecution) {
-      ((AbstractExecution) functionExecutor).setIgnoreDepartedMembers(true);
-    }
-
-    final ResultCollector resultsCollector =
-        functionExecutor.execute(new LuceneListIndexFunction());
-    final List<Set<LuceneIndexDetails>> results =
-        (List<Set<LuceneIndexDetails>>) resultsCollector.getResult();
-
-    List<LuceneIndexDetails> sortedResults =
-        
results.stream().flatMap(Collection::stream).sorted().collect(Collectors.toList());
-    LinkedHashSet<LuceneIndexDetails> uniqResults = new LinkedHashSet<>();
-    uniqResults.addAll(sortedResults);
-    sortedResults.clear();
-    sortedResults.addAll(uniqResults);
-    return sortedResults;
-  }
-
-  protected Result toTabularResult(final List<LuceneIndexDetails> 
indexDetailsList, boolean stats) {
-    if (!indexDetailsList.isEmpty()) {
-      final TabularResultData indexData = 
ResultBuilder.createTabularResultData();
-
-      for (final LuceneIndexDetails indexDetails : indexDetailsList) {
-        indexData.accumulate("Index Name", indexDetails.getIndexName());
-        indexData.accumulate("Region Path", indexDetails.getRegionPath());
-        indexData.accumulate("Server Name", indexDetails.getServerName());
-        indexData.accumulate("Indexed Fields", 
indexDetails.getSearchableFieldNamesString());
-        indexData.accumulate("Field Analyzer", 
indexDetails.getFieldAnalyzersString());
-        indexData.accumulate("Serializer", indexDetails.getSerializerString());
-        indexData.accumulate("Status", indexDetails.getStatus().toString());
-
-        if (stats) {
-          LuceneIndexStatus luceneIndexStatus = indexDetails.getStatus();
-          if (luceneIndexStatus == LuceneIndexStatus.NOT_INITIALIZED
-              || luceneIndexStatus == LuceneIndexStatus.INDEXING_IN_PROGRESS) {
-            indexData.accumulate("Query Executions", "NA");
-            indexData.accumulate("Updates", "NA");
-            indexData.accumulate("Commits", "NA");
-            indexData.accumulate("Documents", "NA");
-          } else {
-            indexData.accumulate("Query Executions",
-                indexDetails.getIndexStats().get("queryExecutions"));
-            indexData.accumulate("Updates", 
indexDetails.getIndexStats().get("updates"));
-            indexData.accumulate("Commits", 
indexDetails.getIndexStats().get("commits"));
-            indexData.accumulate("Documents", 
indexDetails.getIndexStats().get("documents"));
-          }
-        }
-      }
-      return ResultBuilder.buildResult(indexData);
-    } else {
-      return ResultBuilder
-          
.createInfoResult(LuceneCliStrings.LUCENE_LIST_INDEX__INDEXES_NOT_FOUND_MESSAGE);
-    }
-  }
-
-  /**
-   * On the server, we also verify the resource operation permissions 
CLUSTER:WRITE:DISK
-   */
-  @CliCommand(value = LuceneCliStrings.LUCENE_CREATE_INDEX,
-      help = LuceneCliStrings.LUCENE_CREATE_INDEX__HELP)
-  @CliMetaData(relatedTopic = {CliStrings.TOPIC_GEODE_REGION, 
CliStrings.TOPIC_GEODE_DATA})
-  // TODO : Add optionContext for indexName
-  public Result createIndex(@CliOption(key = 
LuceneCliStrings.LUCENE__INDEX_NAME, mandatory = true,
-      help = LuceneCliStrings.LUCENE_CREATE_INDEX__NAME__HELP) final String 
indexName,
-
-      @CliOption(key = LuceneCliStrings.LUCENE__REGION_PATH, mandatory = true,
-          optionContext = ConverterHint.REGION_PATH,
-          help = LuceneCliStrings.LUCENE_CREATE_INDEX__REGION_HELP) final 
String regionPath,
-
-      @CliOption(key = LuceneCliStrings.LUCENE_CREATE_INDEX__FIELD, mandatory 
= true,
-          help = LuceneCliStrings.LUCENE_CREATE_INDEX__FIELD_HELP) final 
String[] fields,
-
-      @CliOption(key = LuceneCliStrings.LUCENE_CREATE_INDEX__ANALYZER,
-          help = LuceneCliStrings.LUCENE_CREATE_INDEX__ANALYZER_HELP) final 
String[] analyzers,
-      @CliOption(key = LuceneCliStrings.LUCENE_CREATE_INDEX__SERIALIZER,
-          help = LuceneCliStrings.LUCENE_CREATE_INDEX__SERIALIZER_HELP) final 
String serializer)
-      throws CommandResultException {
-
-    Result result;
-    // Every lucene index potentially writes to disk.
-    authorize(Resource.CLUSTER, Operation.MANAGE, LucenePermission.TARGET);
-
-    final InternalCache cache = (InternalCache) getCache();
-
-    // trim fields for any leading trailing spaces.
-    String[] trimmedFields = 
Arrays.stream(fields).map(String::trim).toArray(String[]::new);
-    LuceneIndexInfo indexInfo =
-        new LuceneIndexInfo(indexName, regionPath, trimmedFields, analyzers, 
serializer);
-
-    final ResultCollector<?, ?> rc =
-        this.executeFunctionOnAllMembers(createIndexFunction, indexInfo);
-    final List<CliFunctionResult> funcResults = (List<CliFunctionResult>) 
rc.getResult();
-    final XmlEntity xmlEntity = 
funcResults.stream().filter(CliFunctionResult::isSuccessful)
-        
.map(CliFunctionResult::getXmlEntity).filter(Objects::nonNull).findFirst().orElse(null);
-    final TabularResultData tabularResult = 
ResultBuilder.createTabularResultData();
-    for (final CliFunctionResult cliFunctionResult : funcResults) {
-      tabularResult.accumulate("Member", 
cliFunctionResult.getMemberIdOrName());
-
-      if (cliFunctionResult.isSuccessful()) {
-        tabularResult.accumulate("Status", "Successfully created lucene 
index");
-      } else {
-        tabularResult.accumulate("Status", "Failed: " + 
cliFunctionResult.getMessage());
-      }
-    }
-
-    result = ResultBuilder.buildResult(tabularResult);
-    if (xmlEntity != null) {
-      persistClusterConfiguration(result, () -> {
-        ((InternalConfigurationPersistenceService) 
getConfigurationPersistenceService())
-            .addXmlEntity(xmlEntity, null);
-      });
-    }
-    return result;
-  }
-
-  @CliCommand(value = LuceneCliStrings.LUCENE_DESCRIBE_INDEX,
-      help = LuceneCliStrings.LUCENE_DESCRIBE_INDEX__HELP)
-  @CliMetaData(relatedTopic = {CliStrings.TOPIC_GEODE_REGION, 
CliStrings.TOPIC_GEODE_DATA})
-  public Result describeIndex(
-      @CliOption(key = LuceneCliStrings.LUCENE__INDEX_NAME, mandatory = true,
-          help = LuceneCliStrings.LUCENE_DESCRIBE_INDEX__NAME__HELP) final 
String indexName,
-
-      @CliOption(key = LuceneCliStrings.LUCENE__REGION_PATH, mandatory = true,
-          optionContext = ConverterHint.REGION_PATH,
-          help = LuceneCliStrings.LUCENE_DESCRIBE_INDEX__REGION_HELP) final 
String regionPath)
-      throws Exception {
-
-    authorize(Resource.CLUSTER, Operation.READ, LucenePermission.TARGET);
-    LuceneIndexInfo indexInfo = new LuceneIndexInfo(indexName, regionPath);
-    return toTabularResult(getIndexDetails(indexInfo), true);
-  }
-
-  @SuppressWarnings("unchecked")
-  protected List<LuceneIndexDetails> getIndexDetails(LuceneIndexInfo 
indexInfo) throws Exception {
-    final ResultCollector<?, ?> rc =
-        executeFunctionOnRegion(describeIndexFunction, indexInfo, true);
-    final List<LuceneIndexDetails> funcResults = (List<LuceneIndexDetails>) 
rc.getResult();
-    return 
funcResults.stream().filter(Objects::nonNull).collect(Collectors.toList());
-  }
-
-  /**
-   * Internally, we verify the resource operation permissions 
DATA:READ:[RegionName]
-   */
-  @CliCommand(value = LuceneCliStrings.LUCENE_SEARCH_INDEX,
-      help = LuceneCliStrings.LUCENE_SEARCH_INDEX__HELP)
-  @CliMetaData(relatedTopic = {CliStrings.TOPIC_GEODE_REGION, 
CliStrings.TOPIC_GEODE_DATA})
-  public Result searchIndex(@CliOption(key = 
LuceneCliStrings.LUCENE__INDEX_NAME, mandatory = true,
-      help = LuceneCliStrings.LUCENE_SEARCH_INDEX__NAME__HELP) final String 
indexName,
-
-      @CliOption(key = LuceneCliStrings.LUCENE__REGION_PATH, mandatory = true,
-          optionContext = ConverterHint.REGION_PATH,
-          help = LuceneCliStrings.LUCENE_SEARCH_INDEX__REGION_HELP) final 
String regionPath,
-
-      @CliOption(
-          key = {LuceneCliStrings.LUCENE_SEARCH_INDEX__QUERY_STRING,
-              LuceneCliStrings.LUCENE_SEARCH_INDEX__QUERY_STRINGS},
-          mandatory = true,
-          help = LuceneCliStrings.LUCENE_SEARCH_INDEX__QUERY_STRING__HELP) 
final String queryString,
-
-      @CliOption(key = LuceneCliStrings.LUCENE_SEARCH_INDEX__DEFAULT_FIELD, 
mandatory = true,
-          help = LuceneCliStrings.LUCENE_SEARCH_INDEX__DEFAULT_FIELD__HELP) 
final String defaultField,
-
-      @CliOption(key = LuceneCliStrings.LUCENE_SEARCH_INDEX__LIMIT, 
unspecifiedDefaultValue = "-1",
-          help = LuceneCliStrings.LUCENE_SEARCH_INDEX__LIMIT__HELP) final int 
limit,
-
-      @CliOption(key = LuceneCliStrings.LUCENE_SEARCH_INDEX__KEYSONLY,
-          unspecifiedDefaultValue = "false",
-          help = LuceneCliStrings.LUCENE_SEARCH_INDEX__KEYSONLY__HELP) boolean 
keysOnly)
-      throws Exception {
-    authorize(Resource.DATA, Operation.READ, regionPath);
-    LuceneQueryInfo queryInfo =
-        new LuceneQueryInfo(indexName, regionPath, queryString, defaultField, 
limit, keysOnly);
-    int pageSize = Integer.MAX_VALUE;
-    searchResults = getSearchResults(queryInfo);
-    return displayResults(pageSize, keysOnly);
-
-  }
-
-  @CliCommand(value = LuceneCliStrings.LUCENE_DESTROY_INDEX,
-      help = LuceneCliStrings.LUCENE_DESTROY_INDEX__HELP)
-  @CliMetaData(relatedTopic = {CliStrings.TOPIC_GEODE_REGION, 
CliStrings.TOPIC_GEODE_DATA})
-  public Result destroyIndex(@CliOption(key = 
LuceneCliStrings.LUCENE__INDEX_NAME,
-      help = LuceneCliStrings.LUCENE_DESTROY_INDEX__NAME__HELP) final String 
indexName,
-
-      @CliOption(key = LuceneCliStrings.LUCENE__REGION_PATH, mandatory = true,
-          optionContext = ConverterHint.REGION_PATH,
-          help = LuceneCliStrings.LUCENE_DESTROY_INDEX__REGION_HELP) final 
String regionPath) {
-
-    if (indexName != null && StringUtils.isEmpty(indexName)) {
-      return ResultBuilder.createInfoResult(
-          
CliStrings.format(LuceneCliStrings.LUCENE_DESTROY_INDEX__MSG__INDEX_CANNOT_BE_EMPTY));
-    }
-
-    authorize(Resource.CLUSTER, Operation.MANAGE, LucenePermission.TARGET);
-
-    // Get members >= Geode 1.8 (when the new destroy code path went into the 
product)
-    Set<DistributedMember> validVersionMembers =
-        getNormalMembersWithSameOrNewerVersion(Version.GEODE_1_7_0);
-    if (validVersionMembers.isEmpty()) {
-      return ResultBuilder.createInfoResult(CliStrings.format(
-          
LuceneCliStrings.LUCENE_DESTROY_INDEX__MSG__COULD_NOT_FIND__MEMBERS_GREATER_THAN_VERSION_0,
-          Version.GEODE_1_7_0));
-    }
-
-    // Execute the destroy index function
-    LuceneDestroyIndexInfo indexInfo = new LuceneDestroyIndexInfo(indexName, 
regionPath);
-    ResultCollector<?, ?> rc =
-        executeFunction(destroyIndexFunction, indexInfo, validVersionMembers);
-
-    // Get the result
-    List<CliFunctionResult> cliFunctionResults = (List<CliFunctionResult>) 
rc.getResult();
-    Result result = getDestroyIndexResult(cliFunctionResults, indexName, 
regionPath);
-
-    // Get and process the xml entity
-    XmlEntity xmlEntity = findXmlEntity(cliFunctionResults);
-    if (xmlEntity != null) {
-      persistClusterConfiguration(result, () -> {
-        // Delete the xml entity to remove the index(es) in all groups
-        ((InternalConfigurationPersistenceService) 
getConfigurationPersistenceService())
-            .deleteXmlEntity(xmlEntity, null);
-      });
-    }
-
-    return result;
-  }
-
-  private Result getDestroyIndexResult(List<CliFunctionResult> 
cliFunctionResults, String indexName,
-      String regionPath) {
-    final TabularResultData tabularResult = 
ResultBuilder.createTabularResultData();
-    for (CliFunctionResult cliFunctionResult : cliFunctionResults) {
-      tabularResult.accumulate("Member", 
cliFunctionResult.getMemberIdOrName());
-      if (cliFunctionResult.isSuccessful()) {
-        tabularResult.accumulate("Status",
-            indexName == null
-                ? CliStrings.format(
-                    
LuceneCliStrings.LUCENE_DESTROY_INDEX__MSG__SUCCESSFULLY_DESTROYED_INDEXES_FROM_REGION_0,
-                    new Object[] {regionPath})
-                : CliStrings.format(
-                    
LuceneCliStrings.LUCENE_DESTROY_INDEX__MSG__SUCCESSFULLY_DESTROYED_INDEX_0_FROM_REGION_1,
-                    new Object[] {indexName, regionPath}));
-      } else {
-        tabularResult.accumulate("Status", cliFunctionResult.getMessage());
-      }
-    }
-    return ResultBuilder.buildResult(tabularResult);
-  }
-
-  private Result displayResults(int pageSize, boolean keysOnly) throws 
Exception {
-    if (searchResults.size() == 0) {
-      return ResultBuilder
-          
.createInfoResult(LuceneCliStrings.LUCENE_SEARCH_INDEX__NO_RESULTS_MESSAGE);
-    }
-
-    Gfsh gfsh = initGfsh();
-    boolean pagination = searchResults.size() > pageSize;
-    int fromIndex = 0;
-    int toIndex = pageSize < searchResults.size() ? pageSize : 
searchResults.size();
-    int currentPage = 1;
-    int totalPages = (int) Math.ceil((float) searchResults.size() / pageSize);
-    boolean skipDisplay = false;
-    String step = null;
-    do {
-
-      if (!skipDisplay) {
-        CommandResult commandResult = (CommandResult) getResults(fromIndex, 
toIndex, keysOnly);
-        if (!pagination) {
-          return commandResult;
-        }
-        Gfsh.println();
-        while (commandResult.hasNextLine()) {
-          gfsh.printAsInfo(commandResult.nextLine());
-        }
-        gfsh.printAsInfo("\t\tPage " + currentPage + " of " + totalPages);
-        String message = ("Press n to move to next page, q to quit and p to 
previous page : ");
-        step = gfsh.interact(message);
-      }
-
-      switch (step) {
-        case "n": {
-          if (currentPage == totalPages) {
-            gfsh.printAsInfo("No more results to display.");
-            step = gfsh.interact("Press p to move to last page and q to 
quit.");
-            skipDisplay = true;
-            continue;
-          }
-
-          if (skipDisplay) {
-            skipDisplay = false;
-          } else {
-            currentPage++;
-            int current = fromIndex;
-            fromIndex = toIndex;
-            toIndex = (pageSize + fromIndex >= searchResults.size()) ? 
searchResults.size()
-                : pageSize + fromIndex;
-          }
-          break;
-        }
-        case "p": {
-          if (currentPage == 1) {
-            gfsh.printAsInfo("At the top of the search results.");
-            step = gfsh.interact("Press n to move to the first page and q to 
quit.");
-            skipDisplay = true;
-            continue;
-          }
-
-          if (skipDisplay) {
-            skipDisplay = false;
-          } else {
-            currentPage--;
-            int current = fromIndex;
-            toIndex = fromIndex;
-            fromIndex = current - pageSize <= 0 ? 0 : current - pageSize;
-          }
-          break;
-        }
-        case "q":
-          return ResultBuilder.createInfoResult("Search complete.");
-        default:
-          Gfsh.println("Invalid option");
-          break;
-      }
-    } while (true);
-  }
-
-  protected Gfsh initGfsh() {
-    return Gfsh.getCurrentInstance();
-  }
-
-  private List<LuceneSearchResults> getSearchResults(final LuceneQueryInfo 
queryInfo)
-      throws Exception {
-    final String[] groups = {};
-    final ResultCollector<?, ?> rc = this.executeSearch(queryInfo);
-    final List<Set<LuceneSearchResults>> functionResults =
-        (List<Set<LuceneSearchResults>>) rc.getResult();
-
-    return functionResults.stream().flatMap(Collection::stream).sorted()
-        .collect(Collectors.toList());
-  }
-
-  private Result getResults(int fromIndex, int toIndex, boolean keysonly) 
throws Exception {
-    final TabularResultData data = ResultBuilder.createTabularResultData();
-    for (int i = fromIndex; i < toIndex; i++) {
-      if (!searchResults.get(i).getExceptionFlag()) {
-        data.accumulate("key", searchResults.get(i).getKey());
-        if (!keysonly) {
-          data.accumulate("value", searchResults.get(i).getValue());
-          data.accumulate("score", searchResults.get(i).getScore());
-        }
-      } else {
-        throw new 
UserErrorException(searchResults.get(i).getExceptionMessage());
-      }
-    }
-    return ResultBuilder.buildResult(data);
-  }
-
-  protected ResultCollector<?, ?> executeFunctionOnAllMembers(Function 
function,
-      final LuceneFunctionSerializable functionArguments) throws 
IllegalArgumentException {
-    Set<DistributedMember> targetMembers = getAllNormalMembers();
-    return executeFunction(function, functionArguments, targetMembers);
-  }
-
-  protected ResultCollector<?, ?> executeSearch(final LuceneQueryInfo 
queryInfo) throws Exception {
-    return executeFunctionOnRegion(searchIndexFunction, queryInfo, false);
-  }
-
-  protected ResultCollector<?, ?> executeFunctionOnRegion(Function function,
-      LuceneFunctionSerializable functionArguments, boolean returnAllMembers) {
-    Set<DistributedMember> targetMembers = CliUtil.getRegionAssociatedMembers(
-        functionArguments.getRegionPath(), (InternalCache) getCache(), 
returnAllMembers);
-    if (targetMembers.isEmpty()) {
-      throw new UserErrorException(CliStrings.format(
-          
LuceneCliStrings.LUCENE_DESTROY_INDEX__MSG__COULDNOT_FIND_MEMBERS_FOR_REGION_0,
-          new Object[] {functionArguments.getRegionPath()}));
-    }
-    return executeFunction(function, functionArguments, targetMembers);
-  }
-
-  @CliAvailabilityIndicator({LuceneCliStrings.LUCENE_SEARCH_INDEX,
-      LuceneCliStrings.LUCENE_CREATE_INDEX, 
LuceneCliStrings.LUCENE_DESCRIBE_INDEX,
-      LuceneCliStrings.LUCENE_LIST_INDEX, 
LuceneCliStrings.LUCENE_DESTROY_INDEX})
-  public boolean indexCommandsAvailable() {
-    Gfsh gfsh = Gfsh.getCurrentInstance();
-
-    // command should always be available on the server
-    if (gfsh == null) {
-      return true;
-    }
-
-    // if in gfshVM, only when gfsh is connected and ready
-    return gfsh.isConnectedAndReady();
-  }
-}
diff --git 
a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/cli/LuceneListIndexCommand.java
 
b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/cli/LuceneListIndexCommand.java
new file mode 100644
index 0000000..800f3e1
--- /dev/null
+++ 
b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/cli/LuceneListIndexCommand.java
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more 
contributor license
+ * agreements. See the NOTICE file distributed with this work for additional 
information regarding
+ * copyright ownership. The ASF licenses this file to You under the Apache 
License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the 
License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software 
distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 
KIND, either express
+ * or implied. See the License for the specific language governing permissions 
and limitations under
+ * the License.
+ */
+
+package org.apache.geode.cache.lucene.internal.cli;
+
+import java.util.Collection;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import org.springframework.shell.core.annotation.CliAvailabilityIndicator;
+import org.springframework.shell.core.annotation.CliCommand;
+import org.springframework.shell.core.annotation.CliOption;
+
+import org.apache.geode.cache.execute.Execution;
+import org.apache.geode.cache.execute.ResultCollector;
+import 
org.apache.geode.cache.lucene.internal.cli.functions.LuceneListIndexFunction;
+import org.apache.geode.cache.lucene.internal.security.LucenePermission;
+import org.apache.geode.internal.cache.execute.AbstractExecution;
+import org.apache.geode.management.cli.CliMetaData;
+import org.apache.geode.management.internal.cli.i18n.CliStrings;
+import org.apache.geode.management.internal.cli.result.model.ResultModel;
+import org.apache.geode.security.ResourcePermission;
+
+public class LuceneListIndexCommand extends LuceneCommandBase {
+
+  @CliCommand(value = LuceneCliStrings.LUCENE_LIST_INDEX,
+      help = LuceneCliStrings.LUCENE_LIST_INDEX__HELP)
+  @CliMetaData(relatedTopic = {CliStrings.TOPIC_GEODE_REGION, 
CliStrings.TOPIC_GEODE_DATA})
+  public ResultModel listIndex(@CliOption(key = 
LuceneCliStrings.LUCENE_LIST_INDEX__STATS,
+      specifiedDefaultValue = "true", unspecifiedDefaultValue = "false",
+      help = LuceneCliStrings.LUCENE_LIST_INDEX__STATS__HELP) final boolean 
stats) {
+
+    authorize(ResourcePermission.Resource.CLUSTER, 
ResourcePermission.Operation.READ,
+        LucenePermission.TARGET);
+    return toTabularResult(getIndexListing(), stats);
+  }
+
+  @SuppressWarnings("unchecked")
+  protected List<LuceneIndexDetails> getIndexListing() {
+    final Execution functionExecutor = 
getMembersFunctionExecutor(getAllMembers());
+
+    if (functionExecutor instanceof AbstractExecution) {
+      ((AbstractExecution) functionExecutor).setIgnoreDepartedMembers(true);
+    }
+
+    final ResultCollector resultsCollector =
+        functionExecutor.execute(new LuceneListIndexFunction());
+    final List<Set<LuceneIndexDetails>> results =
+        (List<Set<LuceneIndexDetails>>) resultsCollector.getResult();
+
+    List<LuceneIndexDetails> sortedResults =
+        
results.stream().flatMap(Collection::stream).sorted().collect(Collectors.toList());
+    LinkedHashSet<LuceneIndexDetails> uniqResults = new LinkedHashSet<>();
+    uniqResults.addAll(sortedResults);
+    sortedResults.clear();
+    sortedResults.addAll(uniqResults);
+    return sortedResults;
+  }
+
+  @CliAvailabilityIndicator({
+      LuceneCliStrings.LUCENE_LIST_INDEX,
+  })
+  public boolean indexCommandsAvailable() {
+    return super.indexCommandsAvailable();
+  }
+}
diff --git 
a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/cli/LuceneSearchIndexCommand.java
 
b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/cli/LuceneSearchIndexCommand.java
new file mode 100644
index 0000000..0373e63
--- /dev/null
+++ 
b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/cli/LuceneSearchIndexCommand.java
@@ -0,0 +1,207 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more 
contributor license
+ * agreements. See the NOTICE file distributed with this work for additional 
information regarding
+ * copyright ownership. The ASF licenses this file to You under the Apache 
License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the 
License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software 
distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 
KIND, either express
+ * or implied. See the License for the specific language governing permissions 
and limitations under
+ * the License.
+ */
+
+package org.apache.geode.cache.lucene.internal.cli;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import org.springframework.shell.core.annotation.CliAvailabilityIndicator;
+import org.springframework.shell.core.annotation.CliCommand;
+import org.springframework.shell.core.annotation.CliOption;
+
+import org.apache.geode.cache.execute.ResultCollector;
+import 
org.apache.geode.cache.lucene.internal.cli.functions.LuceneSearchIndexFunction;
+import org.apache.geode.management.cli.CliMetaData;
+import org.apache.geode.management.cli.ConverterHint;
+import org.apache.geode.management.internal.cli.exceptions.UserErrorException;
+import org.apache.geode.management.internal.cli.i18n.CliStrings;
+import org.apache.geode.management.internal.cli.result.CommandResult;
+import org.apache.geode.management.internal.cli.result.ModelCommandResult;
+import org.apache.geode.management.internal.cli.result.model.ResultModel;
+import 
org.apache.geode.management.internal.cli.result.model.TabularResultModel;
+import org.apache.geode.management.internal.cli.shell.Gfsh;
+import org.apache.geode.security.ResourcePermission;
+
+public class LuceneSearchIndexCommand extends LuceneCommandBase {
+
+  private static final LuceneSearchIndexFunction searchIndexFunction =
+      new LuceneSearchIndexFunction();
+
+  private List<LuceneSearchResults> searchResults = null;
+
+  /**
+   * Internally, we verify the resource operation permissions 
DATA:READ:[RegionName]
+   */
+  @CliCommand(value = LuceneCliStrings.LUCENE_SEARCH_INDEX,
+      help = LuceneCliStrings.LUCENE_SEARCH_INDEX__HELP)
+  @CliMetaData(relatedTopic = {CliStrings.TOPIC_GEODE_REGION, 
CliStrings.TOPIC_GEODE_DATA})
+  public ResultModel searchIndex(
+      @CliOption(key = LuceneCliStrings.LUCENE__INDEX_NAME, mandatory = true,
+          help = LuceneCliStrings.LUCENE_SEARCH_INDEX__NAME__HELP) final 
String indexName,
+
+      @CliOption(key = LuceneCliStrings.LUCENE__REGION_PATH, mandatory = true,
+          optionContext = ConverterHint.REGION_PATH,
+          help = LuceneCliStrings.LUCENE_SEARCH_INDEX__REGION_HELP) final 
String regionPath,
+
+      @CliOption(
+          key = {LuceneCliStrings.LUCENE_SEARCH_INDEX__QUERY_STRING,
+              LuceneCliStrings.LUCENE_SEARCH_INDEX__QUERY_STRINGS},
+          mandatory = true,
+          help = LuceneCliStrings.LUCENE_SEARCH_INDEX__QUERY_STRING__HELP) 
final String queryString,
+
+      @CliOption(key = LuceneCliStrings.LUCENE_SEARCH_INDEX__DEFAULT_FIELD, 
mandatory = true,
+          help = LuceneCliStrings.LUCENE_SEARCH_INDEX__DEFAULT_FIELD__HELP) 
final String defaultField,
+
+      @CliOption(key = LuceneCliStrings.LUCENE_SEARCH_INDEX__LIMIT, 
unspecifiedDefaultValue = "-1",
+          help = LuceneCliStrings.LUCENE_SEARCH_INDEX__LIMIT__HELP) final int 
limit,
+
+      @CliOption(key = LuceneCliStrings.LUCENE_SEARCH_INDEX__KEYSONLY,
+          unspecifiedDefaultValue = "false",
+          help = LuceneCliStrings.LUCENE_SEARCH_INDEX__KEYSONLY__HELP) boolean 
keysOnly)
+      throws Exception {
+    authorize(ResourcePermission.Resource.DATA, 
ResourcePermission.Operation.READ, regionPath);
+    LuceneQueryInfo queryInfo =
+        new LuceneQueryInfo(indexName, regionPath, queryString, defaultField, 
limit, keysOnly);
+    searchResults = getSearchResults(queryInfo);
+
+    return displayResults(getPageSize(), keysOnly);
+  }
+
+  protected int getPageSize() {
+    return Integer.MAX_VALUE;
+  }
+
+  private List<LuceneSearchResults> getSearchResults(final LuceneQueryInfo 
queryInfo)
+      throws Exception {
+    final ResultCollector<?, ?> rc = this.executeSearch(queryInfo);
+    final List<Set<LuceneSearchResults>> functionResults =
+        (List<Set<LuceneSearchResults>>) rc.getResult();
+
+    return functionResults.stream().flatMap(Collection::stream).sorted()
+        .collect(Collectors.toList());
+  }
+
+  protected ResultCollector<?, ?> executeSearch(final LuceneQueryInfo 
queryInfo) throws Exception {
+    return executeFunctionOnRegion(searchIndexFunction, queryInfo, false);
+  }
+
+  private ResultModel getResults(int fromIndex, int toIndex, boolean keysonly) 
throws Exception {
+    ResultModel result = new ResultModel();
+    TabularResultModel table = result.addTable("lucene-indexes");
+    for (int i = fromIndex; i < toIndex; i++) {
+      if (!searchResults.get(i).getExceptionFlag()) {
+        table.accumulate("key", searchResults.get(i).getKey());
+        if (!keysonly) {
+          table.accumulate("value", searchResults.get(i).getValue());
+          table.accumulate("score", 
Float.toString(searchResults.get(i).getScore()));
+        }
+      } else {
+        throw new 
UserErrorException(searchResults.get(i).getExceptionMessage());
+      }
+    }
+    return result;
+  }
+
+  protected Gfsh initGfsh() {
+    return Gfsh.getCurrentInstance();
+  }
+
+  private ResultModel displayResults(int pageSize, boolean keysOnly) throws 
Exception {
+    if (searchResults.size() == 0) {
+      return 
ResultModel.createInfo(LuceneCliStrings.LUCENE_SEARCH_INDEX__NO_RESULTS_MESSAGE);
+    }
+
+    Gfsh gfsh = initGfsh();
+    boolean pagination = searchResults.size() > pageSize;
+    int fromIndex = 0;
+    int toIndex = pageSize < searchResults.size() ? pageSize : 
searchResults.size();
+    int currentPage = 1;
+    int totalPages = (int) Math.ceil((float) searchResults.size() / pageSize);
+    boolean skipDisplay = false;
+    String step = null;
+    do {
+
+      if (!skipDisplay) {
+        ResultModel resultModel = getResults(fromIndex, toIndex, keysOnly);
+        if (!pagination) {
+          return resultModel;
+        }
+        Gfsh.println();
+
+        CommandResult commandResult = new ModelCommandResult(resultModel);
+        while (commandResult.hasNextLine()) {
+          gfsh.printAsInfo(commandResult.nextLine());
+        }
+
+        gfsh.printAsInfo("\t\tPage " + currentPage + " of " + totalPages);
+        String message = ("Press n to move to next page, q to quit and p to 
previous page : ");
+        step = gfsh.interact(message);
+      }
+
+      switch (step) {
+        case "n": {
+          if (currentPage == totalPages) {
+            gfsh.printAsInfo("No more results to display.");
+            step = gfsh.interact("Press p to move to last page and q to 
quit.");
+            skipDisplay = true;
+            continue;
+          }
+
+          if (skipDisplay) {
+            skipDisplay = false;
+          } else {
+            currentPage++;
+            fromIndex = toIndex;
+            toIndex = (pageSize + fromIndex >= searchResults.size()) ? 
searchResults.size()
+                : pageSize + fromIndex;
+          }
+          break;
+        }
+        case "p": {
+          if (currentPage == 1) {
+            gfsh.printAsInfo("At the top of the search results.");
+            step = gfsh.interact("Press n to move to the first page and q to 
quit.");
+            skipDisplay = true;
+            continue;
+          }
+
+          if (skipDisplay) {
+            skipDisplay = false;
+          } else {
+            currentPage--;
+            int current = fromIndex;
+            toIndex = fromIndex;
+            fromIndex = current - pageSize <= 0 ? 0 : current - pageSize;
+          }
+          break;
+        }
+        case "q":
+          return ResultModel.createInfo("Search complete.");
+        default:
+          Gfsh.println("Invalid option");
+          break;
+      }
+    } while (true);
+  }
+
+
+  @CliAvailabilityIndicator(LuceneCliStrings.LUCENE_SEARCH_INDEX)
+  public boolean indexCommandsAvailable() {
+    return super.indexCommandsAvailable();
+  }
+}
diff --git 
a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/cli/LuceneSearchResults.java
 
b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/cli/LuceneSearchResults.java
index 95167d5..0411c6b 100644
--- 
a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/cli/LuceneSearchResults.java
+++ 
b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/cli/LuceneSearchResults.java
@@ -59,7 +59,7 @@ public class LuceneSearchResults<K, V> implements 
Comparable<LuceneSearchResults
     // result.
     // This comparator is used to list results, order will be higher to lower 
on score. (Ref.
     // GEODE-3206)
-    return Float.compare(getScore(), searchResults.getScore()) * -1;
+    return Float.compare(searchResults.getScore(), getScore());
   }
 
   public boolean getExceptionFlag() {
diff --git 
a/geode-lucene/src/main/resources/META-INF/services/org.springframework.shell.core.CommandMarker
 
b/geode-lucene/src/main/resources/META-INF/services/org.springframework.shell.core.CommandMarker
index 0879e15..b7e5ba3 100644
--- 
a/geode-lucene/src/main/resources/META-INF/services/org.springframework.shell.core.CommandMarker
+++ 
b/geode-lucene/src/main/resources/META-INF/services/org.springframework.shell.core.CommandMarker
@@ -1,2 +1,6 @@
 # Lucene Extensions command
-org.apache.geode.cache.lucene.internal.cli.LuceneIndexCommands
\ No newline at end of file
+org.apache.geode.cache.lucene.internal.cli.LuceneCreateIndexCommand
+org.apache.geode.cache.lucene.internal.cli.LuceneDescribeIndexCommand
+org.apache.geode.cache.lucene.internal.cli.LuceneDestroyIndexCommand
+org.apache.geode.cache.lucene.internal.cli.LuceneListIndexCommand
+org.apache.geode.cache.lucene.internal.cli.LuceneSearchIndexCommand
\ No newline at end of file
diff --git 
a/geode-lucene/src/test/java/org/apache/geode/cache/lucene/internal/cli/LuceneIndexCommandsJUnitTest.java
 
b/geode-lucene/src/test/java/org/apache/geode/cache/lucene/internal/cli/LuceneIndexCommandsJUnitTest.java
index 2202d8c..88b21bd 100644
--- 
a/geode-lucene/src/test/java/org/apache/geode/cache/lucene/internal/cli/LuceneIndexCommandsJUnitTest.java
+++ 
b/geode-lucene/src/test/java/org/apache/geode/cache/lucene/internal/cli/LuceneIndexCommandsJUnitTest.java
@@ -14,8 +14,6 @@
  */
 package org.apache.geode.cache.lucene.internal.cli;
 
-import static org.apache.commons.lang3.SystemUtils.LINE_SEPARATOR;
-import static 
org.apache.geode.management.internal.cli.result.ResultData.TYPE_TABULAR;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.mockito.ArgumentMatchers.anySet;
 import static org.mockito.Mockito.any;
@@ -43,7 +41,6 @@ import org.apache.lucene.analysis.Analyzer;
 import org.apache.lucene.analysis.core.KeywordAnalyzer;
 import org.apache.lucene.analysis.standard.StandardAnalyzer;
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
 import org.junit.runner.RunWith;
@@ -71,18 +68,20 @@ import 
org.apache.geode.management.internal.cli.i18n.CliStrings;
 import org.apache.geode.management.internal.cli.result.CommandResult;
 import org.apache.geode.management.internal.cli.result.ResultBuilder;
 import org.apache.geode.management.internal.cli.result.TabularResultData;
+import org.apache.geode.management.internal.cli.result.model.ResultModel;
+import 
org.apache.geode.management.internal.cli.result.model.TabularResultModel;
 import org.apache.geode.management.internal.cli.shell.Gfsh;
 import org.apache.geode.test.junit.categories.LuceneTest;
 
 /**
  * The LuceneIndexCommandsJUnitTest class is a test suite of test cases 
testing the contract and
- * functionality of the LuceneIndexCommands class.
+ * functionality of the Lucene Index Commands.
  *
- * @see LuceneIndexCommands
- * @see LuceneIndexDetails
- * @see LuceneListIndexFunction
- * @see org.junit.Test
- * @since GemFire 7.0
+ * @see LuceneCreateIndexCommand
+ * @see LuceneDescribeIndexCommand
+ * @see LuceneDestroyIndexCommand
+ * @see LuceneListIndexCommand
+ * @see LuceneSearchIndexCommand
  */
 @Category(LuceneTest.class)
 @RunWith(JUnitParamsRunner.class)
@@ -125,21 +124,22 @@ public class LuceneIndexCommandsJUnitTest {
         .thenReturn(mockResultCollector);
     when(mockResultCollector.getResult()).thenReturn(results);
 
-    final LuceneIndexCommands commands = createIndexCommands(this.mockCache, 
mockFunctionExecutor);
+    final LuceneListIndexCommand command =
+        new LuceneTestListIndexCommand(this.mockCache, mockFunctionExecutor);
 
-    CommandResult result = (CommandResult) commands.listIndex(false);
-    TabularResultData data = (TabularResultData) result.getResultData();
-    assertThat(data.retrieveAllValues("Index Name"))
+    ResultModel result = command.listIndex(false);
+    TabularResultModel data = result.getTableSection("lucene-indexes");
+    assertThat(data.getValuesInColumn("Index Name"))
         .isEqualTo(Arrays.asList("memberFive", "memberSix", "memberTen"));
-    assertThat(data.retrieveAllValues("Region Path"))
+    assertThat(data.getValuesInColumn("Region Path"))
         .isEqualTo(Arrays.asList("/Employees", "/Employees", "/Employees"));
-    assertThat(data.retrieveAllValues("Indexed 
Fields")).isEqualTo(Arrays.asList(
+    assertThat(data.getValuesInColumn("Indexed 
Fields")).isEqualTo(Arrays.asList(
         "[field1, field2, field3]", "[field1, field2, field3]", "[field1, 
field2, field3]"));
-    assertThat(data.retrieveAllValues("Field Analyzer"))
+    assertThat(data.getValuesInColumn("Field Analyzer"))
         .isEqualTo(Arrays.asList("{field1=StandardAnalyzer, 
field2=KeywordAnalyzer}",
             "{field1=StandardAnalyzer, field2=KeywordAnalyzer}",
             "{field1=StandardAnalyzer, field2=KeywordAnalyzer}"));
-    assertThat(data.retrieveAllValues("Status"))
+    assertThat(data.getValuesInColumn("Status"))
         .isEqualTo(Arrays.asList("INITIALIZED", "NOT_INITIALIZED", 
"INITIALIZED"));
   }
 
@@ -176,25 +176,26 @@ public class LuceneIndexCommandsJUnitTest {
         .thenReturn(mockResultCollector);
     when(mockResultCollector.getResult()).thenReturn(results);
 
-    final LuceneIndexCommands commands = createIndexCommands(this.mockCache, 
mockFunctionExecutor);
+    final LuceneListIndexCommand command =
+        new LuceneTestListIndexCommand(this.mockCache, mockFunctionExecutor);
 
-    CommandResult result = (CommandResult) commands.listIndex(true);
-    TabularResultData data = (TabularResultData) result.getResultData();
-    assertThat(data.retrieveAllValues("Index Name"))
+    ResultModel result = command.listIndex(true);
+    TabularResultModel data = result.getTableSection("lucene-indexes");
+    assertThat(data.getValuesInColumn("Index Name"))
         .isEqualTo(Arrays.asList("memberFive", "memberSix", "memberTen"));
-    assertThat(data.retrieveAllValues("Region Path"))
+    assertThat(data.getValuesInColumn("Region Path"))
         .isEqualTo(Arrays.asList("/Employees", "/Employees", "/Employees"));
-    assertThat(data.retrieveAllValues("Indexed 
Fields")).isEqualTo(Arrays.asList(
+    assertThat(data.getValuesInColumn("Indexed 
Fields")).isEqualTo(Arrays.asList(
         "[field1, field2, field3]", "[field1, field2, field3]", "[field1, 
field2, field3]"));
-    assertThat(data.retrieveAllValues("Field Analyzer"))
+    assertThat(data.getValuesInColumn("Field Analyzer"))
         .isEqualTo(Arrays.asList("{field1=StandardAnalyzer, 
field2=KeywordAnalyzer}",
             "{field1=StandardAnalyzer, field2=KeywordAnalyzer}",
             "{field1=StandardAnalyzer, field2=KeywordAnalyzer}"));
-    assertThat(data.retrieveAllValues("Query 
Executions")).isEqualTo(Arrays.asList("1", "2", "3"));
-    
assertThat(data.retrieveAllValues("Commits")).isEqualTo(Arrays.asList("10", 
"20", "30"));
-    assertThat(data.retrieveAllValues("Updates")).isEqualTo(Arrays.asList("5", 
"10", "15"));
-    
assertThat(data.retrieveAllValues("Documents")).isEqualTo(Arrays.asList("1", 
"2", "3"));
-    assertThat(data.retrieveAllValues("Serializer"))
+    assertThat(data.getValuesInColumn("Query 
Executions")).isEqualTo(Arrays.asList("1", "2", "3"));
+    
assertThat(data.getValuesInColumn("Commits")).isEqualTo(Arrays.asList("10", 
"20", "30"));
+    assertThat(data.getValuesInColumn("Updates")).isEqualTo(Arrays.asList("5", 
"10", "15"));
+    
assertThat(data.getValuesInColumn("Documents")).isEqualTo(Arrays.asList("1", 
"2", "3"));
+    assertThat(data.getValuesInColumn("Serializer"))
         
.isEqualTo(Arrays.asList(HeterogeneousLuceneSerializer.class.getSimpleName(),
             HeterogeneousLuceneSerializer.class.getSimpleName(),
             HeterogeneousLuceneSerializer.class.getSimpleName()));
@@ -203,7 +204,8 @@ public class LuceneIndexCommandsJUnitTest {
   @Test
   public void testCreateIndex() throws Exception {
     final ResultCollector mockResultCollector = mock(ResultCollector.class);
-    final LuceneIndexCommands commands = 
spy(createIndexCommands(this.mockCache, null));
+    final LuceneCreateIndexCommand command =
+        spy(new LuceneTestCreateIndexCommand(this.mockCache, null));
 
     final List<CliFunctionResult> cliFunctionResults = new ArrayList<>();
     cliFunctionResults
@@ -213,7 +215,7 @@ public class LuceneIndexCommandsJUnitTest {
     cliFunctionResults
         .add(new CliFunctionResult("member3", 
CliFunctionResult.StatusState.OK, "Index Created"));
 
-    doReturn(mockResultCollector).when(commands).executeFunctionOnAllMembers(
+    doReturn(mockResultCollector).when(command).executeFunctionOnAllMembers(
         any(LuceneCreateIndexFunction.class), any(LuceneIndexInfo.class));
     doReturn(cliFunctionResults).when(mockResultCollector).getResult();
 
@@ -225,13 +227,13 @@ public class LuceneIndexCommandsJUnitTest {
 
     String serializer = PrimitiveSerializer.class.getCanonicalName();
 
-    CommandResult result = (CommandResult) commands.createIndex(indexName, 
regionPath,
-        searchableFields, fieldAnalyzers, serializer);
+    ResultModel result = command.createIndex(indexName, regionPath, 
searchableFields,
+        fieldAnalyzers, serializer);
     assertThat(result.getStatus()).isEqualTo(Status.OK);
-    TabularResultData data = (TabularResultData) result.getResultData();
-    assertThat(data.retrieveAllValues("Member"))
+    TabularResultModel data = result.getTableSection("lucene-indexes");
+    assertThat(data.getValuesInColumn("Member"))
         .isEqualTo(Arrays.asList("member1", "member2", "member3"));
-    assertThat(data.retrieveAllValues("Status"))
+    assertThat(data.getValuesInColumn("Status"))
         .isEqualTo(Arrays.asList("Successfully created lucene index",
             "Failed: Index creation failed", "Successfully created lucene 
index"));
   }
@@ -240,7 +242,8 @@ public class LuceneIndexCommandsJUnitTest {
   public void testDescribeIndex() throws Exception {
     final String serverName = "mockServer";
     final ResultCollector mockResultCollector = mock(ResultCollector.class, 
"ResultCollector");
-    final LuceneIndexCommands commands = 
spy(createIndexCommands(this.mockCache, null));
+    final LuceneDescribeIndexCommand command =
+        spy(new LuceneTestDescribeIndexCommand(this.mockCache, null));
 
     String[] searchableFields = {"field1", "field2", "field3"};
     Map<String, Analyzer> fieldAnalyzers = new HashMap<>();
@@ -253,34 +256,35 @@ public class LuceneIndexCommandsJUnitTest {
     indexDetails.add(createIndexDetails("memberFive", "/Employees", 
searchableFields,
         fieldAnalyzers, mockIndexStats, LuceneIndexStatus.INITIALIZED, 
serverName, serializer));
 
-    doReturn(mockResultCollector).when(commands).executeFunctionOnRegion(
+    doReturn(mockResultCollector).when(command).executeFunctionOnRegion(
         any(LuceneDescribeIndexFunction.class), any(LuceneIndexInfo.class), 
eq(true));
     doReturn(indexDetails).when(mockResultCollector).getResult();
 
-    CommandResult result = (CommandResult) 
commands.describeIndex("memberFive", "/Employees");
+    ResultModel result = command.describeIndex("memberFive", "/Employees");
 
-    TabularResultData data = (TabularResultData) result.getResultData();
-    assertThat(data.retrieveAllValues("Index Name"))
+    TabularResultModel data = result.getTableSection("lucene-indexes");
+    assertThat(data.getValuesInColumn("Index Name"))
         .isEqualTo(Collections.singletonList("memberFive"));
-    assertThat(data.retrieveAllValues("Region Path"))
+    assertThat(data.getValuesInColumn("Region Path"))
         .isEqualTo(Collections.singletonList("/Employees"));
-    assertThat(data.retrieveAllValues("Indexed Fields"))
+    assertThat(data.getValuesInColumn("Indexed Fields"))
         .isEqualTo(Collections.singletonList("[field1, field2, field3]"));
-    assertThat(data.retrieveAllValues("Field Analyzer"))
+    assertThat(data.getValuesInColumn("Field Analyzer"))
         .isEqualTo(Collections.singletonList("{field1=StandardAnalyzer, 
field2=KeywordAnalyzer}"));
-    assertThat(data.retrieveAllValues("Status"))
+    assertThat(data.getValuesInColumn("Status"))
         .isEqualTo(Collections.singletonList("INITIALIZED"));
-    assertThat(data.retrieveAllValues("Query Executions"))
+    assertThat(data.getValuesInColumn("Query Executions"))
         .isEqualTo(Collections.singletonList("1"));
-    
assertThat(data.retrieveAllValues("Commits")).isEqualTo(Collections.singletonList("10"));
-    
assertThat(data.retrieveAllValues("Updates")).isEqualTo(Collections.singletonList("5"));
-    
assertThat(data.retrieveAllValues("Documents")).isEqualTo(Collections.singletonList("1"));
+    
assertThat(data.getValuesInColumn("Commits")).isEqualTo(Collections.singletonList("10"));
+    
assertThat(data.getValuesInColumn("Updates")).isEqualTo(Collections.singletonList("5"));
+    
assertThat(data.getValuesInColumn("Documents")).isEqualTo(Collections.singletonList("1"));
   }
 
   @Test
   public void testSearchIndex() throws Exception {
     final ResultCollector mockResultCollector = mock(ResultCollector.class, 
"ResultCollector");
-    final LuceneIndexCommands commands = 
spy(createIndexCommands(this.mockCache, null));
+    final LuceneSearchIndexCommand command =
+        spy(new LuceneTestSearchIndexCommand(this.mockCache, null));
 
     final List<Set<LuceneSearchResults>> queryResultsList = new ArrayList<>();
     HashSet<LuceneSearchResults> queryResults = new HashSet<>();
@@ -288,23 +292,24 @@ public class LuceneIndexCommandsJUnitTest {
     queryResults.add(createQueryResults("B", "Result1", Float.valueOf("1.2")));
     queryResults.add(createQueryResults("C", "Result1", Float.valueOf("1.1")));
     queryResultsList.add(queryResults);
-    
doReturn(mockResultCollector).when(commands).executeSearch(any(LuceneQueryInfo.class));
+    
doReturn(mockResultCollector).when(command).executeSearch(any(LuceneQueryInfo.class));
     doReturn(queryResultsList).when(mockResultCollector).getResult();
 
-    CommandResult result =
-        (CommandResult) commands.searchIndex("index", "region", "Result1", 
"field1", -1, false);
-    TabularResultData data = (TabularResultData) result.getResultData();
-    assertThat(data.retrieveAllValues("key")).isEqualTo(Arrays.asList("A", 
"B", "C"));
-    assertThat(data.retrieveAllValues("value"))
+    ResultModel result =
+        command.searchIndex("index", "region", "Result1", "field1", -1, false);
+    TabularResultModel data = result.getTableSection("lucene-indexes");
+    assertThat(data.getValuesInColumn("key")).isEqualTo(Arrays.asList("A", 
"B", "C"));
+    assertThat(data.getValuesInColumn("value"))
         .isEqualTo(Arrays.asList("Result1", "Result1", "Result1"));
-    assertThat(data.retrieveAllValues("score")).isEqualTo(Arrays.asList("1.3", 
"1.2", "1.1"));
+    assertThat(data.getValuesInColumn("score")).isEqualTo(Arrays.asList("1.3", 
"1.2", "1.1"));
   }
 
-  @Ignore
+  @Test
   public void testSearchIndexWithPaging() throws Exception {
     final Gfsh mockGfsh = mock(Gfsh.class);
     final ResultCollector mockResultCollector = mock(ResultCollector.class, 
"ResultCollector");
-    final LuceneIndexCommands commands = 
spy(createIndexCommands(this.mockCache, null));
+    final LuceneSearchIndexCommand command =
+        spy(new LuceneTestSearchIndexCommand(this.mockCache, null));
     ArgumentCaptor<String> resultCaptor = 
ArgumentCaptor.forClass(String.class);
 
     LuceneSearchResults result1 = createQueryResults("A", "Result1", 
Float.valueOf("1.7"));
@@ -317,21 +322,22 @@ public class LuceneIndexCommandsJUnitTest {
     final List<Set<LuceneSearchResults>> queryResultsList =
         getSearchResults(result1, result2, result3, result4, result5, result6, 
result7);
 
-    
doReturn(mockResultCollector).when(commands).executeSearch(any(LuceneQueryInfo.class));
+    
doReturn(mockResultCollector).when(command).executeSearch(any(LuceneQueryInfo.class));
     doReturn(queryResultsList).when(mockResultCollector).getResult();
-    doReturn(mockGfsh).when(commands).initGfsh();
+    doReturn(mockGfsh).when(command).initGfsh();
     
when(mockGfsh.interact(anyString())).thenReturn("n").thenReturn("n").thenReturn("n")
         
.thenReturn("n").thenReturn("p").thenReturn("p").thenReturn("p").thenReturn("p")
         .thenReturn("p").thenReturn("n").thenReturn("q");
+    when(command.getPageSize()).thenReturn(2);
 
     LuceneSearchResults[] expectedResults =
         new LuceneSearchResults[] {result7, result6, result5, result4, 
result3, result2, result1};
-    String expectedPage1 = getPage(expectedResults, new int[] {0, 1});
-    String expectedPage2 = getPage(expectedResults, new int[] {2, 3});
-    String expectedPage3 = getPage(expectedResults, new int[] {4, 5});
-    String expectedPage4 = getPage(expectedResults, new int[] {6});
+    String expectedPage1 = getPage(expectedResults, new int[] {6, 5});
+    String expectedPage2 = getPage(expectedResults, new int[] {4, 3});
+    String expectedPage3 = getPage(expectedResults, new int[] {2, 1});
+    String expectedPage4 = getPage(expectedResults, new int[] {0});
 
-    commands.searchIndex("index", "region", "Result1", "field1", -1, false);
+    command.searchIndex("index", "region", "Result1", "field1", -1, false);
     verify(mockGfsh, times(20)).printAsInfo(resultCaptor.capture());
     List<String> actualPageResults = resultCaptor.getAllValues();
 
@@ -370,7 +376,8 @@ public class LuceneIndexCommandsJUnitTest {
   @Test
   public void testSearchIndexWithKeysOnly() throws Exception {
     final ResultCollector mockResultCollector = mock(ResultCollector.class, 
"ResultCollector");
-    final LuceneIndexCommands commands = 
spy(createIndexCommands(this.mockCache, null));
+    final LuceneSearchIndexCommand command =
+        spy(new LuceneTestSearchIndexCommand(this.mockCache, null));
 
     final List<Set<LuceneSearchResults>> queryResultsList = new ArrayList<>();
     HashSet<LuceneSearchResults> queryResults = new HashSet<>();
@@ -378,19 +385,19 @@ public class LuceneIndexCommandsJUnitTest {
     queryResults.add(createQueryResults("B", "Result1", Float.valueOf("1.2")));
     queryResults.add(createQueryResults("C", "Result1", Float.valueOf("1.1")));
     queryResultsList.add(queryResults);
-    
doReturn(mockResultCollector).when(commands).executeSearch(any(LuceneQueryInfo.class));
+    
doReturn(mockResultCollector).when(command).executeSearch(any(LuceneQueryInfo.class));
     doReturn(queryResultsList).when(mockResultCollector).getResult();
 
-    CommandResult result =
-        (CommandResult) commands.searchIndex("index", "region", "Result1", 
"field1", -1, true);
-    TabularResultData data = (TabularResultData) result.getResultData();
-    assertThat(data.retrieveAllValues("key")).isEqualTo(Arrays.asList("A", 
"B", "C"));
+    ResultModel result = command.searchIndex("index", "region", "Result1", 
"field1", -1, true);
+    TabularResultModel data = result.getTableSection("lucene-indexes");
+    assertThat(data.getValuesInColumn("key")).isEqualTo(Arrays.asList("A", 
"B", "C"));
   }
 
   @Test
   public void testSearchIndexWhenSearchResultsHaveSameScore() throws Exception 
{
     final ResultCollector mockResultCollector = mock(ResultCollector.class, 
"ResultCollector");
-    final LuceneIndexCommands commands = 
spy(createIndexCommands(this.mockCache, null));
+    final LuceneSearchIndexCommand command =
+        spy(new LuceneTestSearchIndexCommand(this.mockCache, null));
 
     final List<Set<LuceneSearchResults>> queryResultsList = new ArrayList<>();
     HashSet<LuceneSearchResults> queryResults = new HashSet<>();
@@ -415,32 +422,34 @@ public class LuceneIndexCommandsJUnitTest {
     queryResults.add(createQueryResults("T", "Result1", 1));
     queryResultsList.add(queryResults);
 
-    
doReturn(mockResultCollector).when(commands).executeSearch(any(LuceneQueryInfo.class));
+    
doReturn(mockResultCollector).when(command).executeSearch(any(LuceneQueryInfo.class));
     doReturn(queryResultsList).when(mockResultCollector).getResult();
 
-    CommandResult result =
-        (CommandResult) commands.searchIndex("index", "region", "Result1", 
"field1", -1, true);
-    TabularResultData data = (TabularResultData) result.getResultData();
-    
assertThat(data.retrieveAllValues("key").size()).isEqualTo(queryResults.size());
+    ResultModel result = command.searchIndex("index", "region", "Result1", 
"field1", -1, true);
+    TabularResultModel data = result.getTableSection("lucene-indexes");
+    
assertThat(data.getValuesInColumn("key").size()).isEqualTo(queryResults.size());
   }
 
   @Test
   public void testDestroySingleIndexNoRegionMembers() {
-    LuceneIndexCommands commands = 
createTestLuceneIndexCommandsForDestroyIndex();
+    LuceneDestroyIndexCommand command =
+        spy(new LuceneTestDestroyIndexCommand(mockCache, null));
     final List<CliFunctionResult> cliFunctionResults = new ArrayList<>();
     String expectedStatus = CliStrings.format(
         
LuceneCliStrings.LUCENE_DESTROY_INDEX__MSG__COULD_NOT_FIND__MEMBERS_GREATER_THAN_VERSION_0,
-        new Object[] {Version.GEODE_1_7_0}) + LINE_SEPARATOR;
+        new Object[] {Version.GEODE_1_7_0});
     cliFunctionResults.add(new CliFunctionResult("member0", 
CliFunctionResult.StatusState.OK));
-    
doReturn(Collections.emptySet()).when(commands).getNormalMembersWithSameOrNewerVersion(any());
-    CommandResult result = (CommandResult) commands.destroyIndex("index", 
"regionPath");
+    
doReturn(Collections.emptySet()).when(command).getNormalMembersWithSameOrNewerVersion(any());
+
+    ResultModel result = command.destroyIndex("index", "regionPath");
     verifyDestroyIndexCommandResult(result, cliFunctionResults, 
expectedStatus);
   }
 
   @Test
   @Parameters({"true", "false"})
   public void testDestroySingleIndexWithRegionMembers(boolean 
expectedToSucceed) {
-    LuceneIndexCommands commands = 
createTestLuceneIndexCommandsForDestroyIndex();
+    LuceneDestroyIndexCommand command =
+        spy(new LuceneTestDestroyIndexCommand(mockCache, null));
     String indexName = "index";
     String regionPath = "regionPath";
 
@@ -464,33 +473,36 @@ public class LuceneIndexCommandsJUnitTest {
       cliFunctionResults.add(new CliFunctionResult("member0", e, 
e.getMessage()));
     }
 
-    doReturn(mockResultCollector).when(commands).executeFunction(
+    doReturn(mockResultCollector).when(command).executeFunction(
         any(LuceneDestroyIndexFunction.class), 
any(LuceneDestroyIndexInfo.class), anySet());
     doReturn(cliFunctionResults).when(mockResultCollector).getResult();
 
-    
doReturn(members).when(commands).getNormalMembersWithSameOrNewerVersion(any());
+    
doReturn(members).when(command).getNormalMembersWithSameOrNewerVersion(any());
 
-    CommandResult result = (CommandResult) commands.destroyIndex(indexName, 
regionPath);
+    ResultModel result = command.destroyIndex(indexName, regionPath);
     verifyDestroyIndexCommandResult(result, cliFunctionResults, 
expectedStatus);
   }
 
   @Test
   public void testDestroyAllIndexesNoRegionMembers() {
-    LuceneIndexCommands commands = 
createTestLuceneIndexCommandsForDestroyIndex();
+    LuceneDestroyIndexCommand commands =
+        spy(new LuceneTestDestroyIndexCommand(mockCache, null));
     
doReturn(Collections.emptySet()).when(commands).getNormalMembersWithSameOrNewerVersion(any());
     final List<CliFunctionResult> cliFunctionResults = new ArrayList<>();
     String expectedStatus = CliStrings.format(
         
LuceneCliStrings.LUCENE_DESTROY_INDEX__MSG__COULD_NOT_FIND__MEMBERS_GREATER_THAN_VERSION_0,
-        new Object[] {Version.GEODE_1_7_0}) + LINE_SEPARATOR;
+        new Object[] {Version.GEODE_1_7_0});
     cliFunctionResults.add(new CliFunctionResult("member0", 
CliFunctionResult.StatusState.OK));
-    CommandResult result = (CommandResult) commands.destroyIndex(null, 
"regionPath");
+
+    ResultModel result = commands.destroyIndex(null, "regionPath");
     verifyDestroyIndexCommandResult(result, cliFunctionResults, 
expectedStatus);
   }
 
   @Test
   @Parameters({"true", "false"})
   public void testDestroyAllIndexesWithRegionMembers(boolean 
expectedToSucceed) {
-    LuceneIndexCommands commands = 
createTestLuceneIndexCommandsForDestroyIndex();
+    LuceneDestroyIndexCommand commands =
+        spy(new LuceneTestDestroyIndexCommand(mockCache, null));
     String indexName = null;
     String regionPath = "regionPath";
 
@@ -520,43 +532,33 @@ public class LuceneIndexCommandsJUnitTest {
 
     
doReturn(members).when(commands).getNormalMembersWithSameOrNewerVersion(any());
 
-    CommandResult result = (CommandResult) commands.destroyIndex(indexName, 
regionPath);
+    ResultModel result = commands.destroyIndex(indexName, regionPath);
     verifyDestroyIndexCommandResult(result, cliFunctionResults, 
expectedStatus);
   }
 
-  private LuceneIndexCommands createTestLuceneIndexCommandsForDestroyIndex() {
-    final ResultCollector mockResultCollector = mock(ResultCollector.class);
-    final LuceneIndexCommands commands = 
spy(createIndexCommands(this.mockCache, null));
-
-    final List<CliFunctionResult> cliFunctionResults = new ArrayList<>();
-    cliFunctionResults
-        .add(new CliFunctionResult("member", CliFunctionResult.StatusState.OK, 
"Index Destroyed"));
-
-    doReturn(mockResultCollector).when(commands).executeFunctionOnRegion(
-        any(LuceneDestroyIndexFunction.class), any(LuceneIndexInfo.class), 
eq(false));
-    doReturn(cliFunctionResults).when(mockResultCollector).getResult();
-    return commands;
-  }
-
-  private void verifyDestroyIndexCommandResult(CommandResult result,
+  private void verifyDestroyIndexCommandResult(ResultModel result,
       List<CliFunctionResult> cliFunctionResults, String expectedStatus) {
     assertThat(result.getStatus()).isEqualTo(Status.OK);
-    if (result.getType().equals(TYPE_TABULAR)) {
-      TabularResultData data = (TabularResultData) result.getResultData();
-      List<String> members = data.retrieveAllValues("Member");
+
+    TabularResultModel data = result.getTableSection("lucene-indexes");
+    if (data != null) {
+      List<String> members = data.getValuesInColumn("Member");
       assertThat(cliFunctionResults.size()).isEqualTo(members.size());
       // Verify each member
       for (int i = 0; i < members.size(); i++) {
         assertThat(members.get(i)).isEqualTo("member" + i);
       }
       // Verify each status
-      List<String> status = data.retrieveAllValues("Status");
+      List<String> status = data.getValuesInColumn("Status");
       for (String statu : status) {
         assertThat(statu).isEqualTo(expectedStatus);
       }
-    } else {
+    } else if (result.getInfoSection("info") != null) {
       // Info result. Verify next lines are equal.
-      assertThat(result.nextLine()).isEqualTo(expectedStatus);
+      
assertThat(result.getInfoSection("info").getContent().get(0)).isEqualTo(expectedStatus);
+    } else {
+      // Error result. Verify next lines are equal.
+      
assertThat(result.getInfoSection("error").getContent().get(0)).isEqualTo(expectedStatus);
     }
   }
 
@@ -592,11 +594,6 @@ public class LuceneIndexCommandsJUnitTest {
     return mockIndexStats;
   }
 
-  private LuceneIndexCommands createIndexCommands(final InternalCache cache,
-      final Execution functionExecutor) {
-    return new LuceneTestIndexCommands(cache, functionExecutor);
-  }
-
   private LuceneIndexDetails createIndexDetails(final String indexName, final 
String regionPath,
       final String[] searchableFields, final Map<String, Analyzer> 
fieldAnalyzers,
       LuceneIndexStats indexStats, LuceneIndexStatus status, final String 
serverName,
@@ -617,11 +614,31 @@ public class LuceneIndexCommandsJUnitTest {
     return new LuceneSearchResults(key, value, score);
   }
 
-  private static class LuceneTestIndexCommands extends LuceneIndexCommands {
+  private static class LuceneTestListIndexCommand extends 
LuceneListIndexCommand {
+    private final Execution functionExecutor;
 
+    LuceneTestListIndexCommand(final InternalCache cache, final Execution 
functionExecutor) {
+      assert cache != null : "The InternalCache cannot be null!";
+      setCache(cache);
+      this.functionExecutor = functionExecutor;
+    }
+
+    @Override
+    public Set<DistributedMember> getAllMembers() {
+      return Collections.emptySet();
+    }
+
+    @Override
+    public Execution getMembersFunctionExecutor(final Set<DistributedMember> 
members) {
+      assertThat(members).isNotNull();
+      return this.functionExecutor;
+    }
+  }
+
+  private static class LuceneTestCreateIndexCommand extends 
LuceneCreateIndexCommand {
     private final Execution functionExecutor;
 
-    LuceneTestIndexCommands(final InternalCache cache, final Execution 
functionExecutor) {
+    LuceneTestCreateIndexCommand(final InternalCache cache, final Execution 
functionExecutor) {
       assert cache != null : "The InternalCache cannot be null!";
       setCache(cache);
       this.functionExecutor = functionExecutor;
@@ -639,4 +656,66 @@ public class LuceneIndexCommandsJUnitTest {
     }
   }
 
+  private static class LuceneTestDescribeIndexCommand extends 
LuceneDescribeIndexCommand {
+    private final Execution functionExecutor;
+
+    LuceneTestDescribeIndexCommand(final InternalCache cache, final Execution 
functionExecutor) {
+      assert cache != null : "The InternalCache cannot be null!";
+      setCache(cache);
+      this.functionExecutor = functionExecutor;
+    }
+
+    @Override
+    public Set<DistributedMember> getAllMembers() {
+      return Collections.emptySet();
+    }
+
+    @Override
+    public Execution getMembersFunctionExecutor(final Set<DistributedMember> 
members) {
+      assertThat(members).isNotNull();
+      return this.functionExecutor;
+    }
+  }
+
+  private static class LuceneTestSearchIndexCommand extends 
LuceneSearchIndexCommand {
+    private final Execution functionExecutor;
+
+    LuceneTestSearchIndexCommand(final InternalCache cache, final Execution 
functionExecutor) {
+      assert cache != null : "The InternalCache cannot be null!";
+      setCache(cache);
+      this.functionExecutor = functionExecutor;
+    }
+
+    @Override
+    public Set<DistributedMember> getAllMembers() {
+      return Collections.emptySet();
+    }
+
+    @Override
+    public Execution getMembersFunctionExecutor(final Set<DistributedMember> 
members) {
+      assertThat(members).isNotNull();
+      return this.functionExecutor;
+    }
+  }
+
+  private static class LuceneTestDestroyIndexCommand extends 
LuceneDestroyIndexCommand {
+    private final Execution functionExecutor;
+
+    LuceneTestDestroyIndexCommand(final InternalCache cache, final Execution 
functionExecutor) {
+      assert cache != null : "The InternalCache cannot be null!";
+      setCache(cache);
+      this.functionExecutor = functionExecutor;
+    }
+
+    @Override
+    public Set<DistributedMember> getAllMembers() {
+      return Collections.emptySet();
+    }
+
+    @Override
+    public Execution getMembersFunctionExecutor(final Set<DistributedMember> 
members) {
+      assertThat(members).isNotNull();
+      return this.functionExecutor;
+    }
+  }
 }

Reply via email to