You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@accumulo.apache.org by el...@apache.org on 2014/04/08 05:02:57 UTC

[01/53] [abbrv] Git Push Summary

Repository: accumulo
Updated Branches:
  refs/heads/ACCUMULO-378 71475cf87 -> 5fd07ec03

[33/53] [abbrv] git commit: Revert "ACCUMULO-1897 Move shell into new package and module"

Posted by el...@apache.org.
Revert "ACCUMULO-1897 Move shell into new package and module"

This reverts commit bcc9e7e41c9a40cc36502fece266780c7cba0de8.


Project: http://git-wip-us.apache.org/repos/asf/accumulo/repo
Commit: http://git-wip-us.apache.org/repos/asf/accumulo/commit/b2b985e2
Tree: http://git-wip-us.apache.org/repos/asf/accumulo/tree/b2b985e2
Diff: http://git-wip-us.apache.org/repos/asf/accumulo/diff/b2b985e2

Branch: refs/heads/ACCUMULO-378
Commit: b2b985e240b90cb3645a9d7d4d8469d660961d1b
Parents: 24f895f
Author: Mike Drob <md...@cloudera.com>
Authored: Mon Apr 7 20:36:00 2014 -0400
Committer: Mike Drob <md...@cloudera.com>
Committed: Mon Apr 7 20:36:00 2014 -0400

----------------------------------------------------------------------
 core/pom.xml                                    |   19 +
 .../accumulo/core/client/mock/MockShell.java    |  142 +++
 .../core/util/format/DeleterFormatter.java      |  101 ++
 .../apache/accumulo/core/util/shell/Shell.java  | 1168 ++++++++++++++++++
 .../core/util/shell/ShellCommandException.java  |   59 +
 .../core/util/shell/ShellCompletor.java         |  162 +++
 .../core/util/shell/ShellExtension.java         |   27 +
 .../accumulo/core/util/shell/ShellOptions.java  |   33 +
 .../core/util/shell/ShellOptionsJC.java         |  280 +++++
 .../accumulo/core/util/shell/ShellUtil.java     |   60 +
 .../apache/accumulo/core/util/shell/Token.java  |  137 ++
 .../core/util/shell/commands/AboutCommand.java  |   56 +
 .../commands/ActiveCompactionIterator.java      |  136 ++
 .../util/shell/commands/ActiveScanIterator.java |   91 ++
 .../util/shell/commands/AddAuthsCommand.java    |   82 ++
 .../util/shell/commands/AddSplitsCommand.java   |   88 ++
 .../shell/commands/AuthenticateCommand.java     |   66 +
 .../core/util/shell/commands/ByeCommand.java    |   19 +
 .../util/shell/commands/ClasspathCommand.java   |   55 +
 .../core/util/shell/commands/ClearCommand.java  |   52 +
 .../util/shell/commands/CloneTableCommand.java  |  102 ++
 .../core/util/shell/commands/ClsCommand.java    |   19 +
 .../util/shell/commands/CompactCommand.java     |  129 ++
 .../core/util/shell/commands/ConfigCommand.java |  315 +++++
 .../util/shell/commands/ConstraintCommand.java  |  134 ++
 .../shell/commands/CreateNamespaceCommand.java  |   99 ++
 .../util/shell/commands/CreateTableCommand.java |  203 +++
 .../util/shell/commands/CreateUserCommand.java  |   76 ++
 .../core/util/shell/commands/DUCommand.java     |  124 ++
 .../core/util/shell/commands/DebugCommand.java  |   71 ++
 .../core/util/shell/commands/DeleteCommand.java |  112 ++
 .../util/shell/commands/DeleteIterCommand.java  |  114 ++
 .../util/shell/commands/DeleteManyCommand.java  |   82 ++
 .../shell/commands/DeleteNamespaceCommand.java  |  100 ++
 .../util/shell/commands/DeleteRowsCommand.java  |   65 +
 .../shell/commands/DeleteScanIterCommand.java   |  102 ++
 .../shell/commands/DeleteShellIterCommand.java  |  100 ++
 .../util/shell/commands/DeleteTableCommand.java |   60 +
 .../util/shell/commands/DeleteUserCommand.java  |   19 +
 .../util/shell/commands/DropTableCommand.java   |   19 +
 .../util/shell/commands/DropUserCommand.java    |   61 +
 .../core/util/shell/commands/EGrepCommand.java  |   59 +
 .../util/shell/commands/ExecfileCommand.java    |   67 +
 .../core/util/shell/commands/ExitCommand.java   |   39 +
 .../util/shell/commands/ExportTableCommand.java |   78 ++
 .../util/shell/commands/ExtensionCommand.java   |  102 ++
 .../core/util/shell/commands/FateCommand.java   |  180 +++
 .../core/util/shell/commands/FlushCommand.java  |   63 +
 .../util/shell/commands/FormatterCommand.java   |   69 ++
 .../util/shell/commands/GetAuthsCommand.java    |   67 +
 .../util/shell/commands/GetGroupsCommand.java   |   60 +
 .../util/shell/commands/GetSplitsCommand.java   |  155 +++
 .../core/util/shell/commands/GrantCommand.java  |  133 ++
 .../core/util/shell/commands/GrepCommand.java   |  111 ++
 .../core/util/shell/commands/HelpCommand.java   |  129 ++
 .../core/util/shell/commands/HiddenCommand.java |   62 +
 .../util/shell/commands/HistoryCommand.java     |   82 ++
 .../shell/commands/ImportDirectoryCommand.java  |   58 +
 .../util/shell/commands/ImportTableCommand.java |   51 +
 .../core/util/shell/commands/InfoCommand.java   |   19 +
 .../core/util/shell/commands/InsertCommand.java |  148 +++
 .../util/shell/commands/InterpreterCommand.java |   40 +
 .../shell/commands/ListCompactionsCommand.java  |   78 ++
 .../util/shell/commands/ListIterCommand.java    |  140 +++
 .../util/shell/commands/ListScansCommand.java   |   78 ++
 .../shell/commands/ListShellIterCommand.java    |  105 ++
 .../core/util/shell/commands/MaxRowCommand.java |   55 +
 .../core/util/shell/commands/MergeCommand.java  |  111 ++
 .../commands/NamespacePermissionsCommand.java   |   44 +
 .../util/shell/commands/NamespacesCommand.java  |   83 ++
 .../util/shell/commands/NoTableCommand.java     |   40 +
 .../util/shell/commands/OfflineCommand.java     |   61 +
 .../core/util/shell/commands/OnlineCommand.java |   61 +
 .../core/util/shell/commands/OptUtil.java       |  146 +++
 .../core/util/shell/commands/PasswdCommand.java |   96 ++
 .../core/util/shell/commands/PingCommand.java   |   82 ++
 .../core/util/shell/commands/PingIterator.java  |   58 +
 .../util/shell/commands/QuestionCommand.java    |   24 +
 .../core/util/shell/commands/QuitCommand.java   |   19 +
 .../shell/commands/QuotedStringTokenizer.java   |  141 +++
 .../shell/commands/RenameNamespaceCommand.java  |   79 ++
 .../util/shell/commands/RenameTableCommand.java |   62 +
 .../core/util/shell/commands/RevokeCommand.java |  133 ++
 .../core/util/shell/commands/ScanCommand.java   |  334 +++++
 .../core/util/shell/commands/ScriptCommand.java |  290 +++++
 .../util/shell/commands/SetAuthsCommand.java    |   77 ++
 .../util/shell/commands/SetGroupsCommand.java   |   78 ++
 .../util/shell/commands/SetIterCommand.java     |  453 +++++++
 .../util/shell/commands/SetScanIterCommand.java |  127 ++
 .../shell/commands/SetShellIterCommand.java     |  131 ++
 .../ShellPluginConfigurationCommand.java        |  146 +++
 .../core/util/shell/commands/SleepCommand.java  |   46 +
 .../commands/SystemPermissionsCommand.java      |   44 +
 .../core/util/shell/commands/TableCommand.java  |   60 +
 .../util/shell/commands/TableOperation.java     |  153 +++
 .../shell/commands/TablePermissionsCommand.java |   44 +
 .../core/util/shell/commands/TablesCommand.java |  107 ++
 .../core/util/shell/commands/TraceCommand.java  |  101 ++
 .../core/util/shell/commands/UserCommand.java   |   71 ++
 .../shell/commands/UserPermissionsCommand.java  |  106 ++
 .../core/util/shell/commands/UsersCommand.java  |   45 +
 .../core/util/shell/commands/WhoAmICommand.java |   41 +
 .../core/util/format/DeleterFormatterTest.java  |  176 +++
 .../core/util/shell/PasswordConverterTest.java  |  113 ++
 .../core/util/shell/ShellConfigTest.java        |   90 ++
 .../core/util/shell/ShellSetInstanceTest.java   |  242 ++++
 .../accumulo/core/util/shell/ShellTest.java     |  281 +++++
 .../accumulo/core/util/shell/ShellUtilTest.java |   66 +
 .../shell/command/FormatterCommandTest.java     |  184 +++
 core/src/test/resources/shelltest.txt           |   16 +
 examples/simple/pom.xml                         |    4 -
 .../examples/simple/shell/DebugCommand.java     |    4 +-
 .../simple/shell/MyAppShellExtension.java       |    4 +-
 pom.xml                                         |    6 -
 server/monitor/pom.xml                          |    4 -
 .../accumulo/monitor/servlets/ShellServlet.java |    2 +-
 shell/pom.xml                                   |  123 --
 .../java/org/apache/accumulo/shell/Shell.java   | 1168 ------------------
 .../accumulo/shell/ShellCommandException.java   |   59 -
 .../apache/accumulo/shell/ShellCompletor.java   |  162 ---
 .../apache/accumulo/shell/ShellExtension.java   |   27 -
 .../org/apache/accumulo/shell/ShellOptions.java |   33 -
 .../apache/accumulo/shell/ShellOptionsJC.java   |  280 -----
 .../org/apache/accumulo/shell/ShellUtil.java    |   60 -
 .../java/org/apache/accumulo/shell/Token.java   |  137 --
 .../accumulo/shell/commands/AboutCommand.java   |   56 -
 .../commands/ActiveCompactionIterator.java      |  136 --
 .../shell/commands/ActiveScanIterator.java      |   91 --
 .../shell/commands/AddAuthsCommand.java         |   82 --
 .../shell/commands/AddSplitsCommand.java        |   88 --
 .../shell/commands/AuthenticateCommand.java     |   66 -
 .../accumulo/shell/commands/ByeCommand.java     |   19 -
 .../shell/commands/ClasspathCommand.java        |   55 -
 .../accumulo/shell/commands/ClearCommand.java   |   52 -
 .../shell/commands/CloneTableCommand.java       |  102 --
 .../accumulo/shell/commands/ClsCommand.java     |   19 -
 .../accumulo/shell/commands/CompactCommand.java |  129 --
 .../accumulo/shell/commands/ConfigCommand.java  |  315 -----
 .../shell/commands/ConstraintCommand.java       |  134 --
 .../shell/commands/CreateNamespaceCommand.java  |   99 --
 .../shell/commands/CreateTableCommand.java      |  203 ---
 .../shell/commands/CreateUserCommand.java       |   76 --
 .../accumulo/shell/commands/DUCommand.java      |  124 --
 .../accumulo/shell/commands/DebugCommand.java   |   71 --
 .../accumulo/shell/commands/DeleteCommand.java  |  112 --
 .../shell/commands/DeleteIterCommand.java       |  114 --
 .../shell/commands/DeleteManyCommand.java       |   82 --
 .../shell/commands/DeleteNamespaceCommand.java  |  100 --
 .../shell/commands/DeleteRowsCommand.java       |   65 -
 .../shell/commands/DeleteScanIterCommand.java   |  102 --
 .../shell/commands/DeleteShellIterCommand.java  |  100 --
 .../shell/commands/DeleteTableCommand.java      |   60 -
 .../shell/commands/DeleteUserCommand.java       |   19 -
 .../shell/commands/DropTableCommand.java        |   19 -
 .../shell/commands/DropUserCommand.java         |   61 -
 .../accumulo/shell/commands/EGrepCommand.java   |   59 -
 .../shell/commands/ExecfileCommand.java         |   67 -
 .../accumulo/shell/commands/ExitCommand.java    |   39 -
 .../shell/commands/ExportTableCommand.java      |   78 --
 .../shell/commands/ExtensionCommand.java        |  102 --
 .../accumulo/shell/commands/FateCommand.java    |  180 ---
 .../accumulo/shell/commands/FlushCommand.java   |   63 -
 .../shell/commands/FormatterCommand.java        |   69 --
 .../shell/commands/GetAuthsCommand.java         |   67 -
 .../shell/commands/GetGroupsCommand.java        |   60 -
 .../shell/commands/GetSplitsCommand.java        |  155 ---
 .../accumulo/shell/commands/GrantCommand.java   |  133 --
 .../accumulo/shell/commands/GrepCommand.java    |  111 --
 .../accumulo/shell/commands/HelpCommand.java    |  129 --
 .../accumulo/shell/commands/HiddenCommand.java  |   62 -
 .../accumulo/shell/commands/HistoryCommand.java |   82 --
 .../shell/commands/ImportDirectoryCommand.java  |   58 -
 .../shell/commands/ImportTableCommand.java      |   51 -
 .../accumulo/shell/commands/InfoCommand.java    |   19 -
 .../accumulo/shell/commands/InsertCommand.java  |  148 ---
 .../shell/commands/InterpreterCommand.java      |   40 -
 .../shell/commands/ListCompactionsCommand.java  |   78 --
 .../shell/commands/ListIterCommand.java         |  140 ---
 .../shell/commands/ListScansCommand.java        |   78 --
 .../shell/commands/ListShellIterCommand.java    |  105 --
 .../accumulo/shell/commands/MaxRowCommand.java  |   55 -
 .../accumulo/shell/commands/MergeCommand.java   |  111 --
 .../commands/NamespacePermissionsCommand.java   |   44 -
 .../shell/commands/NamespacesCommand.java       |   83 --
 .../accumulo/shell/commands/NoTableCommand.java |   40 -
 .../accumulo/shell/commands/OfflineCommand.java |   61 -
 .../accumulo/shell/commands/OnlineCommand.java  |   61 -
 .../apache/accumulo/shell/commands/OptUtil.java |  146 ---
 .../accumulo/shell/commands/PasswdCommand.java  |   96 --
 .../accumulo/shell/commands/PingCommand.java    |   82 --
 .../accumulo/shell/commands/PingIterator.java   |   58 -
 .../shell/commands/QuestionCommand.java         |   24 -
 .../accumulo/shell/commands/QuitCommand.java    |   19 -
 .../shell/commands/QuotedStringTokenizer.java   |  141 ---
 .../shell/commands/RenameNamespaceCommand.java  |   79 --
 .../shell/commands/RenameTableCommand.java      |   62 -
 .../accumulo/shell/commands/RevokeCommand.java  |  133 --
 .../accumulo/shell/commands/ScanCommand.java    |  334 -----
 .../accumulo/shell/commands/ScriptCommand.java  |  290 -----
 .../shell/commands/SetAuthsCommand.java         |   77 --
 .../shell/commands/SetGroupsCommand.java        |   78 --
 .../accumulo/shell/commands/SetIterCommand.java |  453 -------
 .../shell/commands/SetScanIterCommand.java      |  127 --
 .../shell/commands/SetShellIterCommand.java     |  131 --
 .../ShellPluginConfigurationCommand.java        |  146 ---
 .../accumulo/shell/commands/SleepCommand.java   |   46 -
 .../commands/SystemPermissionsCommand.java      |   44 -
 .../accumulo/shell/commands/TableCommand.java   |   60 -
 .../accumulo/shell/commands/TableOperation.java |  153 ---
 .../shell/commands/TablePermissionsCommand.java |   44 -
 .../accumulo/shell/commands/TablesCommand.java  |  107 --
 .../accumulo/shell/commands/TraceCommand.java   |  101 --
 .../accumulo/shell/commands/UserCommand.java    |   71 --
 .../shell/commands/UserPermissionsCommand.java  |  106 --
 .../accumulo/shell/commands/UsersCommand.java   |   45 -
 .../accumulo/shell/commands/WhoAmICommand.java  |   41 -
 .../accumulo/shell/format/DeleterFormatter.java |  102 --
 .../apache/accumulo/shell/mock/MockShell.java   |  143 ---
 shell/src/main/resources/.gitignore             |    0
 .../accumulo/shell/PasswordConverterTest.java   |  113 --
 .../apache/accumulo/shell/ShellConfigTest.java  |   91 --
 .../accumulo/shell/ShellSetInstanceTest.java    |  244 ----
 .../org/apache/accumulo/shell/ShellTest.java    |  282 -----
 .../apache/accumulo/shell/ShellUtilTest.java    |   67 -
 .../shell/command/FormatterCommandTest.java     |  184 ---
 .../shell/format/DeleterFormatterTest.java      |  177 ---
 shell/src/test/resources/log4j.properties       |   28 -
 shell/src/test/resources/shelltest.txt          |   16 -
 .../java/org/apache/accumulo/start/Main.java    |    2 +-
 .../org/apache/accumulo/test/ShellServerIT.java |    2 +-
 230 files changed, 12036 insertions(+), 12190 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/pom.xml
----------------------------------------------------------------------
diff --git a/core/pom.xml b/core/pom.xml
index 2572fc1..a89846c 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -35,6 +35,10 @@
       <artifactId>guava</artifactId>
     </dependency>
     <dependency>
+      <groupId>commons-cli</groupId>
+      <artifactId>commons-cli</artifactId>
+    </dependency>
+    <dependency>
       <groupId>commons-codec</groupId>
       <artifactId>commons-codec</artifactId>
     </dependency>
@@ -118,6 +122,21 @@
       <scope>test</scope>
     </dependency>
     <dependency>
+      <groupId>org.powermock</groupId>
+      <artifactId>powermock-api-easymock</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.powermock</groupId>
+      <artifactId>powermock-core</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.powermock</groupId>
+      <artifactId>powermock-module-junit4</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
       <groupId>org.slf4j</groupId>
       <artifactId>slf4j-log4j12</artifactId>
       <scope>test</scope>

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/client/mock/MockShell.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/client/mock/MockShell.java b/core/src/main/java/org/apache/accumulo/core/client/mock/MockShell.java
new file mode 100644
index 0000000..a8061f7
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/client/mock/MockShell.java
@@ -0,0 +1,142 @@
+/*
+ * 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.accumulo.core.client.mock;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.charset.StandardCharsets;
+
+import jline.console.ConsoleReader;
+
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.core.util.shell.ShellOptionsJC;
+
+/**
+ * An Accumulo Shell implementation that allows a developer to attach an InputStream and Writer to the Shell for testing purposes.
+ */
+public class MockShell extends Shell {
+  private static final String NEWLINE = "\n";
+  
+  protected InputStream in;
+  protected OutputStream out;
+  
+  public MockShell(InputStream in, OutputStream out) throws IOException {
+    super();
+    this.in = in;
+    this.out = out;
+  }
+  
+  public boolean config(String... args) {
+    configError = super.config(args);
+    
+    // Update the ConsoleReader with the input and output "redirected"
+    try {
+      this.reader = new ConsoleReader(in, out);
+    } catch (Exception e) {
+      printException(e);
+      configError = true;
+    }
+    
+    // Don't need this for testing purposes
+    this.reader.setHistoryEnabled(false);
+    this.reader.setPaginationEnabled(false);
+    
+    // Make the parsing from the client easier;
+    this.verbose = false;
+    return configError;
+  }
+  
+  @Override
+  protected void setInstance(ShellOptionsJC options) {
+    // We always want a MockInstance for this test
+    instance = new MockInstance();
+  }
+  
+  public int start() throws IOException {
+    if (configError)
+      return 1;
+    
+    String input;
+    if (isVerbose())
+      printInfo();
+    
+    if (execFile != null) {
+      java.util.Scanner scanner = new java.util.Scanner(execFile, StandardCharsets.UTF_8.name());
+      try {
+        while (scanner.hasNextLine() && !hasExited()) {
+          execCommand(scanner.nextLine(), true, isVerbose());
+        }
+      } finally {
+        scanner.close();
+      }
+    } else if (execCommand != null) {
+      for (String command : execCommand.split("\n")) {
+        execCommand(command, true, isVerbose());
+      }
+      return exitCode;
+    }
+    
+    while (true) {
+      if (hasExited())
+        return exitCode;
+      
+      reader.setPrompt(getDefaultPrompt());
+      input = reader.readLine();
+      if (input == null) {
+        reader.println();
+        return exitCode;
+      } // user canceled
+      
+      execCommand(input, false, false);
+    }
+  }
+  
+  /**
+   * @param in
+   *          the in to set
+   */
+  public void setConsoleInputStream(InputStream in) {
+    this.in = in;
+  }
+  
+  /**
+   * @param out
+   *          the output stream to set
+   */
+  public void setConsoleWriter(OutputStream out) {
+    this.out = out;
+  }
+  
+  /**
+   * Convenience method to create the byte-array to hand to the console
+   * 
+   * @param commands
+   *          An array of commands to run
+   * @return A byte[] input stream which can be handed to the console.
+   */
+  public static ByteArrayInputStream makeCommands(String... commands) {
+    StringBuilder sb = new StringBuilder(commands.length * 8);
+    
+    for (String command : commands) {
+      sb.append(command).append(NEWLINE);
+    }
+    
+    return new ByteArrayInputStream(sb.toString().getBytes(StandardCharsets.UTF_8));
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/format/DeleterFormatter.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/format/DeleterFormatter.java b/core/src/main/java/org/apache/accumulo/core/util/format/DeleterFormatter.java
new file mode 100644
index 0000000..7ac0510
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/format/DeleterFormatter.java
@@ -0,0 +1,101 @@
+/*
+ * 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.accumulo.core.util.format;
+
+import java.io.IOException;
+import java.util.Map.Entry;
+
+import org.apache.accumulo.core.client.BatchWriter;
+import org.apache.accumulo.core.client.MutationsRejectedException;
+import org.apache.accumulo.core.data.ConstraintViolationSummary;
+import org.apache.accumulo.core.data.Key;
+import org.apache.accumulo.core.data.Mutation;
+import org.apache.accumulo.core.data.Value;
+import org.apache.accumulo.core.security.ColumnVisibility;
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.log4j.Logger;
+
+public class DeleterFormatter extends DefaultFormatter {
+  
+  private static final Logger log = Logger.getLogger(DeleterFormatter.class);
+  private BatchWriter writer;
+  private Shell shellState;
+  private boolean printTimestamps;
+  private boolean force;
+  private boolean more;
+  
+  public DeleterFormatter(BatchWriter writer, Iterable<Entry<Key,Value>> scanner, boolean printTimestamps, Shell shellState, boolean force) {
+    super.initialize(scanner, printTimestamps);
+    this.writer = writer;
+    this.shellState = shellState;
+    this.printTimestamps = printTimestamps;
+    this.force = force;
+    this.more = true;
+  }
+  
+  @Override
+  public boolean hasNext() {
+    if (!getScannerIterator().hasNext() || !more) {
+      try {
+        writer.close();
+      } catch (MutationsRejectedException e) {
+        log.error(e.toString());
+        if (Shell.isDebuggingEnabled())
+          for (ConstraintViolationSummary cvs : e.getConstraintViolationSummaries())
+            log.trace(cvs.toString());
+      }
+      return false;
+    }
+    return true;
+  }
+  
+  /**
+   * @return null, because the iteration will provide prompts and handle deletes internally.
+   */
+  @Override
+  public String next() {
+    Entry<Key,Value> next = getScannerIterator().next();
+    Key key = next.getKey();
+    Mutation m = new Mutation(key.getRow());
+    String entryStr = formatEntry(next, printTimestamps);
+    boolean delete = force;
+    try {
+      if (!force) {
+        shellState.getReader().flush();
+        String line = shellState.getReader().readLine("Delete { " + entryStr + " } ? ");
+        more = line != null;
+        delete = line != null && (line.equalsIgnoreCase("y") || line.equalsIgnoreCase("yes"));
+      }
+      if (delete) {
+        m.putDelete(key.getColumnFamily(), key.getColumnQualifier(), new ColumnVisibility(key.getColumnVisibility()), key.getTimestamp());
+        try {
+          writer.addMutation(m);
+        } catch (MutationsRejectedException e) {
+          log.error(e.toString());
+          if (Shell.isDebuggingEnabled())
+            for (ConstraintViolationSummary cvs : e.getConstraintViolationSummaries())
+              log.trace(cvs.toString());
+        }
+      }
+      shellState.getReader().print(String.format("[%s] %s%n", delete ? "DELETED" : "SKIPPED", entryStr));
+    } catch (IOException e) {
+      log.error("Cannot write to console", e);
+      throw new RuntimeException(e);
+    }
+    return null;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/Shell.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/Shell.java b/core/src/main/java/org/apache/accumulo/core/util/shell/Shell.java
new file mode 100644
index 0000000..f481395
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/Shell.java
@@ -0,0 +1,1168 @@
+/*
+ * 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.accumulo.core.util.shell;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.net.InetAddress;
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.UUID;
+
+import jline.console.ConsoleReader;
+import jline.console.UserInterruptException;
+import jline.console.history.FileHistory;
+
+import org.apache.accumulo.core.Constants;
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.ClientConfiguration;
+import org.apache.accumulo.core.client.ClientConfiguration.ClientProperty;
+import org.apache.accumulo.core.client.Connector;
+import org.apache.accumulo.core.client.Instance;
+import org.apache.accumulo.core.client.IteratorSetting;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.core.client.ZooKeeperInstance;
+import org.apache.accumulo.core.client.impl.ServerConfigurationUtil;
+import org.apache.accumulo.core.client.impl.Tables;
+import org.apache.accumulo.core.client.mock.MockInstance;
+import org.apache.accumulo.core.client.security.tokens.AuthenticationToken;
+import org.apache.accumulo.core.client.security.tokens.PasswordToken;
+import org.apache.accumulo.core.conf.AccumuloConfiguration;
+import org.apache.accumulo.core.conf.DefaultConfiguration;
+import org.apache.accumulo.core.conf.Property;
+import org.apache.accumulo.core.conf.SiteConfiguration;
+import org.apache.accumulo.core.data.Key;
+import org.apache.accumulo.core.data.Value;
+import org.apache.accumulo.core.data.thrift.TConstraintViolationSummary;
+import org.apache.accumulo.core.tabletserver.thrift.ConstraintViolationException;
+import org.apache.accumulo.core.trace.DistributedTrace;
+import org.apache.accumulo.core.util.BadArgumentException;
+import org.apache.accumulo.core.util.format.BinaryFormatter;
+import org.apache.accumulo.core.util.format.DefaultFormatter;
+import org.apache.accumulo.core.util.format.Formatter;
+import org.apache.accumulo.core.util.format.FormatterFactory;
+import org.apache.accumulo.core.util.shell.commands.AboutCommand;
+import org.apache.accumulo.core.util.shell.commands.AddAuthsCommand;
+import org.apache.accumulo.core.util.shell.commands.AddSplitsCommand;
+import org.apache.accumulo.core.util.shell.commands.AuthenticateCommand;
+import org.apache.accumulo.core.util.shell.commands.ByeCommand;
+import org.apache.accumulo.core.util.shell.commands.ClasspathCommand;
+import org.apache.accumulo.core.util.shell.commands.ClearCommand;
+import org.apache.accumulo.core.util.shell.commands.CloneTableCommand;
+import org.apache.accumulo.core.util.shell.commands.ClsCommand;
+import org.apache.accumulo.core.util.shell.commands.CompactCommand;
+import org.apache.accumulo.core.util.shell.commands.ConfigCommand;
+import org.apache.accumulo.core.util.shell.commands.ConstraintCommand;
+import org.apache.accumulo.core.util.shell.commands.CreateNamespaceCommand;
+import org.apache.accumulo.core.util.shell.commands.CreateTableCommand;
+import org.apache.accumulo.core.util.shell.commands.CreateUserCommand;
+import org.apache.accumulo.core.util.shell.commands.DUCommand;
+import org.apache.accumulo.core.util.shell.commands.DebugCommand;
+import org.apache.accumulo.core.util.shell.commands.DeleteCommand;
+import org.apache.accumulo.core.util.shell.commands.DeleteIterCommand;
+import org.apache.accumulo.core.util.shell.commands.DeleteManyCommand;
+import org.apache.accumulo.core.util.shell.commands.DeleteNamespaceCommand;
+import org.apache.accumulo.core.util.shell.commands.DeleteRowsCommand;
+import org.apache.accumulo.core.util.shell.commands.DeleteScanIterCommand;
+import org.apache.accumulo.core.util.shell.commands.DeleteShellIterCommand;
+import org.apache.accumulo.core.util.shell.commands.DeleteTableCommand;
+import org.apache.accumulo.core.util.shell.commands.DeleteUserCommand;
+import org.apache.accumulo.core.util.shell.commands.DropTableCommand;
+import org.apache.accumulo.core.util.shell.commands.DropUserCommand;
+import org.apache.accumulo.core.util.shell.commands.EGrepCommand;
+import org.apache.accumulo.core.util.shell.commands.ExecfileCommand;
+import org.apache.accumulo.core.util.shell.commands.ExitCommand;
+import org.apache.accumulo.core.util.shell.commands.ExportTableCommand;
+import org.apache.accumulo.core.util.shell.commands.ExtensionCommand;
+import org.apache.accumulo.core.util.shell.commands.FateCommand;
+import org.apache.accumulo.core.util.shell.commands.FlushCommand;
+import org.apache.accumulo.core.util.shell.commands.FormatterCommand;
+import org.apache.accumulo.core.util.shell.commands.GetAuthsCommand;
+import org.apache.accumulo.core.util.shell.commands.GetGroupsCommand;
+import org.apache.accumulo.core.util.shell.commands.GetSplitsCommand;
+import org.apache.accumulo.core.util.shell.commands.GrantCommand;
+import org.apache.accumulo.core.util.shell.commands.GrepCommand;
+import org.apache.accumulo.core.util.shell.commands.HelpCommand;
+import org.apache.accumulo.core.util.shell.commands.HiddenCommand;
+import org.apache.accumulo.core.util.shell.commands.HistoryCommand;
+import org.apache.accumulo.core.util.shell.commands.ImportDirectoryCommand;
+import org.apache.accumulo.core.util.shell.commands.ImportTableCommand;
+import org.apache.accumulo.core.util.shell.commands.InfoCommand;
+import org.apache.accumulo.core.util.shell.commands.InsertCommand;
+import org.apache.accumulo.core.util.shell.commands.InterpreterCommand;
+import org.apache.accumulo.core.util.shell.commands.ListCompactionsCommand;
+import org.apache.accumulo.core.util.shell.commands.ListIterCommand;
+import org.apache.accumulo.core.util.shell.commands.ListScansCommand;
+import org.apache.accumulo.core.util.shell.commands.ListShellIterCommand;
+import org.apache.accumulo.core.util.shell.commands.MaxRowCommand;
+import org.apache.accumulo.core.util.shell.commands.MergeCommand;
+import org.apache.accumulo.core.util.shell.commands.NamespacePermissionsCommand;
+import org.apache.accumulo.core.util.shell.commands.NamespacesCommand;
+import org.apache.accumulo.core.util.shell.commands.NoTableCommand;
+import org.apache.accumulo.core.util.shell.commands.OfflineCommand;
+import org.apache.accumulo.core.util.shell.commands.OnlineCommand;
+import org.apache.accumulo.core.util.shell.commands.PasswdCommand;
+import org.apache.accumulo.core.util.shell.commands.PingCommand;
+import org.apache.accumulo.core.util.shell.commands.QuestionCommand;
+import org.apache.accumulo.core.util.shell.commands.QuitCommand;
+import org.apache.accumulo.core.util.shell.commands.QuotedStringTokenizer;
+import org.apache.accumulo.core.util.shell.commands.RenameNamespaceCommand;
+import org.apache.accumulo.core.util.shell.commands.RenameTableCommand;
+import org.apache.accumulo.core.util.shell.commands.RevokeCommand;
+import org.apache.accumulo.core.util.shell.commands.ScanCommand;
+import org.apache.accumulo.core.util.shell.commands.ScriptCommand;
+import org.apache.accumulo.core.util.shell.commands.SetAuthsCommand;
+import org.apache.accumulo.core.util.shell.commands.SetGroupsCommand;
+import org.apache.accumulo.core.util.shell.commands.SetIterCommand;
+import org.apache.accumulo.core.util.shell.commands.SetScanIterCommand;
+import org.apache.accumulo.core.util.shell.commands.SetShellIterCommand;
+import org.apache.accumulo.core.util.shell.commands.SleepCommand;
+import org.apache.accumulo.core.util.shell.commands.SystemPermissionsCommand;
+import org.apache.accumulo.core.util.shell.commands.TableCommand;
+import org.apache.accumulo.core.util.shell.commands.TablePermissionsCommand;
+import org.apache.accumulo.core.util.shell.commands.TablesCommand;
+import org.apache.accumulo.core.util.shell.commands.TraceCommand;
+import org.apache.accumulo.core.util.shell.commands.UserCommand;
+import org.apache.accumulo.core.util.shell.commands.UserPermissionsCommand;
+import org.apache.accumulo.core.util.shell.commands.UsersCommand;
+import org.apache.accumulo.core.util.shell.commands.WhoAmICommand;
+import org.apache.accumulo.core.volume.VolumeConfiguration;
+import org.apache.accumulo.core.zookeeper.ZooUtil;
+import org.apache.accumulo.fate.zookeeper.ZooReader;
+import org.apache.commons.cli.BasicParser;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.HelpFormatter;
+import org.apache.commons.cli.MissingOptionException;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+import org.apache.commons.cli.ParseException;
+import org.apache.hadoop.fs.Path;
+import org.apache.log4j.Level;
+import org.apache.log4j.Logger;
+
+import com.beust.jcommander.JCommander;
+import com.beust.jcommander.ParameterException;
+
+/**
+ * A convenient console interface to perform basic accumulo functions Includes auto-complete, help, and quoted strings with escape sequences
+ */
+public class Shell extends ShellOptions {
+  public static final Logger log = Logger.getLogger(Shell.class);
+  private static final Logger audit = Logger.getLogger(Shell.class.getName() + ".audit");
+
+  public static final String CHARSET = "ISO-8859-1";
+  public static final int NO_FIXED_ARG_LENGTH_CHECK = -1;
+  public static final String COMMENT_PREFIX = "#";
+  public static final String HISTORY_DIR_NAME = ".accumulo";
+  public static final String HISTORY_FILE_NAME = "shell_history.txt";
+  private static final String SHELL_DESCRIPTION = "Shell - Apache Accumulo Interactive Shell";
+
+  protected int exitCode = 0;
+  private String tableName;
+  protected Instance instance;
+  private Connector connector;
+  protected ConsoleReader reader;
+  private String principal;
+  private AuthenticationToken token;
+  private final Class<? extends Formatter> defaultFormatterClass = DefaultFormatter.class;
+  private final Class<? extends Formatter> binaryFormatterClass = BinaryFormatter.class;
+  public Map<String,List<IteratorSetting>> scanIteratorOptions = new HashMap<String,List<IteratorSetting>>();
+  public Map<String,List<IteratorSetting>> iteratorProfiles = new HashMap<String,List<IteratorSetting>>();
+
+  private Token rootToken;
+  public final Map<String,Command> commandFactory = new TreeMap<String,Command>();
+  public final Map<String,Command[]> commandGrouping = new TreeMap<String,Command[]>();
+  protected boolean configError = false;
+
+  // exit if true
+  private boolean exit = false;
+
+  // file to execute commands from
+  protected File execFile = null;
+  // single command to execute from the command line
+  protected String execCommand = null;
+  protected boolean verbose = true;
+
+  private boolean tabCompletion;
+  private boolean disableAuthTimeout;
+  private long authTimeout;
+  private long lastUserActivity = System.currentTimeMillis();
+  private boolean logErrorsToConsole = false;
+  private PrintWriter writer = null;
+  private boolean masking = false;
+
+  public Shell() throws IOException {
+    this(new ConsoleReader(), new PrintWriter(
+        new OutputStreamWriter(System.out,
+        System.getProperty("jline.WindowsTerminal.output.encoding", System.getProperty("file.encoding")))));
+  }
+
+  public Shell(ConsoleReader reader, PrintWriter writer) {
+    super();
+    this.reader = reader;
+    this.writer = writer;
+  }
+
+  // Not for client use
+  public boolean config(String... args) {
+    ShellOptionsJC options = new ShellOptionsJC();
+    JCommander jc = new JCommander();
+
+    jc.setProgramName("accumulo shell");
+    jc.addObject(options);
+    try {
+      jc.parse(args);
+    } catch (ParameterException e) {
+      configError = true;
+    }
+
+    if (options.isHelpEnabled()) {
+      configError = true;
+    }
+
+    if (!configError && options.getUnrecognizedOptions() != null) {
+      configError = true;
+      logError("Unrecognized Options: " + options.getUnrecognizedOptions().toString());
+    }
+
+    if (configError) {
+      jc.usage();
+      return true;
+    }
+
+    setDebugging(options.isDebugEnabled());
+    authTimeout = options.getAuthTimeout() * 60 * 1000; // convert minutes to milliseconds
+    disableAuthTimeout = options.isAuthTimeoutDisabled();
+
+    // get the options that were parsed
+    String user = options.getUsername();
+    String password = options.getPassword();
+
+    tabCompletion = !options.isTabCompletionDisabled();
+
+    // Use a fake (Mock), ZK, or HdfsZK Accumulo instance
+    setInstance(options);
+
+    // AuthenticationToken options
+    token = options.getAuthenticationToken();
+    Map<String,String> loginOptions = options.getTokenProperties();
+
+    // process default parameters if unspecified
+    try {
+      boolean hasToken = (token != null);
+      boolean hasTokenOptions = !loginOptions.isEmpty();
+
+      if (hasToken && password != null) {
+        throw new ParameterException("Can not supply '--pass' option with '--tokenClass' option");
+      }
+
+      Runtime.getRuntime().addShutdownHook(new Thread() {
+        @Override
+        public void run() {
+          reader.getTerminal().setEchoEnabled(true);
+        }
+      });
+
+      // Need either both a token and options, or neither, but not just one.
+      if (hasToken != hasTokenOptions) {
+        throw new ParameterException("Must supply either both or neither of '--tokenClass' and '--tokenProperty'");
+      } else if (hasToken) { // implied hasTokenOptions
+        // Fully qualified name so we don't shadow java.util.Properties
+        org.apache.accumulo.core.client.security.tokens.AuthenticationToken.Properties props;
+        // and line wrap it because the package name is so long
+        props = new org.apache.accumulo.core.client.security.tokens.AuthenticationToken.Properties();
+
+        props.putAllStrings(loginOptions);
+        token.init(props);
+      } else {
+        // Read password if the user explicitly asked for it, or didn't specify anything at all
+        if ("stdin".equals(password) || password == null) {
+          password = reader.readLine("Password: ", '*');
+        }
+
+        if (password == null) {
+          // User cancel, e.g. Ctrl-D pressed
+          throw new ParameterException("No password or token option supplied");
+        } else {
+          this.token = new PasswordToken(password);
+        }
+      }
+
+      if (!options.isFake()) {
+        ZooReader zr = new ZooReader(instance.getZooKeepers(), instance.getZooKeepersSessionTimeOut());
+        DistributedTrace.enable(instance, zr, "shell", InetAddress.getLocalHost().getHostName());
+      }
+
+      this.setTableName("");
+      this.principal = user;
+      connector = instance.getConnector(this.principal, token);
+
+    } catch (Exception e) {
+      printException(e);
+      configError = true;
+    }
+
+    // decide whether to execute commands from a file and quit
+    if (options.getExecFile() != null) {
+      execFile = options.getExecFile();
+      verbose = false;
+    } else if (options.getExecFileVerbose() != null) {
+      execFile = options.getExecFileVerbose();
+      verbose = true;
+    }
+    execCommand = options.getExecCommand();
+    if (execCommand != null) {
+      verbose = false;
+    }
+
+    rootToken = new Token();
+
+    Command[] dataCommands = {new DeleteCommand(), new DeleteManyCommand(), new DeleteRowsCommand(), new EGrepCommand(), new FormatterCommand(),
+        new InterpreterCommand(), new GrepCommand(), new ImportDirectoryCommand(), new InsertCommand(), new MaxRowCommand(), new ScanCommand()};
+    Command[] debuggingCommands = {new ClasspathCommand(), new DebugCommand(), new ListScansCommand(), new ListCompactionsCommand(), new TraceCommand(),
+        new PingCommand()};
+    Command[] execCommands = {new ExecfileCommand(), new HistoryCommand(), new ExtensionCommand(), new ScriptCommand()};
+    Command[] exitCommands = {new ByeCommand(), new ExitCommand(), new QuitCommand()};
+    Command[] helpCommands = {new AboutCommand(), new HelpCommand(), new InfoCommand(), new QuestionCommand()};
+    Command[] iteratorCommands = {new DeleteIterCommand(), new DeleteScanIterCommand(), new ListIterCommand(), new SetIterCommand(), new SetScanIterCommand(),
+        new SetShellIterCommand(), new ListShellIterCommand(), new DeleteShellIterCommand()};
+    Command[] otherCommands = {new HiddenCommand()};
+    Command[] permissionsCommands = {new GrantCommand(), new RevokeCommand(), new SystemPermissionsCommand(), new TablePermissionsCommand(),
+        new UserPermissionsCommand(), new NamespacePermissionsCommand()};
+    Command[] stateCommands = {new AuthenticateCommand(), new ClsCommand(), new ClearCommand(), new FateCommand(), new NoTableCommand(), new SleepCommand(),
+        new TableCommand(), new UserCommand(), new WhoAmICommand()};
+    Command[] tableCommands = {new CloneTableCommand(), new ConfigCommand(), new CreateTableCommand(), new DeleteTableCommand(), new DropTableCommand(),
+        new DUCommand(), new ExportTableCommand(), new ImportTableCommand(), new OfflineCommand(), new OnlineCommand(), new RenameTableCommand(),
+        new TablesCommand(), new NamespacesCommand(), new CreateNamespaceCommand(), new DeleteNamespaceCommand(), new RenameNamespaceCommand()};
+    Command[] tableControlCommands = {new AddSplitsCommand(), new CompactCommand(), new ConstraintCommand(), new FlushCommand(), new GetGroupsCommand(),
+        new GetSplitsCommand(), new MergeCommand(), new SetGroupsCommand()};
+    Command[] userCommands = {new AddAuthsCommand(), new CreateUserCommand(), new DeleteUserCommand(), new DropUserCommand(), new GetAuthsCommand(),
+        new PasswdCommand(), new SetAuthsCommand(), new UsersCommand()};
+    commandGrouping.put("-- Writing, Reading, and Removing Data --", dataCommands);
+    commandGrouping.put("-- Debugging Commands -------------------", debuggingCommands);
+    commandGrouping.put("-- Shell Execution Commands -------------", execCommands);
+    commandGrouping.put("-- Exiting Commands ---------------------", exitCommands);
+    commandGrouping.put("-- Help Commands ------------------------", helpCommands);
+    commandGrouping.put("-- Iterator Configuration ---------------", iteratorCommands);
+    commandGrouping.put("-- Permissions Administration Commands --", permissionsCommands);
+    commandGrouping.put("-- Shell State Commands -----------------", stateCommands);
+    commandGrouping.put("-- Table Administration Commands --------", tableCommands);
+    commandGrouping.put("-- Table Control Commands ---------------", tableControlCommands);
+    commandGrouping.put("-- User Administration Commands ---------", userCommands);
+
+    for (Command[] cmds : commandGrouping.values()) {
+      for (Command cmd : cmds)
+        commandFactory.put(cmd.getName(), cmd);
+    }
+    for (Command cmd : otherCommands) {
+      commandFactory.put(cmd.getName(), cmd);
+    }
+    return configError;
+  }
+
+  /**
+   * Sets the instance used by the shell based on the given options.
+   * 
+   * @param options
+   *          shell options
+   */
+  protected void setInstance(ShellOptionsJC options) {
+    // should only be one set of instance options set
+    instance = null;
+    if (options.isFake()) {
+      instance = new MockInstance("fake");
+    } else {
+      String instanceName, hosts;
+      if (options.isHdfsZooInstance()) {
+        instanceName = hosts = null;
+      } else if (options.getZooKeeperInstance().size() > 0) {
+        List<String> zkOpts = options.getZooKeeperInstance();
+        instanceName = zkOpts.get(0);
+        hosts = zkOpts.get(1);
+      } else {
+        instanceName = options.getZooKeeperInstanceName();
+        hosts = options.getZooKeeperHosts();
+      }
+      try {
+        instance = getZooInstance(instanceName, hosts, options.getClientConfiguration());
+      } catch (Exception e) {
+        throw new IllegalArgumentException("Unable to load client config from " + options.getClientConfigFile(), e);
+      }
+    }
+  }
+
+  /*
+   * Takes instanceName and keepers as separate arguments, rather than just packaged into the clientConfig, so that we can fail over to accumulo-site.xml or
+   * HDFS config if they're unspecified.
+   */
+  private static Instance getZooInstance(String instanceName, String keepers, ClientConfiguration clientConfig) {
+    UUID instanceId = null;
+    if (instanceName == null) {
+      instanceName = clientConfig.get(ClientProperty.INSTANCE_NAME);
+    }
+    if (instanceName == null || keepers == null) {
+      AccumuloConfiguration conf = SiteConfiguration.getInstance(ServerConfigurationUtil.convertClientConfig(DefaultConfiguration.getInstance(), clientConfig));
+      if (instanceName == null) {
+        Path instanceDir = new Path(VolumeConfiguration.getVolumeUris(conf)[0], "instance_id");
+        instanceId = UUID.fromString(ZooUtil.getInstanceIDFromHdfs(instanceDir, conf));
+      }
+      if (keepers == null) {
+        keepers = conf.get(Property.INSTANCE_ZK_HOST);
+      }
+    }
+    if (instanceId != null) {
+      return new ZooKeeperInstance(clientConfig.withInstance(instanceId).withZkHosts(keepers));
+    } else {
+      return new ZooKeeperInstance(clientConfig.withInstance(instanceName).withZkHosts(keepers));
+    }
+  }
+
+  public Connector getConnector() {
+    return connector;
+  }
+
+  public Instance getInstance() {
+    return instance;
+  }
+
+  public static void main(String args[]) throws IOException {
+    Shell shell = new Shell();
+    try {
+      shell.config(args);
+
+      System.exit(shell.start());
+    } finally {
+      shell.shutdown();
+    }
+  }
+
+  public int start() throws IOException {
+    if (configError)
+      return 1;
+
+    String input;
+    if (isVerbose())
+      printInfo();
+
+    String home = System.getProperty("HOME");
+    if (home == null)
+      home = System.getenv("HOME");
+    String configDir = home + "/" + HISTORY_DIR_NAME;
+    String historyPath = configDir + "/" + HISTORY_FILE_NAME;
+    File accumuloDir = new File(configDir);
+    if (!accumuloDir.exists() && !accumuloDir.mkdirs())
+      log.warn("Unable to make directory for history at " + accumuloDir);
+    try {
+      final FileHistory history = new FileHistory(new File(historyPath));
+      reader.setHistory(history);
+      // Add shutdown hook to flush file history, per jline javadocs
+      Runtime.getRuntime().addShutdownHook(new Thread() {
+        @Override
+        public void run() {
+          try {
+            history.flush();
+          } catch (IOException e) {
+            log.warn("Could not flush history to file.");
+          }
+        }
+      });
+    } catch (IOException e) {
+      log.warn("Unable to load history file at " + historyPath);
+    }
+
+    // Turn Ctrl+C into Exception instead of JVM exit
+    reader.setHandleUserInterrupt(true);
+
+    ShellCompletor userCompletor = null;
+
+    if (execFile != null) {
+      java.util.Scanner scanner = new java.util.Scanner(execFile, StandardCharsets.UTF_8.name());
+      try {
+        while (scanner.hasNextLine() && !hasExited()) {
+          execCommand(scanner.nextLine(), true, isVerbose());
+        }
+      } finally {
+        scanner.close();
+      }
+    } else if (execCommand != null) {
+      for (String command : execCommand.split("\n")) {
+        execCommand(command, true, isVerbose());
+      }
+      return exitCode;
+    }
+
+    while (true) {
+      try {
+        if (hasExited())
+          return exitCode;
+
+        // If tab completion is true we need to reset
+        if (tabCompletion) {
+          if (userCompletor != null)
+            reader.removeCompleter(userCompletor);
+
+          userCompletor = setupCompletion();
+          reader.addCompleter(userCompletor);
+        }
+
+        reader.setPrompt(getDefaultPrompt());
+        input = reader.readLine();
+        if (input == null) {
+          reader.println();
+          return exitCode;
+        } // User Canceled (Ctrl+D)
+
+        execCommand(input, disableAuthTimeout, false);
+      } catch (UserInterruptException uie) {
+        // User Cancelled (Ctrl+C)
+        reader.println();
+
+        String partialLine = uie.getPartialLine();
+        if (partialLine == null || "".equals(uie.getPartialLine().trim())) {
+          // No content, actually exit
+          return exitCode;
+        }
+      } finally {
+        reader.flush();
+      }
+    }
+  }
+
+  public void shutdown() {
+    if (reader != null) {
+      reader.shutdown();
+    }
+  }
+
+  public void printInfo() throws IOException {
+    reader.print("\n" + SHELL_DESCRIPTION + "\n" + "- \n" + "- version: " + Constants.VERSION + "\n" + "- instance name: "
+        + connector.getInstance().getInstanceName() + "\n" + "- instance id: " + connector.getInstance().getInstanceID() + "\n" + "- \n"
+        + "- type 'help' for a list of available commands\n" + "- \n");
+    reader.flush();
+  }
+
+  public void printVerboseInfo() throws IOException {
+    StringBuilder sb = new StringBuilder("-\n");
+    sb.append("- Current user: ").append(connector.whoami()).append("\n");
+    if (execFile != null)
+      sb.append("- Executing commands from: ").append(execFile).append("\n");
+    if (disableAuthTimeout)
+      sb.append("- Authorization timeout: disabled\n");
+    else
+      sb.append("- Authorization timeout: ").append(String.format("%.2fs%n", authTimeout / 1000.0));
+    sb.append("- Debug: ").append(isDebuggingEnabled() ? "on" : "off").append("\n");
+    if (!scanIteratorOptions.isEmpty()) {
+      for (Entry<String,List<IteratorSetting>> entry : scanIteratorOptions.entrySet()) {
+        sb.append("- Session scan iterators for table ").append(entry.getKey()).append(":\n");
+        for (IteratorSetting setting : entry.getValue()) {
+          sb.append("-    Iterator ").append(setting.getName()).append(" options:\n");
+          sb.append("-        ").append("iteratorPriority").append(" = ").append(setting.getPriority()).append("\n");
+          sb.append("-        ").append("iteratorClassName").append(" = ").append(setting.getIteratorClass()).append("\n");
+          for (Entry<String,String> optEntry : setting.getOptions().entrySet()) {
+            sb.append("-        ").append(optEntry.getKey()).append(" = ").append(optEntry.getValue()).append("\n");
+          }
+        }
+      }
+    }
+    sb.append("-\n");
+    reader.print(sb.toString());
+  }
+
+  public String getDefaultPrompt() {
+    return connector.whoami() + "@" + connector.getInstance().getInstanceName() + (getTableName().isEmpty() ? "" : " ") + getTableName() + "> ";
+  }
+
+  public void execCommand(String input, boolean ignoreAuthTimeout, boolean echoPrompt) throws IOException {
+    audit.log(Level.INFO, getDefaultPrompt() + input);
+    if (echoPrompt) {
+      reader.print(getDefaultPrompt());
+      reader.println(input);
+    }
+
+    if (input.startsWith(COMMENT_PREFIX)) {
+      return;
+    }
+
+    String fields[];
+    try {
+      fields = new QuotedStringTokenizer(input).getTokens();
+    } catch (BadArgumentException e) {
+      printException(e);
+      ++exitCode;
+      return;
+    }
+    if (fields.length == 0)
+      return;
+
+    String command = fields[0];
+    fields = fields.length > 1 ? Arrays.copyOfRange(fields, 1, fields.length) : new String[] {};
+
+    Command sc = null;
+    if (command.length() > 0) {
+      try {
+        // Obtain the command from the command table
+        sc = commandFactory.get(command);
+        if (sc == null) {
+          reader.println(String.format("Unknown command \"%s\".  Enter \"help\" for a list possible commands.", command));
+          reader.flush();
+          return;
+        }
+
+        if (!(sc instanceof ExitCommand) && !ignoreAuthTimeout && System.currentTimeMillis() - lastUserActivity > authTimeout) {
+          reader.println("Shell has been idle for too long. Please re-authenticate.");
+          boolean authFailed = true;
+          do {
+            String pwd = readMaskedLine("Enter current password for '" + connector.whoami() + "': ", '*');
+            if (pwd == null) {
+              reader.println();
+              return;
+            } // user canceled
+
+            try {
+              authFailed = !connector.securityOperations().authenticateUser(connector.whoami(), new PasswordToken(pwd));
+            } catch (Exception e) {
+              ++exitCode;
+              printException(e);
+            }
+
+            if (authFailed)
+              reader.print("Invalid password. ");
+          } while (authFailed);
+          lastUserActivity = System.currentTimeMillis();
+        }
+
+        // Get the options from the command on how to parse the string
+        Options parseOpts = sc.getOptionsWithHelp();
+
+        // Parse the string using the given options
+        CommandLine cl = new BasicParser().parse(parseOpts, fields);
+
+        int actualArgLen = cl.getArgs().length;
+        int expectedArgLen = sc.numArgs();
+        if (cl.hasOption(helpOption)) {
+          // Display help if asked to; otherwise execute the command
+          sc.printHelp(this);
+        } else if (expectedArgLen != NO_FIXED_ARG_LENGTH_CHECK && actualArgLen != expectedArgLen) {
+          ++exitCode;
+          // Check for valid number of fixed arguments (if not
+          // negative; negative means it is not checked, for
+          // vararg-like commands)
+          printException(new IllegalArgumentException(String.format("Expected %d argument%s. There %s %d.", expectedArgLen, expectedArgLen == 1 ? "" : "s",
+              actualArgLen == 1 ? "was" : "were", actualArgLen)));
+          sc.printHelp(this);
+        } else {
+          int tmpCode = sc.execute(input, cl, this);
+          exitCode += tmpCode;
+          reader.flush();
+        }
+
+      } catch (ConstraintViolationException e) {
+        ++exitCode;
+        printConstraintViolationException(e);
+      } catch (TableNotFoundException e) {
+        ++exitCode;
+        if (getTableName().equals(e.getTableName()))
+          setTableName("");
+        printException(e);
+      } catch (ParseException e) {
+        // not really an error if the exception is a missing required
+        // option when the user is asking for help
+        if (!(e instanceof MissingOptionException && (Arrays.asList(fields).contains("-" + helpOption) || Arrays.asList(fields).contains("--" + helpLongOption)))) {
+          ++exitCode;
+          printException(e);
+        }
+        if (sc != null)
+          sc.printHelp(this);
+      } catch (UserInterruptException e) {
+        ++exitCode;
+      } catch (Exception e) {
+        ++exitCode;
+        printException(e);
+      }
+    } else {
+      ++exitCode;
+      printException(new BadArgumentException("Unrecognized empty command", command, -1));
+    }
+    reader.flush();
+  }
+
+  /**
+   * The command tree is built in reverse so that the references are more easily linked up. There is some code in token to allow forward building of the command
+   * tree.
+   */
+  private ShellCompletor setupCompletion() {
+    rootToken = new Token();
+
+    Set<String> tableNames = null;
+    try {
+      tableNames = connector.tableOperations().list();
+    } catch (Exception e) {
+      log.debug("Unable to obtain list of tables", e);
+      tableNames = Collections.emptySet();
+    }
+
+    Set<String> userlist = null;
+    try {
+      userlist = connector.securityOperations().listLocalUsers();
+    } catch (Exception e) {
+      log.debug("Unable to obtain list of users", e);
+      userlist = Collections.emptySet();
+    }
+
+    Set<String> namespaces = null;
+    try {
+      namespaces = connector.namespaceOperations().list();
+    } catch (Exception e) {
+      log.debug("Unable to obtain list of namespaces", e);
+      namespaces = Collections.emptySet();
+    }
+
+    Map<Command.CompletionSet,Set<String>> options = new HashMap<Command.CompletionSet,Set<String>>();
+
+    Set<String> commands = new HashSet<String>();
+    for (String a : commandFactory.keySet())
+      commands.add(a);
+
+    Set<String> modifiedUserlist = new HashSet<String>();
+    Set<String> modifiedTablenames = new HashSet<String>();
+    Set<String> modifiedNamespaces = new HashSet<String>();
+
+    for (String a : tableNames)
+      modifiedTablenames.add(a.replaceAll("([\\s'\"])", "\\\\$1"));
+    for (String a : userlist)
+      modifiedUserlist.add(a.replaceAll("([\\s'\"])", "\\\\$1"));
+    for (String a : namespaces) {
+      String b = a.replaceAll("([\\s'\"])", "\\\\$1");
+      modifiedNamespaces.add(b.isEmpty() ? "\"\"" : b);
+    }
+
+    options.put(Command.CompletionSet.USERNAMES, modifiedUserlist);
+    options.put(Command.CompletionSet.TABLENAMES, modifiedTablenames);
+    options.put(Command.CompletionSet.NAMESPACES, modifiedNamespaces);
+    options.put(Command.CompletionSet.COMMANDS, commands);
+
+    for (Command[] cmdGroup : commandGrouping.values()) {
+      for (Command c : cmdGroup) {
+        c.getOptionsWithHelp(); // prep the options for the command
+        // so that the completion can
+        // include them
+        c.registerCompletion(rootToken, options);
+      }
+    }
+    return new ShellCompletor(rootToken, options);
+  }
+
+  /**
+   * The Command class represents a command to be run in the shell. It contains the methods to execute along with some methods to help tab completion, and
+   * return the command name, help, and usage.
+   */
+  public static abstract class Command {
+    // Helper methods for completion
+    public enum CompletionSet {
+      TABLENAMES, USERNAMES, COMMANDS, NAMESPACES
+    }
+
+    static Set<String> getCommandNames(Map<CompletionSet,Set<String>> objects) {
+      return objects.get(CompletionSet.COMMANDS);
+    }
+
+    static Set<String> getTableNames(Map<CompletionSet,Set<String>> objects) {
+      return objects.get(CompletionSet.TABLENAMES);
+    }
+
+    static Set<String> getUserNames(Map<CompletionSet,Set<String>> objects) {
+      return objects.get(CompletionSet.USERNAMES);
+    }
+
+    static Set<String> getNamespaces(Map<CompletionSet,Set<String>> objects) {
+      return objects.get(CompletionSet.NAMESPACES);
+    }
+
+    public void registerCompletionGeneral(Token root, Set<String> args, boolean caseSens) {
+      Token t = new Token(args);
+      t.setCaseSensitive(caseSens);
+
+      Token command = new Token(getName());
+      command.addSubcommand(t);
+
+      root.addSubcommand(command);
+    }
+
+    public void registerCompletionForTables(Token root, Map<CompletionSet,Set<String>> completionSet) {
+      registerCompletionGeneral(root, completionSet.get(CompletionSet.TABLENAMES), true);
+    }
+
+    public void registerCompletionForUsers(Token root, Map<CompletionSet,Set<String>> completionSet) {
+      registerCompletionGeneral(root, completionSet.get(CompletionSet.USERNAMES), true);
+    }
+
+    public void registerCompletionForCommands(Token root, Map<CompletionSet,Set<String>> completionSet) {
+      registerCompletionGeneral(root, completionSet.get(CompletionSet.COMMANDS), false);
+    }
+
+    public void registerCompletionForNamespaces(Token root, Map<CompletionSet,Set<String>> completionSet) {
+      registerCompletionGeneral(root, completionSet.get(CompletionSet.NAMESPACES), true);
+    }
+
+    // abstract methods to override
+    public abstract int execute(String fullCommand, CommandLine cl, Shell shellState) throws Exception;
+
+    public abstract String description();
+
+    /**
+     * If the number of arguments is not always zero (not including those arguments handled through Options), make sure to override the {@link #usage()} method.
+     * Otherwise, {@link #usage()} does need to be overridden.
+     */
+    public abstract int numArgs();
+
+    // OPTIONAL methods to override:
+
+    // the general version of getname uses reflection to get the class name
+    // and then cuts off the suffix -Command to get the name of the command
+    public String getName() {
+      String s = this.getClass().getName();
+      int st = Math.max(s.lastIndexOf('$'), s.lastIndexOf('.'));
+      int i = s.indexOf("Command");
+      return i > 0 ? s.substring(st + 1, i).toLowerCase(Locale.ENGLISH) : null;
+    }
+
+    // The general version of this method adds the name
+    // of the command to the completion tree
+    public void registerCompletion(Token root, Map<CompletionSet,Set<String>> completion_set) {
+      root.addSubcommand(new Token(getName()));
+    }
+
+    // The general version of this method uses the HelpFormatter
+    // that comes with the apache Options package to print out the help
+    public final void printHelp(Shell shellState) {
+      shellState.printHelp(usage(), "description: " + this.description(), getOptionsWithHelp());
+    }
+
+    public final void printHelp(Shell shellState, int width) {
+      shellState.printHelp(usage(), "description: " + this.description(), getOptionsWithHelp(), width);
+    }
+
+    // Get options with help
+    public final Options getOptionsWithHelp() {
+      Options opts = getOptions();
+      opts.addOption(new Option(helpOption, helpLongOption, false, "display this help"));
+      return opts;
+    }
+
+    // General usage is just the command
+    public String usage() {
+      return getName();
+    }
+
+    // General Options are empty
+    public Options getOptions() {
+      return new Options();
+    }
+  }
+
+  public interface PrintLine {
+    void print(String s);
+
+    void close();
+  }
+
+  public static class PrintShell implements PrintLine {
+    ConsoleReader reader;
+
+    public PrintShell(ConsoleReader reader) {
+      this.reader = reader;
+    }
+
+    @Override
+    public void print(String s) {
+      try {
+        reader.println(s);
+      } catch (Exception ex) {
+        throw new RuntimeException(ex);
+      }
+    }
+
+    @Override
+    public void close() {}
+  };
+
+  public static class PrintFile implements PrintLine {
+    PrintWriter writer;
+
+    public PrintFile(String filename) throws FileNotFoundException {
+      writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(filename), StandardCharsets.UTF_8)));
+    }
+
+    @Override
+    public void print(String s) {
+      writer.println(s);
+    }
+
+    @Override
+    public void close() {
+      writer.close();
+    }
+  };
+
+  public final void printLines(Iterator<String> lines, boolean paginate) throws IOException {
+    printLines(lines, paginate, null);
+  }
+
+  public final void printLines(Iterator<String> lines, boolean paginate, PrintLine out) throws IOException {
+    int linesPrinted = 0;
+    String prompt = "-- hit any key to continue or 'q' to quit --";
+    int lastPromptLength = prompt.length();
+    int termWidth = reader.getTerminal().getWidth();
+    int maxLines = reader.getTerminal().getHeight();
+
+    String peek = null;
+    while (lines.hasNext()) {
+      String nextLine = lines.next();
+      if (nextLine == null)
+        continue;
+      for (String line : nextLine.split("\\n")) {
+        if (out == null) {
+          if (peek != null) {
+            reader.println(peek);
+            if (paginate) {
+              linesPrinted += peek.length() == 0 ? 0 : Math.ceil(peek.length() * 1.0 / termWidth);
+
+              // check if displaying the next line would result in
+              // scrolling off the screen
+              if (linesPrinted + Math.ceil(lastPromptLength * 1.0 / termWidth) + Math.ceil(prompt.length() * 1.0 / termWidth)
+                  + Math.ceil(line.length() * 1.0 / termWidth) > maxLines) {
+                linesPrinted = 0;
+                int numdashes = (termWidth - prompt.length()) / 2;
+                String nextPrompt = repeat("-", numdashes) + prompt + repeat("-", numdashes);
+                lastPromptLength = nextPrompt.length();
+                reader.print(nextPrompt);
+                reader.flush();
+
+                if (Character.toUpperCase((char) reader.readCharacter()) == 'Q') {
+                  reader.println();
+                  return;
+                }
+                reader.println();
+                termWidth = reader.getTerminal().getWidth();
+                maxLines = reader.getTerminal().getHeight();
+              }
+            }
+          }
+          peek = line;
+        } else {
+          out.print(line);
+        }
+      }
+    }
+    if (out == null && peek != null) {
+      reader.println(peek);
+    }
+  }
+
+  public final void printRecords(Iterable<Entry<Key,Value>> scanner, boolean printTimestamps, boolean paginate, Class<? extends Formatter> formatterClass,
+      PrintLine outFile) throws IOException {
+    printLines(FormatterFactory.getFormatter(formatterClass, scanner, printTimestamps), paginate, outFile);
+  }
+
+  public final void printRecords(Iterable<Entry<Key,Value>> scanner, boolean printTimestamps, boolean paginate, Class<? extends Formatter> formatterClass)
+      throws IOException {
+    printLines(FormatterFactory.getFormatter(formatterClass, scanner, printTimestamps), paginate);
+  }
+
+  public final void printBinaryRecords(Iterable<Entry<Key,Value>> scanner, boolean printTimestamps, boolean paginate, PrintLine outFile) throws IOException {
+    printLines(FormatterFactory.getFormatter(binaryFormatterClass, scanner, printTimestamps), paginate, outFile);
+  }
+
+  public final void printBinaryRecords(Iterable<Entry<Key,Value>> scanner, boolean printTimestamps, boolean paginate) throws IOException {
+    printLines(FormatterFactory.getFormatter(binaryFormatterClass, scanner, printTimestamps), paginate);
+  }
+
+  public static String repeat(String s, int c) {
+    StringBuilder sb = new StringBuilder();
+    for (int i = 0; i < c; i++)
+      sb.append(s);
+    return sb.toString();
+  }
+
+  public void checkTableState() {
+    if (getTableName().isEmpty())
+      throw new IllegalStateException(
+          "Not in a table context. Please use 'table <tableName>' to switch to a table, or use '-t' to specify a table if option is available.");
+  }
+
+  private final void printConstraintViolationException(ConstraintViolationException cve) {
+    printException(cve, "");
+    int COL1 = 50, COL2 = 14;
+    int col3 = Math.max(1, Math.min(Integer.MAX_VALUE, reader.getTerminal().getWidth() - COL1 - COL2 - 6));
+    logError(String.format("%" + COL1 + "s-+-%" + COL2 + "s-+-%" + col3 + "s%n", repeat("-", COL1), repeat("-", COL2), repeat("-", col3)));
+    logError(String.format("%-" + COL1 + "s | %" + COL2 + "s | %-" + col3 + "s%n", "Constraint class", "Violation code", "Violation Description"));
+    logError(String.format("%" + COL1 + "s-+-%" + COL2 + "s-+-%" + col3 + "s%n", repeat("-", COL1), repeat("-", COL2), repeat("-", col3)));
+    for (TConstraintViolationSummary cvs : cve.violationSummaries)
+      logError(String.format("%-" + COL1 + "s | %" + COL2 + "d | %-" + col3 + "s%n", cvs.constrainClass, cvs.violationCode, cvs.violationDescription));
+    logError(String.format("%" + COL1 + "s-+-%" + COL2 + "s-+-%" + col3 + "s%n", repeat("-", COL1), repeat("-", COL2), repeat("-", col3)));
+  }
+
+  public final void printException(Exception e) {
+    printException(e, e.getMessage());
+  }
+
+  private final void printException(Exception e, String msg) {
+    logError(e.getClass().getName() + (msg != null ? ": " + msg : ""));
+    log.debug(e.getClass().getName() + (msg != null ? ": " + msg : ""), e);
+  }
+
+  public static final void setDebugging(boolean debuggingEnabled) {
+    Logger.getLogger(Constants.CORE_PACKAGE_NAME).setLevel(debuggingEnabled ? Level.TRACE : Level.INFO);
+  }
+
+  public static final boolean isDebuggingEnabled() {
+    return Logger.getLogger(Constants.CORE_PACKAGE_NAME).isTraceEnabled();
+  }
+
+  private final void printHelp(String usage, String description, Options opts) {
+    printHelp(usage, description, opts, Integer.MAX_VALUE);
+  }
+
+  private final void printHelp(String usage, String description, Options opts, int width) {
+    // TODO Use the OutputStream from the JLine ConsoleReader if we can ever get access to it
+    new HelpFormatter().printHelp(writer, width, usage, description, opts, 2, 5, null, true);
+    writer.flush();
+  }
+
+  public int getExitCode() {
+    return exitCode;
+  }
+
+  public void resetExitCode() {
+    exitCode = 0;
+  }
+
+  public void setExit(boolean exit) {
+    this.exit = exit;
+  }
+
+  public boolean getExit() {
+    return this.exit;
+  }
+
+  public boolean isVerbose() {
+    return verbose;
+  }
+
+  public void setTableName(String tableName) {
+    this.tableName = (tableName == null || tableName.isEmpty()) ? "" : Tables.qualified(tableName);
+  }
+
+  public String getTableName() {
+    return tableName;
+  }
+
+  public ConsoleReader getReader() {
+    return reader;
+  }
+
+  public void updateUser(String principal, AuthenticationToken token) throws AccumuloException, AccumuloSecurityException {
+    connector = instance.getConnector(principal, token);
+    this.principal = principal;
+    this.token = token;
+  }
+
+  public String getPrincipal() {
+    return principal;
+  }
+
+  public AuthenticationToken getToken() {
+    return token;
+  }
+
+  /**
+   * Return the formatter for the current table.
+   * 
+   * @return the formatter class for the current table
+   */
+  public Class<? extends Formatter> getFormatter() {
+    return getFormatter(this.tableName);
+  }
+
+  /**
+   * Return the formatter for the given table.
+   * 
+   * @param tableName
+   *          the table name
+   * @return the formatter class for the given table
+   */
+  public Class<? extends Formatter> getFormatter(String tableName) {
+    Class<? extends Formatter> formatter = FormatterCommand.getCurrentFormatter(tableName, this);
+
+    if (null == formatter) {
+      logError("Could not load the specified formatter. Using the DefaultFormatter");
+      return this.defaultFormatterClass;
+    } else {
+      return formatter;
+    }
+  }
+
+  public void setLogErrorsToConsole() {
+    this.logErrorsToConsole = true;
+  }
+
+  private void logError(String s) {
+    log.error(s);
+    if (logErrorsToConsole) {
+      try {
+        reader.println("ERROR: " + s);
+        reader.flush();
+      } catch (IOException e) {}
+    }
+  }
+
+  public String readMaskedLine(String prompt, Character mask) throws IOException {
+    this.masking = true;
+    String s = reader.readLine(prompt, mask);
+    this.masking = false;
+    return s;
+  }
+
+  public boolean isMasking() {
+    return masking;
+  }
+
+  public boolean hasExited() {
+    return exit;
+  }
+
+  public boolean isTabCompletion() {
+    return tabCompletion;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/ShellCommandException.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/ShellCommandException.java b/core/src/main/java/org/apache/accumulo/core/util/shell/ShellCommandException.java
new file mode 100644
index 0000000..6bef379
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/ShellCommandException.java
@@ -0,0 +1,59 @@
+/*
+ * 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.accumulo.core.util.shell;
+
+public class ShellCommandException extends Exception {
+  private static final long serialVersionUID = 1L;
+  
+  public enum ErrorCode {
+    UNKNOWN_ERROR("Unknown error"),
+    UNSUPPORTED_LANGUAGE("Programming language used is not supported"),
+    UNRECOGNIZED_COMMAND("Command is not supported"),
+    INITIALIZATION_FAILURE("Command could not be initialized"),
+    XML_PARSING_ERROR("Failed to parse the XML file");
+    
+    private String description;
+    
+    private ErrorCode(String description) {
+      this.description = description;
+    }
+    
+    public String getDescription() {
+      return this.description;
+    }
+    
+    public String toString() {
+      return getDescription();
+    }
+  }
+  
+  private ErrorCode code;
+  private String command;
+  
+  public ShellCommandException(ErrorCode code) {
+    this(code, null);
+  }
+  
+  public ShellCommandException(ErrorCode code, String command) {
+    this.code = code;
+    this.command = command;
+  }
+  
+  public String getMessage() {
+    return code + (command != null ? " (" + command + ")" : "");
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/ShellCompletor.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/ShellCompletor.java b/core/src/main/java/org/apache/accumulo/core/util/shell/ShellCompletor.java
new file mode 100644
index 0000000..c64e0c7
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/ShellCompletor.java
@@ -0,0 +1,162 @@
+/*
+ * 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.accumulo.core.util.shell;
+
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import jline.console.completer.Completer;
+
+import org.apache.accumulo.core.util.shell.Shell.Command.CompletionSet;
+import org.apache.accumulo.core.util.shell.commands.QuotedStringTokenizer;
+
+public class ShellCompletor implements Completer {
+
+  // private static final Logger log = Logger.getLogger(ShellCompletor.class);
+
+  Map<CompletionSet,Set<String>> options;
+  Token root = null;
+
+  public ShellCompletor() {}
+
+  public ShellCompletor(Token root) {
+    this.root = root;
+  }
+
+  public ShellCompletor(Token rootToken, Map<CompletionSet,Set<String>> options) {
+    this.root = rootToken;
+    this.options = options;
+  }
+
+  @Override
+  @SuppressWarnings({"unchecked", "rawtypes"})
+  public int complete(String buffer, int cursor, List candidates) {
+    try {
+      return _complete(buffer, cursor, candidates);
+    } catch (Exception e) {
+      candidates.add("");
+      candidates.add(e.getMessage());
+      return cursor;
+    }
+  }
+
+  private int _complete(String fullBuffer, int cursor, List<String> candidates) {
+    boolean inTableFlag = false, inUserFlag = false, inNamespaceFlag = false;
+    // Only want to grab the buffer up to the cursor because
+    // the user could be trying to tab complete in the middle
+    // of the line
+    String buffer = fullBuffer.substring(0, cursor);
+
+    Token current_command_token = root;
+    String current_string_token = null;
+    boolean end_space = buffer.endsWith(" ");
+
+    // tabbing with no text
+    if (buffer.length() == 0) {
+      candidates.addAll(root.getSubcommandNames());
+      return 0;
+    }
+
+    String prefix = "";
+
+    QuotedStringTokenizer qst = new QuotedStringTokenizer(buffer);
+
+    Iterator<String> iter = qst.iterator();
+    while (iter.hasNext()) {
+      current_string_token = iter.next();
+      current_string_token = current_string_token.replaceAll("([\\s'\"])", "\\\\$1");
+
+      if (!iter.hasNext()) {
+        // if we end in a space and that space isn't part of the last token
+        // (which would be the case at the start of a quote) OR the buffer
+        // ends with a " indicating that we need to start on the next command
+        // and not complete the current command.
+        if (end_space && !current_string_token.endsWith(" ") || buffer.endsWith("\"")) {
+          // match subcommands
+
+          // we're in a subcommand so try to match the universal
+          // option flags if we're there
+          if (current_string_token.trim().equals("-" + Shell.tableOption)) {
+            candidates.addAll(options.get(Shell.Command.CompletionSet.TABLENAMES));
+            prefix += "-" + Shell.tableOption + " ";
+          } else if (current_string_token.trim().equals("-" + Shell.userOption)) {
+            candidates.addAll(options.get(Shell.Command.CompletionSet.USERNAMES));
+            prefix += "-" + Shell.userOption + " ";
+          } else if (current_string_token.trim().equals("-" + Shell.namespaceOption)) {
+            candidates.addAll(options.get(Shell.Command.CompletionSet.NAMESPACES));
+            prefix += "-" + Shell.namespaceOption + " ";
+          } else if (current_command_token != null) {
+            Token next = current_command_token.getSubcommand(current_string_token);
+            if (next != null) {
+              current_command_token = next;
+
+              if (current_command_token.getCaseSensitive())
+                prefix += current_string_token + " ";
+              else
+                prefix += current_string_token.toUpperCase() + " ";
+
+              candidates.addAll(current_command_token.getSubcommandNames());
+            }
+          }
+          Collections.sort(candidates);
+          return (prefix.length());
+        }
+        // need to match current command
+        // if we're in -t <table>, -u <user>, or -tn <namespace> complete those
+        if (inTableFlag) {
+          for (String a : options.get(Shell.Command.CompletionSet.TABLENAMES))
+            if (a.startsWith(current_string_token))
+              candidates.add(a);
+        } else if (inUserFlag) {
+          for (String a : options.get(Shell.Command.CompletionSet.USERNAMES))
+            if (a.startsWith(current_string_token))
+              candidates.add(a);
+        } else if (inNamespaceFlag) {
+          for (String a : options.get(Shell.Command.CompletionSet.NAMESPACES))
+            if (a.startsWith(current_string_token))
+              candidates.add(a);
+        } else if (current_command_token != null)
+          candidates.addAll(current_command_token.getSubcommandNames(current_string_token));
+
+        Collections.sort(candidates);
+        return (prefix.length());
+      }
+
+      if (current_string_token.trim().equals("-" + Shell.tableOption))
+        inTableFlag = true;
+      else if (current_string_token.trim().equals("-" + Shell.userOption))
+        inUserFlag = true;
+      else if (current_string_token.trim().equals("-" + Shell.namespaceOption))
+        inNamespaceFlag = true;
+      else
+        inUserFlag = inTableFlag = inNamespaceFlag = false;
+
+      if (current_command_token != null && current_command_token.getCaseSensitive())
+        prefix += current_string_token + " ";
+      else
+        prefix += current_string_token.toUpperCase() + " ";
+
+      if (current_command_token != null && current_command_token.getSubcommandNames().contains(current_string_token))
+        current_command_token = current_command_token.getSubcommand(current_string_token);
+
+    }
+    return 0;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/ShellExtension.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/ShellExtension.java b/core/src/main/java/org/apache/accumulo/core/util/shell/ShellExtension.java
new file mode 100644
index 0000000..5deccef
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/ShellExtension.java
@@ -0,0 +1,27 @@
+/*
+ * 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.accumulo.core.util.shell;
+
+import org.apache.accumulo.core.util.shell.Shell.Command;
+
+public abstract class ShellExtension {
+    
+    public abstract String getExtensionName();
+
+    public abstract Command[] getCommands();
+    
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/ShellOptions.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/ShellOptions.java b/core/src/main/java/org/apache/accumulo/core/util/shell/ShellOptions.java
new file mode 100644
index 0000000..4e573ed
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/ShellOptions.java
@@ -0,0 +1,33 @@
+/*
+ * 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.accumulo.core.util.shell;
+
+import org.apache.commons.cli.Option;
+
+/**
+ * Abstract class to encompass the Options available on the Accumulo Shell
+ */
+public abstract class ShellOptions {
+  // Global options flags
+  public static final String userOption = "u";
+  public static final String tableOption = "t";
+  public static final String namespaceOption = "ns";
+  public static final String helpOption = "?";
+  public static final String helpLongOption = "help";
+
+  final Option helpOpt = new Option(helpOption, helpLongOption, false, "display this help");
+}


[28/53] [abbrv] Revert "ACCUMULO-1897 Move shell into new package and module"

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SetIterCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SetIterCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SetIterCommand.java
new file mode 100644
index 0000000..3d8a5a7
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SetIterCommand.java
@@ -0,0 +1,453 @@
+/*
+ * 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.accumulo.core.util.shell.commands;
+
+import java.io.IOException;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import jline.console.ConsoleReader;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.IteratorSetting;
+import org.apache.accumulo.core.client.NamespaceNotFoundException;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.core.conf.Property;
+import org.apache.accumulo.core.data.Key;
+import org.apache.accumulo.core.data.Value;
+import org.apache.accumulo.core.iterators.IteratorUtil.IteratorScope;
+import org.apache.accumulo.core.iterators.OptionDescriber;
+import org.apache.accumulo.core.iterators.OptionDescriber.IteratorOptions;
+import org.apache.accumulo.core.iterators.SortedKeyValueIterator;
+import org.apache.accumulo.core.iterators.user.AgeOffFilter;
+import org.apache.accumulo.core.iterators.user.RegExFilter;
+import org.apache.accumulo.core.iterators.user.ReqVisFilter;
+import org.apache.accumulo.core.iterators.user.VersioningIterator;
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.core.util.shell.Shell.Command;
+import org.apache.accumulo.core.util.shell.ShellCommandException;
+import org.apache.accumulo.core.util.shell.ShellCommandException.ErrorCode;
+import org.apache.accumulo.start.classloader.vfs.AccumuloVFSClassLoader;
+import org.apache.accumulo.start.classloader.vfs.ContextManager;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.OptionGroup;
+import org.apache.commons.cli.Options;
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.vfs2.FileSystemException;
+
+public class SetIterCommand extends Command {
+
+  private Option allScopeOpt, mincScopeOpt, majcScopeOpt, scanScopeOpt, nameOpt, priorityOpt;
+  private Option aggTypeOpt, ageoffTypeOpt, regexTypeOpt, versionTypeOpt, reqvisTypeOpt, classnameTypeOpt;
+
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException,
+      TableNotFoundException, IOException, ShellCommandException {
+
+    boolean tables = cl.hasOption(OptUtil.tableOpt().getOpt()) || !shellState.getTableName().isEmpty();
+    boolean namespaces = cl.hasOption(OptUtil.namespaceOpt().getOpt());
+
+    final int priority = Integer.parseInt(cl.getOptionValue(priorityOpt.getOpt()));
+
+    final Map<String,String> options = new HashMap<String,String>();
+    String classname = cl.getOptionValue(classnameTypeOpt.getOpt());
+    if (cl.hasOption(aggTypeOpt.getOpt())) {
+      Shell.log.warn("aggregators are deprecated");
+      @SuppressWarnings("deprecation")
+      String deprecatedClassName = org.apache.accumulo.core.iterators.AggregatingIterator.class.getName();
+      classname = deprecatedClassName;
+    } else if (cl.hasOption(regexTypeOpt.getOpt())) {
+      classname = RegExFilter.class.getName();
+    } else if (cl.hasOption(ageoffTypeOpt.getOpt())) {
+      classname = AgeOffFilter.class.getName();
+    } else if (cl.hasOption(versionTypeOpt.getOpt())) {
+      classname = VersioningIterator.class.getName();
+    } else if (cl.hasOption(reqvisTypeOpt.getOpt())) {
+      classname = ReqVisFilter.class.getName();
+    }
+
+    ClassLoader classloader = getClassLoader(cl, shellState);
+
+    // Get the iterator options, with potentially a name provided by the OptionDescriber impl or through user input
+    String configuredName = setUpOptions(classloader, shellState.getReader(), classname, options);
+
+    // Try to get the name provided by the setiter command
+    String name = cl.getOptionValue(nameOpt.getOpt(), null);
+    
+    // Cannot continue if no name is provided
+    if (null == name && null == configuredName) {
+      throw new IllegalArgumentException("No provided or default name for iterator");
+    } else if (null == name) {
+      // Fall back to the name from OptionDescriber or user input if none is provided on setiter option
+      name = configuredName;
+    }
+
+    if (namespaces) {
+      try {
+        setNamespaceProperties(cl, shellState, priority, options, classname, name);
+      } catch (NamespaceNotFoundException e) {
+        throw new IllegalArgumentException(e);
+      }
+    } else if (tables) {
+      setTableProperties(cl, shellState, priority, options, classname, name);
+    } else {
+      throw new IllegalArgumentException("No table or namespace specified");
+    }
+    return 0;
+  }
+
+  private ClassLoader getClassLoader(final CommandLine cl, final Shell shellState) throws AccumuloException, TableNotFoundException, AccumuloSecurityException,
+      IOException, FileSystemException {
+
+    boolean tables = cl.hasOption(OptUtil.tableOpt().getOpt()) || !shellState.getTableName().isEmpty();
+    boolean namespaces = cl.hasOption(OptUtil.namespaceOpt().getOpt());
+
+    String classpath = null;
+    Iterable<Entry<String,String>> tableProps;
+
+    if (namespaces) {
+      try {
+        tableProps = shellState.getConnector().namespaceOperations().getProperties(OptUtil.getNamespaceOpt(cl, shellState));
+      } catch (NamespaceNotFoundException e) {
+        throw new IllegalArgumentException(e);
+      }
+    } else if (tables) {
+      tableProps = shellState.getConnector().tableOperations().getProperties(OptUtil.getTableOpt(cl, shellState));
+    } else {
+      throw new IllegalArgumentException("No table or namespace specified");
+    }
+    for (Entry<String,String> entry : tableProps) {
+      if (entry.getKey().equals(Property.TABLE_CLASSPATH.getKey())) {
+        classpath = entry.getValue();
+      }
+    }
+
+    ClassLoader classloader;
+
+    if (classpath != null && !classpath.equals("")) {
+      shellState.getConnector().instanceOperations().getSystemConfiguration().get(Property.VFS_CONTEXT_CLASSPATH_PROPERTY.getKey() + classpath);
+
+      try {
+        AccumuloVFSClassLoader.getContextManager().setContextConfig(new ContextManager.DefaultContextsConfig(new Iterable<Map.Entry<String,String>>() {
+          @Override
+          public Iterator<Entry<String,String>> iterator() {
+            try {
+              return shellState.getConnector().instanceOperations().getSystemConfiguration().entrySet().iterator();
+            } catch (AccumuloException e) {
+              throw new RuntimeException(e);
+            } catch (AccumuloSecurityException e) {
+              throw new RuntimeException(e);
+            }
+          }
+        }));
+      } catch (IllegalStateException ise) {}
+
+      classloader = AccumuloVFSClassLoader.getContextManager().getClassLoader(classpath);
+    } else {
+      classloader = AccumuloVFSClassLoader.getClassLoader();
+    }
+    return classloader;
+  }
+
+  protected void setTableProperties(final CommandLine cl, final Shell shellState, final int priority, final Map<String,String> options, final String classname,
+      final String name) throws AccumuloException, AccumuloSecurityException, ShellCommandException, TableNotFoundException {
+    // remove empty values
+
+    final String tableName = OptUtil.getTableOpt(cl, shellState);
+
+    if (!shellState.getConnector().tableOperations().testClassLoad(tableName, classname, SortedKeyValueIterator.class.getName())) {
+      throw new ShellCommandException(ErrorCode.INITIALIZATION_FAILURE, "Servers are unable to load " + classname + " as type "
+          + SortedKeyValueIterator.class.getName());
+    }
+
+    final String aggregatorClass = options.get("aggregatorClass");
+    @SuppressWarnings("deprecation")
+    String deprecatedAggregatorClassName = org.apache.accumulo.core.iterators.aggregation.Aggregator.class.getName();
+    if (aggregatorClass != null && !shellState.getConnector().tableOperations().testClassLoad(tableName, aggregatorClass, deprecatedAggregatorClassName)) {
+      throw new ShellCommandException(ErrorCode.INITIALIZATION_FAILURE, "Servers are unable to load " + aggregatorClass + " as type "
+          + deprecatedAggregatorClassName);
+    }
+
+    for (Iterator<Entry<String,String>> i = options.entrySet().iterator(); i.hasNext();) {
+      final Entry<String,String> entry = i.next();
+      if (entry.getValue() == null || entry.getValue().isEmpty()) {
+        i.remove();
+      }
+    }
+    final EnumSet<IteratorScope> scopes = EnumSet.noneOf(IteratorScope.class);
+    if (cl.hasOption(allScopeOpt.getOpt()) || cl.hasOption(mincScopeOpt.getOpt())) {
+      scopes.add(IteratorScope.minc);
+    }
+    if (cl.hasOption(allScopeOpt.getOpt()) || cl.hasOption(majcScopeOpt.getOpt())) {
+      scopes.add(IteratorScope.majc);
+    }
+    if (cl.hasOption(allScopeOpt.getOpt()) || cl.hasOption(scanScopeOpt.getOpt())) {
+      scopes.add(IteratorScope.scan);
+    }
+    if (scopes.isEmpty()) {
+      throw new IllegalArgumentException("You must select at least one scope to configure");
+    }
+    final IteratorSetting setting = new IteratorSetting(priority, name, classname, options);
+    shellState.getConnector().tableOperations().attachIterator(tableName, setting, scopes);
+  }
+
+  protected void setNamespaceProperties(final CommandLine cl, final Shell shellState, final int priority, final Map<String,String> options,
+      final String classname, final String name) throws AccumuloException, AccumuloSecurityException, ShellCommandException, NamespaceNotFoundException {
+    // remove empty values
+
+    final String namespace = OptUtil.getNamespaceOpt(cl, shellState);
+
+    if (!shellState.getConnector().namespaceOperations().testClassLoad(namespace, classname, SortedKeyValueIterator.class.getName())) {
+      throw new ShellCommandException(ErrorCode.INITIALIZATION_FAILURE, "Servers are unable to load " + classname + " as type "
+          + SortedKeyValueIterator.class.getName());
+    }
+
+    final String aggregatorClass = options.get("aggregatorClass");
+    @SuppressWarnings("deprecation")
+    String deprecatedAggregatorClassName = org.apache.accumulo.core.iterators.aggregation.Aggregator.class.getName();
+    if (aggregatorClass != null && !shellState.getConnector().namespaceOperations().testClassLoad(namespace, aggregatorClass, deprecatedAggregatorClassName)) {
+      throw new ShellCommandException(ErrorCode.INITIALIZATION_FAILURE, "Servers are unable to load " + aggregatorClass + " as type "
+          + deprecatedAggregatorClassName);
+    }
+
+    for (Iterator<Entry<String,String>> i = options.entrySet().iterator(); i.hasNext();) {
+      final Entry<String,String> entry = i.next();
+      if (entry.getValue() == null || entry.getValue().isEmpty()) {
+        i.remove();
+      }
+    }
+    final EnumSet<IteratorScope> scopes = EnumSet.noneOf(IteratorScope.class);
+    if (cl.hasOption(allScopeOpt.getOpt()) || cl.hasOption(mincScopeOpt.getOpt())) {
+      scopes.add(IteratorScope.minc);
+    }
+    if (cl.hasOption(allScopeOpt.getOpt()) || cl.hasOption(majcScopeOpt.getOpt())) {
+      scopes.add(IteratorScope.majc);
+    }
+    if (cl.hasOption(allScopeOpt.getOpt()) || cl.hasOption(scanScopeOpt.getOpt())) {
+      scopes.add(IteratorScope.scan);
+    }
+    if (scopes.isEmpty()) {
+      throw new IllegalArgumentException("You must select at least one scope to configure");
+    }
+    final IteratorSetting setting = new IteratorSetting(priority, name, classname, options);
+    shellState.getConnector().namespaceOperations().attachIterator(namespace, setting, scopes);
+  }
+
+  private static String setUpOptions(ClassLoader classloader, final ConsoleReader reader, final String className, final Map<String,String> options)
+      throws IOException, ShellCommandException {
+    String input;
+    @SuppressWarnings("rawtypes")
+    SortedKeyValueIterator untypedInstance;
+    @SuppressWarnings("rawtypes")
+    Class<? extends SortedKeyValueIterator> clazz;
+    try {
+      clazz = classloader.loadClass(className).asSubclass(SortedKeyValueIterator.class);
+      untypedInstance = clazz.newInstance();
+    } catch (ClassNotFoundException e) {
+      StringBuilder msg = new StringBuilder("Unable to load ").append(className);
+      if (className.indexOf('.') < 0) {
+        msg.append("; did you use a fully qualified package name?");
+      } else {
+        msg.append("; class not found.");
+      }
+      throw new ShellCommandException(ErrorCode.INITIALIZATION_FAILURE, msg.toString());
+    } catch (InstantiationException e) {
+      throw new IllegalArgumentException(e.getMessage());
+    } catch (IllegalAccessException e) {
+      throw new IllegalArgumentException(e.getMessage());
+    } catch (ClassCastException e) {
+      StringBuilder msg = new StringBuilder(50);
+      msg.append(className).append(" loaded successfully but does not implement SortedKeyValueIterator.");
+      msg.append(" This class cannot be used with this command.");
+      throw new ShellCommandException(ErrorCode.INITIALIZATION_FAILURE, msg.toString());
+    }
+
+    @SuppressWarnings("unchecked")
+    SortedKeyValueIterator<Key,Value> skvi = (SortedKeyValueIterator<Key,Value>) untypedInstance;
+    OptionDescriber iterOptions = null;
+    if (OptionDescriber.class.isAssignableFrom(skvi.getClass())) {
+      iterOptions = (OptionDescriber) skvi;
+    }
+
+    String iteratorName;
+    if (null != iterOptions) {
+      final IteratorOptions itopts = iterOptions.describeOptions();
+      iteratorName = itopts.getName();
+      
+      if (iteratorName == null) {
+        throw new IllegalArgumentException(className + " described its default distinguishing name as null");
+      }
+      String shortClassName = className;
+      if (className.contains(".")) {
+        shortClassName = className.substring(className.lastIndexOf('.') + 1);
+      }
+      final Map<String,String> localOptions = new HashMap<String,String>();
+      do {
+        // clean up the overall options that caused things to fail
+        for (String key : localOptions.keySet()) {
+          options.remove(key);
+        }
+        localOptions.clear();
+  
+        reader.println(itopts.getDescription());
+  
+        String prompt;
+        if (itopts.getNamedOptions() != null) {
+          for (Entry<String,String> e : itopts.getNamedOptions().entrySet()) {
+            prompt = Shell.repeat("-", 10) + "> set " + shortClassName + " parameter " + e.getKey() + ", " + e.getValue() + ": ";
+            reader.flush();
+            input = reader.readLine(prompt);
+            if (input == null) {
+              reader.println();
+              throw new IOException("Input stream closed");
+            }
+            // Places all Parameters and Values into the LocalOptions, even if the value is "".
+            // This allows us to check for "" values when setting the iterators and allows us to remove
+            // the parameter and value from the table property.
+            localOptions.put(e.getKey(), input);
+          }
+        }
+  
+        if (itopts.getUnnamedOptionDescriptions() != null) {
+          for (String desc : itopts.getUnnamedOptionDescriptions()) {
+            reader.println(Shell.repeat("-", 10) + "> entering options: " + desc);
+            input = "start";
+            prompt = Shell.repeat("-", 10) + "> set " + shortClassName + " option (<name> <value>, hit enter to skip): ";
+            while (true) {
+              reader.flush();
+              input = reader.readLine(prompt);
+              if (input == null) {
+                reader.println();
+                throw new IOException("Input stream closed");
+              } else {
+                input = new String(input);
+              }
+  
+              if (input.length() == 0)
+                break;
+  
+              String[] sa = input.split(" ", 2);
+              localOptions.put(sa[0], sa[1]);
+            }
+          }
+        }
+  
+        options.putAll(localOptions);
+        if (!iterOptions.validateOptions(options))
+          reader.println("invalid options for " + clazz.getName());
+  
+      } while (!iterOptions.validateOptions(options));
+    } else {
+      reader.flush();
+      reader.println("The iterator class does not implement OptionDescriber. Consider this for better iterator configuration using this setiter command.");
+      iteratorName = reader.readLine("Name for iterator (enter to skip): ");
+      if (null == iteratorName) {
+        reader.println();
+        throw new IOException("Input stream closed");
+      } else if (StringUtils.isWhitespace(iteratorName)) {
+        // Treat whitespace or empty string as no name provided
+        iteratorName = null;
+      }
+      
+      reader.flush();
+      reader.println("Optional, configure name-value options for iterator:");
+      String prompt = Shell.repeat("-", 10) + "> set option (<name> <value>, hit enter to skip): ";
+      final HashMap<String,String> localOptions = new HashMap<String,String>();
+      
+      while (true) {
+        reader.flush();
+        input = reader.readLine(prompt);
+        if (input == null) {
+          reader.println();
+          throw new IOException("Input stream closed");
+        } else if (StringUtils.isWhitespace(input)) {
+          break;
+        } 
+
+        String[] sa = input.split(" ", 2);
+        localOptions.put(sa[0], sa[1]);
+      }
+      
+      options.putAll(localOptions);
+    }
+    
+    return iteratorName;
+  }
+
+  @Override
+  public String description() {
+    return "sets a table-specific or namespace-specific iterator";
+  }
+
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+
+    priorityOpt = new Option("p", "priority", true, "the order in which the iterator is applied");
+    priorityOpt.setArgName("pri");
+    priorityOpt.setRequired(true);
+
+    nameOpt = new Option("n", "name", true, "iterator to set");
+    nameOpt.setArgName("itername");
+
+    allScopeOpt = new Option("all", "all-scopes", false, "applied at scan time, minor and major compactions");
+    mincScopeOpt = new Option(IteratorScope.minc.name(), "minor-compaction", false, "applied at minor compaction");
+    majcScopeOpt = new Option(IteratorScope.majc.name(), "major-compaction", false, "applied at major compaction");
+    scanScopeOpt = new Option(IteratorScope.scan.name(), "scan-time", false, "applied at scan time");
+
+    final OptionGroup typeGroup = new OptionGroup();
+    classnameTypeOpt = new Option("class", "class-name", true, "a java class that implements SortedKeyValueIterator");
+    classnameTypeOpt.setArgName("name");
+    aggTypeOpt = new Option("agg", "aggregator", false, "an aggregating type");
+    regexTypeOpt = new Option("regex", "regular-expression", false, "a regex matching iterator");
+    versionTypeOpt = new Option("vers", "version", false, "a versioning iterator");
+    reqvisTypeOpt = new Option("reqvis", "require-visibility", false, "an iterator that omits entries with empty visibilities");
+    ageoffTypeOpt = new Option("ageoff", "ageoff", false, "an aging off iterator");
+
+    typeGroup.addOption(classnameTypeOpt);
+    typeGroup.addOption(aggTypeOpt);
+    typeGroup.addOption(regexTypeOpt);
+    typeGroup.addOption(versionTypeOpt);
+    typeGroup.addOption(reqvisTypeOpt);
+    typeGroup.addOption(ageoffTypeOpt);
+    typeGroup.setRequired(true);
+
+    final OptionGroup tableGroup = new OptionGroup();
+    tableGroup.addOption(OptUtil.tableOpt("table to configure iterators on"));
+    tableGroup.addOption(OptUtil.namespaceOpt("namespace to configure iterators on"));
+
+    o.addOption(priorityOpt);
+    o.addOption(nameOpt);
+    o.addOption(allScopeOpt);
+    o.addOption(mincScopeOpt);
+    o.addOption(majcScopeOpt);
+    o.addOption(scanScopeOpt);
+    o.addOptionGroup(typeGroup);
+    o.addOptionGroup(tableGroup);
+    return o;
+  }
+
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SetScanIterCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SetScanIterCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SetScanIterCommand.java
new file mode 100644
index 0000000..513975c
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SetScanIterCommand.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.accumulo.core.util.shell.commands;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.IteratorSetting;
+import org.apache.accumulo.core.client.Scanner;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.core.iterators.IteratorUtil.IteratorScope;
+import org.apache.accumulo.core.iterators.SortedKeyValueIterator;
+import org.apache.accumulo.core.security.Authorizations;
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.core.util.shell.ShellCommandException;
+import org.apache.accumulo.core.util.shell.ShellCommandException.ErrorCode;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.OptionGroup;
+import org.apache.commons.cli.Options;
+
+public class SetScanIterCommand extends SetIterCommand {
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException, TableNotFoundException,
+      IOException, ShellCommandException {
+    Shell.log.warn("Deprecated, use " + new SetShellIterCommand().getName());
+    return super.execute(fullCommand, cl, shellState);
+  }
+  
+  @Override
+  protected void setTableProperties(final CommandLine cl, final Shell shellState, final int priority, final Map<String,String> options, final String classname,
+      final String name) throws AccumuloException, AccumuloSecurityException, ShellCommandException, TableNotFoundException {
+    
+    final String tableName = OptUtil.getTableOpt(cl, shellState);
+
+    // instead of setting table properties, just put the options in a list to use at scan time
+    Class<?> loadClass;
+    try {
+      loadClass = getClass().getClassLoader().loadClass(classname);
+    } catch (ClassNotFoundException e) {
+      throw new ShellCommandException(ErrorCode.INITIALIZATION_FAILURE, "Unable to load " + classname);
+    }
+    try {
+      loadClass.asSubclass(SortedKeyValueIterator.class);
+    } catch (ClassCastException ex) {
+      throw new ShellCommandException(ErrorCode.INITIALIZATION_FAILURE, "Unable to load " + classname  + " as type "
+          + SortedKeyValueIterator.class.getName());
+    }
+    
+    for (Iterator<Entry<String,String>> i = options.entrySet().iterator(); i.hasNext();) {
+      final Entry<String,String> entry = i.next();
+      if (entry.getValue() == null || entry.getValue().isEmpty()) {
+        i.remove();
+      }
+    }
+
+    List<IteratorSetting> tableScanIterators = shellState.scanIteratorOptions.get(tableName);
+    if (tableScanIterators == null) {
+      tableScanIterators = new ArrayList<IteratorSetting>();
+      shellState.scanIteratorOptions.put(tableName, tableScanIterators);
+    }
+    final IteratorSetting setting = new IteratorSetting(priority, name, classname);
+    setting.addOptions(options);
+    
+    // initialize a scanner to ensure the new setting does not conflict with existing settings
+    final String user = shellState.getConnector().whoami();
+    final Authorizations auths = shellState.getConnector().securityOperations().getUserAuthorizations(user);
+    final Scanner scanner = shellState.getConnector().createScanner(tableName, auths);
+    for (IteratorSetting s : tableScanIterators) {
+      scanner.addScanIterator(s);
+    }
+    scanner.addScanIterator(setting);
+    
+    // if no exception has been thrown, it's safe to add it to the list
+    tableScanIterators.add(setting);
+    Shell.log.debug("Scan iterators :" + shellState.scanIteratorOptions.get(tableName));
+  }
+  
+  @Override
+  public String description() {
+    return "sets a table-specific scan iterator for this shell session";
+  }
+  
+  @Override
+  public Options getOptions() {
+    // Remove the options that specify which type of iterator this is, since
+    // they are all scan iterators with this command.
+    final HashSet<OptionGroup> groups = new HashSet<OptionGroup>();
+    final Options parentOptions = super.getOptions();
+    final Options modifiedOptions = new Options();
+    for (Iterator<?> it = parentOptions.getOptions().iterator(); it.hasNext();) {
+      Option o = (Option) it.next();
+      if (!IteratorScope.majc.name().equals(o.getOpt()) && !IteratorScope.minc.name().equals(o.getOpt()) && !IteratorScope.scan.name().equals(o.getOpt())) {
+        modifiedOptions.addOption(o);
+        OptionGroup group = parentOptions.getOptionGroup(o);
+        if (group != null)
+          groups.add(group);
+      }
+    }
+    for (OptionGroup group : groups) {
+      modifiedOptions.addOptionGroup(group);
+    }
+    return modifiedOptions;
+  }
+  
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SetShellIterCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SetShellIterCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SetShellIterCommand.java
new file mode 100644
index 0000000..b95725a
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SetShellIterCommand.java
@@ -0,0 +1,131 @@
+/*
+ * 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.accumulo.core.util.shell.commands;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.IteratorSetting;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.core.iterators.IteratorUtil.IteratorScope;
+import org.apache.accumulo.core.iterators.SortedKeyValueIterator;
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.core.util.shell.ShellCommandException;
+import org.apache.accumulo.core.util.shell.ShellCommandException.ErrorCode;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.OptionGroup;
+import org.apache.commons.cli.Options;
+
+public class SetShellIterCommand extends SetIterCommand {
+  private Option profileOpt;
+
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException,
+      TableNotFoundException, IOException, ShellCommandException {
+    return super.execute(fullCommand, cl, shellState);
+  }
+  
+  @Override
+  protected void setTableProperties(final CommandLine cl, final Shell shellState, final int priority, final Map<String,String> options, final String classname,
+      final String name) throws AccumuloException, AccumuloSecurityException, ShellCommandException, TableNotFoundException {
+    // instead of setting table properties, just put the options in a list to use at scan time
+    
+    String profile = cl.getOptionValue(profileOpt.getOpt());
+
+    // instead of setting table properties, just put the options in a list to use at scan time
+    Class<?> loadClass;
+    try {
+      loadClass = getClass().getClassLoader().loadClass(classname);
+    } catch (ClassNotFoundException e) {
+      throw new ShellCommandException(ErrorCode.INITIALIZATION_FAILURE, "Unable to load " + classname);
+    }
+    try {
+      loadClass.asSubclass(SortedKeyValueIterator.class);
+    } catch (ClassCastException ex) {
+      throw new ShellCommandException(ErrorCode.INITIALIZATION_FAILURE, "xUnable to load " + classname  + " as type "
+          + SortedKeyValueIterator.class.getName());
+    }
+    
+    for (Iterator<Entry<String,String>> i = options.entrySet().iterator(); i.hasNext();) {
+      final Entry<String,String> entry = i.next();
+      if (entry.getValue() == null || entry.getValue().isEmpty()) {
+        i.remove();
+      }
+    }
+
+    List<IteratorSetting> tableScanIterators = shellState.iteratorProfiles.get(profile);
+    if (tableScanIterators == null) {
+      tableScanIterators = new ArrayList<IteratorSetting>();
+      shellState.iteratorProfiles.put(profile, tableScanIterators);
+    }
+    final IteratorSetting setting = new IteratorSetting(priority, name, classname);
+    setting.addOptions(options);
+
+    Iterator<IteratorSetting> iter = tableScanIterators.iterator();
+    while (iter.hasNext()) {
+      if (iter.next().getName().equals(name)) {
+        iter.remove();
+      }
+    }
+
+    tableScanIterators.add(setting);
+  }
+  
+  @Override
+  public String description() {
+    return "adds an iterator to a profile for this shell session";
+  }
+  
+  @Override
+  public Options getOptions() {
+    // Remove the options that specify which type of iterator this is, since
+    // they are all scan iterators with this command.
+    final HashSet<OptionGroup> groups = new HashSet<OptionGroup>();
+    final Options parentOptions = super.getOptions();
+    final Options modifiedOptions = new Options();
+    for (Iterator<?> it = parentOptions.getOptions().iterator(); it.hasNext();) {
+      Option o = (Option) it.next();
+      if (!IteratorScope.majc.name().equals(o.getOpt()) && !IteratorScope.minc.name().equals(o.getOpt()) && !IteratorScope.scan.name().equals(o.getOpt())
+          && !"table".equals(o.getLongOpt())) {
+        modifiedOptions.addOption(o);
+        OptionGroup group = parentOptions.getOptionGroup(o);
+        if (group != null)
+          groups.add(group);
+      }
+    }
+    for (OptionGroup group : groups) {
+      modifiedOptions.addOptionGroup(group);
+    }
+    
+    profileOpt = new Option("pn", "profile", true, "iterator profile name");
+    profileOpt.setRequired(true);
+    profileOpt.setArgName("profile");
+    
+    modifiedOptions.addOption(profileOpt);
+
+    return modifiedOptions;
+  }
+  
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ShellPluginConfigurationCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ShellPluginConfigurationCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ShellPluginConfigurationCommand.java
new file mode 100644
index 0000000..d4c9739
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ShellPluginConfigurationCommand.java
@@ -0,0 +1,146 @@
+/*
+ * 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.accumulo.core.util.shell.commands;
+
+import java.util.Iterator;
+import java.util.Map.Entry;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.core.conf.Property;
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.core.util.shell.Shell.Command;
+import org.apache.accumulo.start.classloader.vfs.AccumuloVFSClassLoader;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.OptionGroup;
+import org.apache.commons.cli.Options;
+import org.apache.log4j.Logger;
+
+public abstract class ShellPluginConfigurationCommand extends Command {
+  private Option removePluginOption, pluginClassOption, listPluginOption;
+  
+  private String pluginType;
+  
+  private Property tableProp;
+  
+  private String classOpt;
+  
+  ShellPluginConfigurationCommand(final String typeName, final Property tableProp, final String classOpt) {
+    this.pluginType = typeName;
+    this.tableProp = tableProp;
+    this.classOpt = classOpt;
+  }
+
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    final String tableName = OptUtil.getTableOpt(cl, shellState);
+    
+    if (cl.hasOption(removePluginOption.getOpt())) {
+      // Remove the property
+      removePlugin(cl, shellState, tableName);
+      
+      shellState.getReader().println("Removed "+pluginType+" on " + tableName);
+    } else if (cl.hasOption(listPluginOption.getOpt())) {
+      // Get the options for this table
+      final Iterator<Entry<String,String>> iter = shellState.getConnector().tableOperations().getProperties(tableName).iterator();
+      
+      while (iter.hasNext()) {
+        Entry<String,String> ent = iter.next();
+        
+        // List all parameters with the property name
+        if (ent.getKey().startsWith(tableProp.toString())) {
+          shellState.getReader().println(ent.getKey() + ": " + ent.getValue());
+        }
+      }
+    } else {
+      // Set the plugin with the provided options
+      String className = cl.getOptionValue(pluginClassOption.getOpt());
+      
+      // Set the plugin property on the table
+      setPlugin(cl, shellState, tableName, className);
+    }
+    
+    return 0;
+  }
+
+  protected void setPlugin(final CommandLine cl, final Shell shellState, final String tableName, final String className) throws AccumuloException, AccumuloSecurityException {
+    shellState.getConnector().tableOperations().setProperty(tableName, tableProp.toString(), className);
+  }
+  
+  protected void removePlugin(final CommandLine cl, final Shell shellState, final String tableName) throws AccumuloException, AccumuloSecurityException {
+    shellState.getConnector().tableOperations().removeProperty(tableName, tableProp.toString());
+  }
+  
+  public static <T> Class<? extends T> getPluginClass(final String tableName, final Shell shellState, final Class<T> clazz, final Property pluginProp) {
+    Iterator<Entry<String,String>> props;
+    try {
+      props = shellState.getConnector().tableOperations().getProperties(tableName).iterator();
+    } catch (AccumuloException e) {
+      return null;
+    } catch (TableNotFoundException e) {
+      return null;
+    }
+    
+    while (props.hasNext()) {
+      final Entry<String,String> ent = props.next();
+      if (ent.getKey().equals(pluginProp.toString())) {
+        Class<? extends T> pluginClazz;
+        try {
+          pluginClazz = AccumuloVFSClassLoader.loadClass(ent.getValue(), clazz);
+        } catch (ClassNotFoundException e) {
+          Logger.getLogger(ShellPluginConfigurationCommand.class).warn("Class not found" + e.getMessage());
+          return null;
+        }
+        
+        return pluginClazz;
+      }
+    }
+    
+    return null;
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+    final OptionGroup actionGroup = new OptionGroup();
+    
+    pluginClassOption = new Option(classOpt, pluginType, true, "fully qualified name of the " + pluginType + " class to use");
+    pluginClassOption.setArgName("className");
+    
+    // Action to take: apply (default), remove, list
+    removePluginOption = new Option("r", "remove", false, "remove the current "+pluginType+"");
+    listPluginOption = new Option("l", "list", false, "display the current "+pluginType+"");
+    
+    actionGroup.addOption(pluginClassOption);
+    actionGroup.addOption(removePluginOption);
+    actionGroup.addOption(listPluginOption);
+    actionGroup.setRequired(true);
+    
+    o.addOptionGroup(actionGroup);
+    o.addOption(OptUtil.tableOpt("table to set the "+pluginType+" on"));
+    
+    return o;
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+  
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SleepCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SleepCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SleepCommand.java
new file mode 100644
index 0000000..ab69456
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SleepCommand.java
@@ -0,0 +1,46 @@
+/*
+ * 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.accumulo.core.util.shell.commands;
+
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.core.util.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+
+public class SleepCommand extends Command {
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    final double secs = Double.parseDouble(cl.getArgs()[0]);
+    Thread.sleep((long) (secs * 1000));
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "sleeps for the given number of seconds";
+  }
+  
+  @Override
+  public int numArgs() {
+    return 1;
+  }
+  
+  @Override
+  public String usage() {
+    return getName() + " <seconds>";
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SystemPermissionsCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SystemPermissionsCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SystemPermissionsCommand.java
new file mode 100644
index 0000000..3dec6fc
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SystemPermissionsCommand.java
@@ -0,0 +1,44 @@
+/*
+ * 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.accumulo.core.util.shell.commands;
+
+import java.io.IOException;
+
+import org.apache.accumulo.core.security.SystemPermission;
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.core.util.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+
+public class SystemPermissionsCommand extends Command {
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws IOException {
+    for (String p : SystemPermission.printableValues()) {
+      shellState.getReader().println(p);
+    }
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "displays a list of valid system permissions";
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/TableCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/TableCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/TableCommand.java
new file mode 100644
index 0000000..d77f6fb
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/TableCommand.java
@@ -0,0 +1,60 @@
+/*
+ * 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.accumulo.core.util.shell.commands;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.core.util.shell.Shell.Command;
+import org.apache.accumulo.core.util.shell.Token;
+import org.apache.commons.cli.CommandLine;
+
+public class TableCommand extends Command {
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException, TableNotFoundException {
+    final String tableName = cl.getArgs()[0];
+    if (!shellState.getConnector().tableOperations().exists(tableName)) {
+      throw new TableNotFoundException(null, tableName, null);
+    }
+    shellState.setTableName(tableName);
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "switches to the specified table";
+  }
+  
+  @Override
+  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> special) {
+    registerCompletionForTables(root, special);
+  }
+  
+  @Override
+  public String usage() {
+    return getName() + " <tableName>";
+  }
+  
+  @Override
+  public int numArgs() {
+    return 1;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/TableOperation.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/TableOperation.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/TableOperation.java
new file mode 100644
index 0000000..27946b8
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/TableOperation.java
@@ -0,0 +1,153 @@
+/*
+ * 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.accumulo.core.util.shell.commands;
+
+import java.util.Map;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import org.apache.accumulo.core.client.Instance;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.core.client.impl.Namespaces;
+import org.apache.accumulo.core.client.impl.Tables;
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.core.util.shell.Shell.Command;
+import org.apache.accumulo.core.util.shell.Token;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.OptionGroup;
+import org.apache.commons.cli.Options;
+
+public abstract class TableOperation extends Command {
+
+  protected Option optTablePattern, optTableName, optNamespace;
+  private boolean force = true;
+  private boolean useCommandLine = true;
+
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    // populate the tableSet set with the tables you want to operate on
+    final SortedSet<String> tableSet = new TreeSet<String>();
+    if (cl.hasOption(optTablePattern.getOpt())) {
+      for (String table : shellState.getConnector().tableOperations().list())
+        if (table.matches(cl.getOptionValue(optTablePattern.getOpt()))) {
+          tableSet.add(table);
+        }
+    } else if (cl.hasOption(optTableName.getOpt())) {
+      tableSet.add(cl.getOptionValue(optTableName.getOpt()));
+    } else if (cl.hasOption(optNamespace.getOpt())) {
+      Instance instance = shellState.getInstance();
+      String namespaceId = Namespaces.getNamespaceId(instance, cl.getOptionValue(optNamespace.getOpt()));
+      for (String tableId : Namespaces.getTableIds(instance, namespaceId)) {
+        tableSet.add(Tables.getTableName(instance, tableId));
+      }
+    } else if (useCommandLine && cl.getArgs().length > 0) {
+      for (String tableName : cl.getArgs()) {
+        tableSet.add(tableName);
+      }
+    } else {
+      shellState.checkTableState();
+      tableSet.add(shellState.getTableName());
+    }
+
+    if (tableSet.isEmpty())
+      Shell.log.warn("No tables found that match your criteria");
+
+    boolean more = true;
+    // flush the tables
+    for (String tableName : tableSet) {
+      if (!more) {
+        break;
+      }
+      if (!shellState.getConnector().tableOperations().exists(tableName)) {
+        throw new TableNotFoundException(null, tableName, null);
+      }
+      boolean operate = true;
+      if (!force) {
+        shellState.getReader().flush();
+        String line = shellState.getReader().readLine(getName() + " { " + tableName + " } (yes|no)? ");
+        more = line != null;
+        operate = line != null && (line.equalsIgnoreCase("y") || line.equalsIgnoreCase("yes"));
+      }
+      if (operate) {
+        doTableOp(shellState, tableName);
+      }
+    }
+
+    return 0;
+  }
+
+  protected abstract void doTableOp(Shell shellState, String tableName) throws Exception;
+
+  @Override
+  public String description() {
+    return "makes a best effort to flush tables from memory to disk";
+  }
+
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+
+    optTablePattern = new Option("p", "pattern", true, "regex pattern of table names to operate on");
+    optTablePattern.setArgName("pattern");
+
+    optTableName = new Option(Shell.tableOption, "table", true, "name of a table to operate on");
+    optTableName.setArgName("tableName");
+
+    optNamespace = new Option(Shell.namespaceOption, "namespace", true, "name of a namespace to operate on");
+    optNamespace.setArgName("namespace");
+
+    final OptionGroup opg = new OptionGroup();
+
+    opg.addOption(optTablePattern);
+    opg.addOption(optTableName);
+    opg.addOption(optNamespace);
+
+    o.addOptionGroup(opg);
+
+    return o;
+  }
+
+  @Override
+  public int numArgs() {
+    return useCommandLine ? Shell.NO_FIXED_ARG_LENGTH_CHECK : 0;
+  }
+
+  protected void force() {
+    force = true;
+  }
+
+  protected void noForce() {
+    force = false;
+  }
+
+  protected void disableUnflaggedTableOptions() {
+    useCommandLine = false;
+  }
+
+  @Override
+  public String usage() {
+    return getName() + " [<table>{ <table>}]";
+  }
+
+  @Override
+  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> special) {
+    if (useCommandLine)
+      registerCompletionForTables(root, special);
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/TablePermissionsCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/TablePermissionsCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/TablePermissionsCommand.java
new file mode 100644
index 0000000..1f92f21
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/TablePermissionsCommand.java
@@ -0,0 +1,44 @@
+/*
+ * 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.accumulo.core.util.shell.commands;
+
+import java.io.IOException;
+
+import org.apache.accumulo.core.security.TablePermission;
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.core.util.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+
+public class TablePermissionsCommand extends Command {
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws IOException {
+    for (String p : TablePermission.printableValues()) {
+      shellState.getReader().println(p);
+    }
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "displays a list of valid table permissions";
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/TablesCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/TablesCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/TablesCommand.java
new file mode 100644
index 0000000..a03a986
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/TablesCommand.java
@@ -0,0 +1,107 @@
+/*
+ * 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.accumulo.core.util.shell.commands;
+
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.TreeMap;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.NamespaceNotFoundException;
+import org.apache.accumulo.core.client.impl.Tables;
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.core.util.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+import org.apache.commons.collections.MapUtils;
+
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+import com.google.common.collect.Iterators;
+import com.google.common.collect.Maps;
+
+public class TablesCommand extends Command {
+  static final String NAME_AND_ID_FORMAT = "%-20s => %9s%n";
+
+  private Option tableIdOption;
+  private Option sortByTableIdOption;
+  private Option disablePaginationOpt;
+
+  @SuppressWarnings("unchecked")
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException, IOException,
+      NamespaceNotFoundException {
+
+    final String namespace = cl.hasOption(OptUtil.namespaceOpt().getOpt()) ? OptUtil.getNamespaceOpt(cl, shellState) : null;
+    Map<String,String> tables = shellState.getConnector().tableOperations().tableIdMap();
+
+    // filter only specified namespace
+    tables = Maps.filterKeys(tables, new Predicate<String>() {
+      @Override
+      public boolean apply(String tableName) {
+        return namespace == null || Tables.qualify(tableName).getFirst().equals(namespace);
+      }
+    });
+
+    final boolean sortByTableId = cl.hasOption(sortByTableIdOption.getOpt());
+    tables = new TreeMap<String,String>((sortByTableId ? MapUtils.invertMap(tables) : tables));
+
+    Iterator<String> it = Iterators.transform(tables.entrySet().iterator(), new Function<Entry<String,String>,String>() {
+      @Override
+      public String apply(Map.Entry<String,String> entry) {
+        String tableName = String.valueOf(sortByTableId ? entry.getValue() : entry.getKey());
+        String tableId = String.valueOf(sortByTableId ? entry.getKey() : entry.getValue());
+        if (namespace != null)
+          tableName = Tables.qualify(tableName).getSecond();
+        if (cl.hasOption(tableIdOption.getOpt()))
+          return String.format(NAME_AND_ID_FORMAT, tableName, tableId);
+        else
+          return tableName;
+      };
+    });
+
+    shellState.printLines(it, !cl.hasOption(disablePaginationOpt.getOpt()));
+    return 0;
+  }
+
+  @Override
+  public String description() {
+    return "displays a list of all existing tables";
+  }
+
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+    tableIdOption = new Option("l", "list-ids", false, "display internal table ids along with the table name");
+    o.addOption(tableIdOption);
+    sortByTableIdOption = new Option("s", "sort-ids", false, "with -l: sort output by table ids");
+    o.addOption(sortByTableIdOption);
+    disablePaginationOpt = new Option("np", "no-pagination", false, "disable pagination of output");
+    o.addOption(disablePaginationOpt);
+    o.addOption(OptUtil.namespaceOpt("name of namespace to list only its tables"));
+    return o;
+  }
+
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/TraceCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/TraceCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/TraceCommand.java
new file mode 100644
index 0000000..281a33a
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/TraceCommand.java
@@ -0,0 +1,101 @@
+/*
+ * 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.accumulo.core.util.shell.commands;
+
+import java.io.IOException;
+import java.util.Map;
+
+import org.apache.accumulo.trace.instrument.Trace;
+import org.apache.accumulo.core.client.Scanner;
+import org.apache.accumulo.core.conf.Property;
+import org.apache.accumulo.core.data.Range;
+import org.apache.accumulo.core.security.Authorizations;
+import org.apache.accumulo.core.trace.TraceDump;
+import org.apache.accumulo.core.trace.TraceDump.Printer;
+import org.apache.accumulo.core.util.BadArgumentException;
+import org.apache.accumulo.core.util.UtilWaitThread;
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.commons.cli.CommandLine;
+import org.apache.hadoop.io.Text;
+
+public class TraceCommand extends DebugCommand {
+  
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws IOException {
+    if (cl.getArgs().length == 1) {
+      if (cl.getArgs()[0].equalsIgnoreCase("on")) {
+        Trace.on("shell:" + shellState.getPrincipal());
+      } else if (cl.getArgs()[0].equalsIgnoreCase("off")) {
+        if (Trace.isTracing()) {
+          final long trace = Trace.currentTrace().traceId();
+          Trace.off();
+          StringBuffer sb = new StringBuffer();
+          int traceCount = 0;
+          for (int i = 0; i < 30; i++) {
+            sb = new StringBuffer();
+            try {
+              final Map<String,String> properties = shellState.getConnector().instanceOperations().getSystemConfiguration();
+              final String table = properties.get(Property.TRACE_TABLE.getKey());
+              final String user = shellState.getConnector().whoami();
+              final Authorizations auths = shellState.getConnector().securityOperations().getUserAuthorizations(user);
+              final Scanner scanner = shellState.getConnector().createScanner(table, auths);
+              scanner.setRange(new Range(new Text(Long.toHexString(trace))));
+              final StringBuffer finalSB = sb;
+              traceCount = TraceDump.printTrace(scanner, new Printer() {
+                @Override
+                public void print(final String line) {
+                  try {
+                    finalSB.append(line + "\n");
+                  } catch (Exception ex) {
+                    throw new RuntimeException(ex);
+                  }
+                }
+              });
+              if (traceCount > 0) {
+                shellState.getReader().print(sb.toString());
+                break;
+              }
+            } catch (Exception ex) {
+              shellState.printException(ex);
+            }
+            shellState.getReader().println("Waiting for trace information");
+            shellState.getReader().flush();
+            UtilWaitThread.sleep(500);
+          }
+          if (traceCount < 0) {
+            // display the trace even though there are unrooted spans
+            shellState.getReader().print(sb.toString());
+          }
+        } else {
+          shellState.getReader().println("Not tracing");
+        }
+      } else
+        throw new BadArgumentException("Argument must be 'on' or 'off'", fullCommand, fullCommand.indexOf(cl.getArgs()[0]));
+    } else if (cl.getArgs().length == 0) {
+      shellState.getReader().println(Trace.isTracing() ? "on" : "off");
+    } else {
+      shellState.printException(new IllegalArgumentException("Expected 0 or 1 argument. There were " + cl.getArgs().length + "."));
+      printHelp(shellState);
+      return 1;
+    }
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "turns trace logging on or off";
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/UserCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/UserCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/UserCommand.java
new file mode 100644
index 0000000..07da450
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/UserCommand.java
@@ -0,0 +1,71 @@
+/*
+ * 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.accumulo.core.util.shell.commands;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.security.tokens.PasswordToken;
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.core.util.shell.Shell.Command;
+import org.apache.accumulo.core.util.shell.Token;
+import org.apache.commons.cli.CommandLine;
+
+public class UserCommand extends Command {
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException, IOException {
+    // save old credentials and connection in case of failure
+    String user = cl.getArgs()[0];
+    byte[] pass;
+    
+    // We can't let the wrapping try around the execute method deal
+    // with the exceptions because we have to do something if one
+    // of these methods fails
+    final String p = shellState.readMaskedLine("Enter password for user " + user + ": ", '*');
+    if (p == null) {
+      shellState.getReader().println();
+      return 0;
+    } // user canceled
+    pass = p.getBytes(StandardCharsets.UTF_8);
+    shellState.updateUser(user, new PasswordToken(pass));
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "switches to the specified user";
+  }
+  
+  @Override
+  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> special) {
+    registerCompletionForUsers(root, special);
+  }
+  
+  @Override
+  public String usage() {
+    return getName() + " <username>";
+  }
+  
+  @Override
+  public int numArgs() {
+    return 1;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/UserPermissionsCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/UserPermissionsCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/UserPermissionsCommand.java
new file mode 100644
index 0000000..a126159
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/UserPermissionsCommand.java
@@ -0,0 +1,106 @@
+/*
+ * 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.accumulo.core.util.shell.commands;
+
+import java.io.IOException;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.security.NamespacePermission;
+import org.apache.accumulo.core.security.SystemPermission;
+import org.apache.accumulo.core.security.TablePermission;
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.core.util.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+
+public class UserPermissionsCommand extends Command {
+  private Option userOpt;
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException, IOException {
+    final String user = cl.getOptionValue(userOpt.getOpt(), shellState.getConnector().whoami());
+
+    String delim = "";
+    shellState.getReader().print("System permissions: ");
+    for (SystemPermission p : SystemPermission.values()) {
+      if (p != null && shellState.getConnector().securityOperations().hasSystemPermission(user, p)) {
+        shellState.getReader().print(delim + "System." + p.name());
+        delim = ", ";
+      }
+    }
+    shellState.getReader().println();
+
+    boolean runOnce = true;
+    for (String n : shellState.getConnector().namespaceOperations().list()) {
+      delim = "";
+      for (NamespacePermission p : NamespacePermission.values()) {
+        if (p != null && shellState.getConnector().securityOperations().hasNamespacePermission(user, n, p)) {
+          if (runOnce) {
+            shellState.getReader().print("\nNamespace permissions (" + n + "): ");
+            runOnce = false;
+          }
+          shellState.getReader().print(delim + "Namespace." + p.name());
+          delim = ", ";
+        }
+      }
+      runOnce = true;
+    }
+    shellState.getReader().println();
+
+    
+    runOnce = true;
+    for (String t : shellState.getConnector().tableOperations().list()) {
+      delim = "";
+      for (TablePermission p : TablePermission.values()) {
+        if (shellState.getConnector().securityOperations().hasTablePermission(user, t, p) && p != null) {
+          if (runOnce) {
+            shellState.getReader().print("\nTable permissions (" + t + "): ");
+            runOnce = false;
+          }
+          shellState.getReader().print(delim + "Table." + p.name());
+          delim = ", ";
+        }
+
+      }
+      runOnce = true;
+    }
+    shellState.getReader().println();
+
+    return 0;
+  }
+
+  @Override
+  public String description() {
+    return "displays a user's system, table, and namespace permissions";
+  }
+
+  @Override
+  public Options getOptions() {
+    Options o = new Options();
+    userOpt = new Option(Shell.userOption, "user", true, "user to operate on");
+    userOpt.setArgName("user");
+    o.addOption(userOpt);
+    return o;
+  }
+
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/UsersCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/UsersCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/UsersCommand.java
new file mode 100644
index 0000000..023c38b
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/UsersCommand.java
@@ -0,0 +1,45 @@
+/*
+ * 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.accumulo.core.util.shell.commands;
+
+import java.io.IOException;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.core.util.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+
+public class UsersCommand extends Command {
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException, IOException {
+    for (String user : shellState.getConnector().securityOperations().listLocalUsers()) {
+      shellState.getReader().println(user);
+    }
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "displays a list of existing users";
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/WhoAmICommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/WhoAmICommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/WhoAmICommand.java
new file mode 100644
index 0000000..e7bb29d
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/WhoAmICommand.java
@@ -0,0 +1,41 @@
+/*
+ * 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.accumulo.core.util.shell.commands;
+
+import java.io.IOException;
+
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.core.util.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+
+public class WhoAmICommand extends Command {
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws IOException {
+    shellState.getReader().println(shellState.getConnector().whoami());
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "reports the current user name";
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/test/java/org/apache/accumulo/core/util/format/DeleterFormatterTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/accumulo/core/util/format/DeleterFormatterTest.java b/core/src/test/java/org/apache/accumulo/core/util/format/DeleterFormatterTest.java
new file mode 100644
index 0000000..9223166
--- /dev/null
+++ b/core/src/test/java/org/apache/accumulo/core/util/format/DeleterFormatterTest.java
@@ -0,0 +1,176 @@
+/*
+ * 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.accumulo.core.util.format;
+
+import static org.easymock.EasyMock.anyObject;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.createNiceMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.expectLastCall;
+import static org.easymock.EasyMock.replay;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+import java.util.Collections;
+import java.util.Map;
+import java.util.TreeMap;
+
+import jline.UnsupportedTerminal;
+import jline.console.ConsoleReader;
+
+import org.apache.accumulo.core.client.BatchWriter;
+import org.apache.accumulo.core.client.MutationsRejectedException;
+import org.apache.accumulo.core.data.Key;
+import org.apache.accumulo.core.data.Mutation;
+import org.apache.accumulo.core.data.Value;
+import org.apache.accumulo.core.util.shell.Shell;
+import org.junit.Before;
+import org.junit.Test;
+
+public class DeleterFormatterTest {
+  DeleterFormatter formatter;
+  Map<Key,Value> data;
+  BatchWriter writer;
+  BatchWriter exceptionWriter;
+  Shell shellState;
+
+  ByteArrayOutputStream baos;
+  ConsoleReader reader;
+
+  SettableInputStream input;
+
+  class SettableInputStream extends InputStream {
+    ByteArrayInputStream bais;
+
+    @Override
+    public int read() throws IOException {
+      return bais.read();
+    }
+
+    public void set(String in) {
+      bais = new ByteArrayInputStream(in.getBytes(StandardCharsets.UTF_8));
+    }
+  };
+
+  @Before
+  public void setUp() throws IOException, MutationsRejectedException {
+    input = new SettableInputStream();
+    baos = new ByteArrayOutputStream();
+
+    MutationsRejectedException mre = createMock(MutationsRejectedException.class);
+
+    writer = createNiceMock(BatchWriter.class);
+    exceptionWriter = createNiceMock(BatchWriter.class);
+    exceptionWriter.close();
+    expectLastCall().andThrow(mre);
+    exceptionWriter.addMutation(anyObject(Mutation.class));
+    expectLastCall().andThrow(mre);
+
+    shellState = createNiceMock(Shell.class);
+
+    reader = new ConsoleReader(input, baos, new UnsupportedTerminal());
+    expect(shellState.getReader()).andReturn(reader).anyTimes();
+
+    replay(writer, exceptionWriter, shellState);
+
+    data = new TreeMap<Key,Value>();
+    data.put(new Key("r", "cf", "cq"), new Value("value".getBytes(StandardCharsets.UTF_8)));
+  }
+
+  @Test
+  public void testEmpty() {
+    formatter = new DeleterFormatter(writer, Collections.<Key,Value> emptyMap().entrySet(), true, shellState, true);
+    assertFalse(formatter.hasNext());
+  }
+
+  @Test
+  public void testSingle() throws IOException {
+    formatter = new DeleterFormatter(writer, data.entrySet(), true, shellState, true);
+
+    assertTrue(formatter.hasNext());
+    assertNull(formatter.next());
+
+    verify("[DELETED]", " r ", "cf", "cq", "value");
+  }
+
+  @Test
+  public void testNo() throws IOException {
+    input.set("no\n");
+    data.put(new Key("z"), new Value("v2".getBytes(StandardCharsets.UTF_8)));
+    formatter = new DeleterFormatter(writer, data.entrySet(), true, shellState, false);
+
+    assertTrue(formatter.hasNext());
+    assertNull(formatter.next());
+
+    verify("[SKIPPED]", " r ", "cf", "cq", "value");
+
+    assertTrue(formatter.hasNext());
+  }
+
+  @Test
+  public void testNoConfirmation() throws IOException {
+    input.set("");
+    data.put(new Key("z"), new Value("v2".getBytes(StandardCharsets.UTF_8)));
+    formatter = new DeleterFormatter(writer, data.entrySet(), true, shellState, false);
+
+    assertTrue(formatter.hasNext());
+    assertNull(formatter.next());
+
+    verify("[SKIPPED]", " r ", "cf", "cq", "value");
+
+    assertFalse(formatter.hasNext());
+  }
+
+  @Test
+  public void testYes() throws IOException {
+    input.set("y\nyes\n");
+    data.put(new Key("z"), new Value("v2".getBytes(StandardCharsets.UTF_8)));
+    formatter = new DeleterFormatter(writer, data.entrySet(), true, shellState, false);
+
+    assertTrue(formatter.hasNext());
+    assertNull(formatter.next());
+    verify("[DELETED]", " r ", "cf", "cq", "value");
+
+    assertTrue(formatter.hasNext());
+    assertNull(formatter.next());
+    verify("[DELETED]", " z ", "v2");
+  }
+
+  @Test
+  public void testMutationException() {
+    formatter = new DeleterFormatter(exceptionWriter, data.entrySet(), true, shellState, true);
+
+    assertTrue(formatter.hasNext());
+    assertNull(formatter.next());
+    assertFalse(formatter.hasNext());
+  }
+
+  private void verify(String... chunks) throws IOException {
+    reader.flush();
+
+    String output = baos.toString();
+    for (String chunk : chunks) {
+      assertTrue(output.contains(chunk));
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/test/java/org/apache/accumulo/core/util/shell/PasswordConverterTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/accumulo/core/util/shell/PasswordConverterTest.java b/core/src/test/java/org/apache/accumulo/core/util/shell/PasswordConverterTest.java
new file mode 100644
index 0000000..d1d24a6
--- /dev/null
+++ b/core/src/test/java/org/apache/accumulo/core/util/shell/PasswordConverterTest.java
@@ -0,0 +1,113 @@
+/*
+ * 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.accumulo.core.util.shell;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStreamWriter;
+import java.io.PipedInputStream;
+import java.io.PipedOutputStream;
+import java.util.Scanner;
+
+import org.apache.accumulo.core.util.shell.ShellOptionsJC.PasswordConverter;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import com.beust.jcommander.JCommander;
+import com.beust.jcommander.Parameter;
+import com.beust.jcommander.ParameterException;
+
+public class PasswordConverterTest {
+  
+  private class Password {
+    @Parameter(names = "--password", converter = PasswordConverter.class)
+    String password;
+  }
+  
+  private String[] argv;
+  private Password password;
+  private static InputStream realIn;
+  
+  @BeforeClass
+  public static void saveIn() {
+    realIn = System.in;
+  }
+  
+  @Before
+  public void setup() throws IOException {
+    argv = new String[] {"--password", ""};
+    password = new Password();
+    
+    PipedInputStream in = new PipedInputStream();
+    PipedOutputStream out = new PipedOutputStream(in);
+    OutputStreamWriter osw = new OutputStreamWriter(out);
+    osw.write("secret");
+    osw.close();
+    
+    System.setIn(in);
+  }
+  
+  @After
+  public void teardown() {
+    System.setIn(realIn);
+  }
+  
+  @Test
+  public void testPass() {
+    String expected = String.valueOf(Math.random());
+    argv[1] = "pass:" + expected;
+    new JCommander(password, argv);
+    assertEquals(expected, password.password);
+  }
+  
+  @Test
+  public void testEnv() {
+    String name = System.getenv().keySet().iterator().next();
+    argv[1] = "env:" + name;
+    new JCommander(password, argv);
+    assertEquals(System.getenv(name), password.password);
+  }
+  
+  @Test
+  public void testFile() throws FileNotFoundException {
+    argv[1] = "file:pom.xml";
+    Scanner scan = new Scanner(new File("pom.xml"));
+    String expected = scan.nextLine();
+    scan.close();
+    new JCommander(password, argv);
+    assertEquals(expected, password.password);
+  }
+  
+  @Test(expected=ParameterException.class)
+  public void testNoFile() throws FileNotFoundException {
+    argv[1] = "file:doesnotexist";
+    new JCommander(password, argv);
+  }
+
+  @Test
+  public void testStdin() {
+    argv[1] = "stdin";
+    new JCommander(password, argv);
+    assertEquals("stdin", password.password);
+  }
+}


[44/53] [abbrv] ACCUMULO-1879 Move shell into new package and module

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/CreateTableCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/CreateTableCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/CreateTableCommand.java
deleted file mode 100644
index bc5f1d1..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/CreateTableCommand.java
+++ /dev/null
@@ -1,203 +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.accumulo.core.util.shell.commands;
-
-import java.io.IOException;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.SortedSet;
-import java.util.TreeSet;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.TableExistsException;
-import org.apache.accumulo.core.client.TableNotFoundException;
-import org.apache.accumulo.core.client.admin.TimeType;
-import org.apache.accumulo.core.client.impl.Tables;
-import org.apache.accumulo.core.conf.Property;
-import org.apache.accumulo.core.iterators.IteratorUtil;
-import org.apache.accumulo.core.security.VisibilityConstraint;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.accumulo.core.util.shell.ShellUtil;
-import org.apache.accumulo.core.util.shell.Token;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.OptionGroup;
-import org.apache.commons.cli.Options;
-import org.apache.hadoop.io.Text;
-
-public class CreateTableCommand extends Command {
-  private Option createTableOptCopySplits;
-  private Option createTableOptCopyConfig;
-  private Option createTableOptSplit;
-  private Option createTableOptTimeLogical;
-  private Option createTableOptTimeMillis;
-  private Option createTableNoDefaultIters;
-  private Option createTableOptEVC;
-  private Option base64Opt;
-  private Option createTableOptFormatter;
-
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException,
-      TableExistsException, TableNotFoundException, IOException, ClassNotFoundException {
-
-    final String testTableName = cl.getArgs()[0];
-
-    if (!testTableName.matches(Tables.VALID_NAME_REGEX)) {
-      shellState.getReader().println("Only letters, numbers and underscores are allowed for use in table names.");
-      throw new IllegalArgumentException();
-    }
-
-    final String tableName = cl.getArgs()[0];
-    if (shellState.getConnector().tableOperations().exists(tableName)) {
-      throw new TableExistsException(null, tableName, null);
-    }
-    final SortedSet<Text> partitions = new TreeSet<Text>();
-    final boolean decode = cl.hasOption(base64Opt.getOpt());
-
-    if (cl.hasOption(createTableOptSplit.getOpt())) {
-      partitions.addAll(ShellUtil.scanFile(cl.getOptionValue(createTableOptSplit.getOpt()), decode));
-    } else if (cl.hasOption(createTableOptCopySplits.getOpt())) {
-      final String oldTable = cl.getOptionValue(createTableOptCopySplits.getOpt());
-      if (!shellState.getConnector().tableOperations().exists(oldTable)) {
-        throw new TableNotFoundException(null, oldTable, null);
-      }
-      partitions.addAll(shellState.getConnector().tableOperations().listSplits(oldTable));
-    }
-
-    if (cl.hasOption(createTableOptCopyConfig.getOpt())) {
-      final String oldTable = cl.getOptionValue(createTableOptCopyConfig.getOpt());
-      if (!shellState.getConnector().tableOperations().exists(oldTable)) {
-        throw new TableNotFoundException(null, oldTable, null);
-      }
-    }
-
-    TimeType timeType = TimeType.MILLIS;
-    if (cl.hasOption(createTableOptTimeLogical.getOpt())) {
-      timeType = TimeType.LOGICAL;
-    }
-
-    // create table
-    shellState.getConnector().tableOperations().create(tableName, true, timeType);
-    if (partitions.size() > 0) {
-      shellState.getConnector().tableOperations().addSplits(tableName, partitions);
-    }
-
-    shellState.setTableName(tableName); // switch shell to new table context
-
-    if (cl.hasOption(createTableNoDefaultIters.getOpt())) {
-      for (String key : IteratorUtil.generateInitialTableProperties(true).keySet()) {
-        shellState.getConnector().tableOperations().removeProperty(tableName, key);
-      }
-    }
-
-    // Copy options if flag was set
-    if (cl.hasOption(createTableOptCopyConfig.getOpt())) {
-      if (shellState.getConnector().tableOperations().exists(tableName)) {
-        final Iterable<Entry<String,String>> configuration = shellState.getConnector().tableOperations()
-            .getProperties(cl.getOptionValue(createTableOptCopyConfig.getOpt()));
-        for (Entry<String,String> entry : configuration) {
-          if (Property.isValidTablePropertyKey(entry.getKey())) {
-            shellState.getConnector().tableOperations().setProperty(tableName, entry.getKey(), entry.getValue());
-          }
-        }
-      }
-    }
-
-    if (cl.hasOption(createTableOptEVC.getOpt())) {
-      try {
-        shellState.getConnector().tableOperations().addConstraint(tableName, VisibilityConstraint.class.getName());
-      } catch (AccumuloException e) {
-        Shell.log.warn(e.getMessage() + " while setting visibility constraint, but table was created");
-      }
-    }
-
-    // Load custom formatter if set
-    if (cl.hasOption(createTableOptFormatter.getOpt())) {
-      final String formatterClass = cl.getOptionValue(createTableOptFormatter.getOpt());
-
-      shellState.getConnector().tableOperations().setProperty(tableName, Property.TABLE_FORMATTER_CLASS.toString(), formatterClass);
-    }
-
-    return 0;
-  }
-
-  @Override
-  public String description() {
-    return "creates a new table, with optional aggregators and optionally pre-split";
-  }
-
-  @Override
-  public String usage() {
-    return getName() + " <tableName>";
-  }
-
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-
-    createTableOptCopyConfig = new Option("cc", "copy-config", true, "table to copy configuration from");
-    createTableOptCopySplits = new Option("cs", "copy-splits", true, "table to copy current splits from");
-    createTableOptSplit = new Option("sf", "splits-file", true, "file with a newline-separated list of rows to split the table with");
-    createTableOptTimeLogical = new Option("tl", "time-logical", false, "use logical time");
-    createTableOptTimeMillis = new Option("tm", "time-millis", false, "use time in milliseconds");
-    createTableNoDefaultIters = new Option("ndi", "no-default-iterators", false, "prevent creation of the normal default iterator set");
-    createTableOptEVC = new Option("evc", "enable-visibility-constraint", false,
-        "prevent users from writing data they cannot read.  When enabling this, consider disabling bulk import and alter table.");
-    createTableOptFormatter = new Option("f", "formatter", true, "default formatter to set");
-
-    createTableOptCopyConfig.setArgName("table");
-    createTableOptCopySplits.setArgName("table");
-    createTableOptSplit.setArgName("filename");
-    createTableOptFormatter.setArgName("className");
-
-    // Splits and CopySplits are put in an optionsgroup to make them
-    // mutually exclusive
-    final OptionGroup splitOrCopySplit = new OptionGroup();
-    splitOrCopySplit.addOption(createTableOptSplit);
-    splitOrCopySplit.addOption(createTableOptCopySplits);
-
-    final OptionGroup timeGroup = new OptionGroup();
-    timeGroup.addOption(createTableOptTimeLogical);
-    timeGroup.addOption(createTableOptTimeMillis);
-
-    base64Opt = new Option("b64", "base64encoded", false, "decode encoded split points");
-    o.addOption(base64Opt);
-
-    o.addOptionGroup(splitOrCopySplit);
-    o.addOptionGroup(timeGroup);
-    o.addOption(createTableOptSplit);
-    o.addOption(createTableOptCopyConfig);
-    o.addOption(createTableNoDefaultIters);
-    o.addOption(createTableOptEVC);
-    o.addOption(createTableOptFormatter);
-
-    return o;
-  }
-
-  @Override
-  public int numArgs() {
-    return 1;
-  }
-
-  @Override
-  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> special) {
-    registerCompletionForNamespaces(root, special);
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/CreateUserCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/CreateUserCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/CreateUserCommand.java
deleted file mode 100644
index aa3d7b9..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/CreateUserCommand.java
+++ /dev/null
@@ -1,76 +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.accumulo.core.util.shell.commands;
-
-import java.io.IOException;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.TableExistsException;
-import org.apache.accumulo.core.client.TableNotFoundException;
-import org.apache.accumulo.core.client.security.tokens.PasswordToken;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Options;
-
-public class CreateUserCommand extends Command {
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, TableNotFoundException,
-      AccumuloSecurityException, TableExistsException, IOException {
-    final String user = cl.getArgs()[0];
-    
-    final String password = shellState.readMaskedLine("Enter new password for '" + user + "': ", '*');
-    if (password == null) {
-      shellState.getReader().println();
-      return 0;
-    } // user canceled
-    String passwordConfirm = shellState.readMaskedLine("Please confirm new password for '" + user + "': ", '*');
-    if (passwordConfirm == null) {
-      shellState.getReader().println();
-      return 0;
-    } // user canceled
-    
-    if (!password.equals(passwordConfirm)) {
-      throw new IllegalArgumentException("Passwords do not match");
-    }
-    shellState.getConnector().securityOperations().createLocalUser(user, new PasswordToken(password));
-    Shell.log.debug("Created user " + user);
-    return 0;
-  }
-  
-  @Override
-  public String usage() {
-    return getName() + " <username>";
-  }
-  
-  @Override
-  public String description() {
-    return "creates a new user";
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-    return o;
-  }
-  
-  @Override
-  public int numArgs() {
-    return 1;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DUCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DUCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DUCommand.java
deleted file mode 100644
index 660ec6c..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DUCommand.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.accumulo.core.util.shell.commands;
-
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.SortedSet;
-import java.util.TreeSet;
-
-import org.apache.accumulo.core.client.Instance;
-import org.apache.accumulo.core.client.NamespaceNotFoundException;
-import org.apache.accumulo.core.client.TableNotFoundException;
-import org.apache.accumulo.core.client.admin.DiskUsage;
-import org.apache.accumulo.core.client.impl.Namespaces;
-import org.apache.accumulo.core.util.NumUtil;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-
-public class DUCommand extends Command {
-
-  private Option optTablePattern, optHumanReadble, optNamespace;
-
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws IOException, TableNotFoundException,
-      NamespaceNotFoundException {
-
-    final SortedSet<String> tables = new TreeSet<String>(Arrays.asList(cl.getArgs()));
-
-    if (cl.hasOption(Shell.tableOption)) {
-      String tableName = cl.getOptionValue(Shell.tableOption);
-      if (!shellState.getConnector().tableOperations().exists(tableName)) {
-        throw new TableNotFoundException(tableName, tableName, "specified table that doesn't exist");
-      }
-      tables.add(tableName);
-    }
-
-    if (cl.hasOption(optNamespace.getOpt())) {
-      Instance instance = shellState.getInstance();
-      String namespaceId = Namespaces.getNamespaceId(instance, cl.getOptionValue(optNamespace.getOpt()));
-      tables.addAll(Namespaces.getTableNames(instance, namespaceId));
-    }
-
-    boolean prettyPrint = cl.hasOption(optHumanReadble.getOpt()) ? true : false;
-
-    // Add any patterns
-    if (cl.hasOption(optTablePattern.getOpt())) {
-      for (String table : shellState.getConnector().tableOperations().list()) {
-        if (table.matches(cl.getOptionValue(optTablePattern.getOpt()))) {
-          tables.add(table);
-        }
-      }
-    }
-
-    // If we didn't get any tables, and we have a table selected, add the current table
-    if (tables.isEmpty() && !shellState.getTableName().isEmpty()) {
-      tables.add(shellState.getTableName());
-    }
-
-    try {
-      String valueFormat = prettyPrint ? "%9s" : "%,24d";
-      for (DiskUsage usage : shellState.getConnector().tableOperations().getDiskUsage(tables)) {
-        Object value = prettyPrint ? NumUtil.bigNumberForSize(usage.getUsage()) : usage.getUsage();
-        shellState.getReader().println(String.format(valueFormat + " %s", value, usage.getTables()));
-      }
-    } catch (Exception ex) {
-      throw new RuntimeException(ex);
-    }
-    return 0;
-  }
-
-  @Override
-  public String description() {
-    return "prints how much space, in bytes, is used by files referenced by a table.  When multiple tables are specified it prints how much space, in bytes, is used by files shared between tables, if any.";
-  }
-
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-
-    optTablePattern = new Option("p", "pattern", true, "regex pattern of table names");
-    optTablePattern.setArgName("pattern");
-
-    optHumanReadble = new Option("h", "human-readable", false, "format large sizes to human readable units");
-    optHumanReadble.setArgName("human readable output");
-
-    optNamespace = new Option(Shell.namespaceOption, "namespace", true, "name of a namespace");
-    optNamespace.setArgName("namespace");
-
-    o.addOption(OptUtil.tableOpt("table to examine"));
-
-    o.addOption(optTablePattern);
-    o.addOption(optHumanReadble);
-    o.addOption(optNamespace);
-
-    return o;
-  }
-
-  @Override
-  public String usage() {
-    return getName() + " <table>{ <table>}";
-  }
-
-  @Override
-  public int numArgs() {
-    return Shell.NO_FIXED_ARG_LENGTH_CHECK;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DebugCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DebugCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DebugCommand.java
deleted file mode 100644
index 206b5901..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DebugCommand.java
+++ /dev/null
@@ -1,71 +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.accumulo.core.util.shell.commands;
-
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.accumulo.core.util.BadArgumentException;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.accumulo.core.util.shell.Token;
-import org.apache.commons.cli.CommandLine;
-
-public class DebugCommand extends Command {
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws IOException {
-    if (cl.getArgs().length == 1) {
-      if (cl.getArgs()[0].equalsIgnoreCase("on")) {
-        Shell.setDebugging(true);
-      } else if (cl.getArgs()[0].equalsIgnoreCase("off")) {
-        Shell.setDebugging(false);
-      } else {
-        throw new BadArgumentException("Argument must be 'on' or 'off'", fullCommand, fullCommand.indexOf(cl.getArgs()[0]));
-      }
-    } else if (cl.getArgs().length == 0) {
-      shellState.getReader().println(Shell.isDebuggingEnabled() ? "on" : "off");
-    } else {
-      shellState.printException(new IllegalArgumentException("Expected 0 or 1 argument. There were " + cl.getArgs().length + "."));
-      printHelp(shellState);
-      return 1;
-    }
-    return 0;
-  }
-  
-  @Override
-  public String description() {
-    return "turns debug logging on or off";
-  }
-  
-  @Override
-  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> special) {
-    final Token debug_command = new Token(getName());
-    debug_command.addSubcommand(Arrays.asList(new String[] {"on", "off"}));
-    root.addSubcommand(debug_command);
-  }
-  
-  @Override
-  public String usage() {
-    return getName() + " [ on | off ]";
-  }
-  
-  @Override
-  public int numArgs() {
-    return Shell.NO_FIXED_ARG_LENGTH_CHECK;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteCommand.java
deleted file mode 100644
index b409ccc..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteCommand.java
+++ /dev/null
@@ -1,112 +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.accumulo.core.util.shell.commands;
-
-import java.io.IOException;
-import java.util.concurrent.TimeUnit;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.BatchWriter;
-import org.apache.accumulo.core.client.BatchWriterConfig;
-import org.apache.accumulo.core.client.TableNotFoundException;
-import org.apache.accumulo.core.conf.AccumuloConfiguration;
-import org.apache.accumulo.core.data.Mutation;
-import org.apache.accumulo.core.security.ColumnVisibility;
-import org.apache.accumulo.core.tabletserver.thrift.ConstraintViolationException;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-import org.apache.hadoop.io.Text;
-
-public class DeleteCommand extends Command {
-  private Option deleteOptAuths, timestampOpt;
-  private Option timeoutOption;
-  
-  protected long getTimeout(final CommandLine cl) {
-    if (cl.hasOption(timeoutOption.getLongOpt())) {
-      return AccumuloConfiguration.getTimeInMillis(cl.getOptionValue(timeoutOption.getLongOpt()));
-    }
-    
-    return Long.MAX_VALUE;
-  }
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException,
-      TableNotFoundException, IOException, ConstraintViolationException {
-    shellState.checkTableState();
-    
-    final Mutation m = new Mutation(new Text(cl.getArgs()[0].getBytes(Shell.CHARSET)));
-    final Text colf = new Text(cl.getArgs()[1].getBytes(Shell.CHARSET));
-    final Text colq = new Text(cl.getArgs()[2].getBytes(Shell.CHARSET));
-    
-    if (cl.hasOption(deleteOptAuths.getOpt())) {
-      final ColumnVisibility le = new ColumnVisibility(cl.getOptionValue(deleteOptAuths.getOpt()));
-      if (cl.hasOption(timestampOpt.getOpt())) {
-        m.putDelete(colf, colq, le, Long.parseLong(cl.getOptionValue(timestampOpt.getOpt())));
-      } else {
-        m.putDelete(colf, colq, le);
-      }
-    } else if (cl.hasOption(timestampOpt.getOpt())) {
-      m.putDelete(colf, colq, Long.parseLong(cl.getOptionValue(timestampOpt.getOpt())));
-    } else {
-      m.putDelete(colf, colq);
-    }
-    final BatchWriter bw = shellState.getConnector().createBatchWriter(shellState.getTableName(),
-        new BatchWriterConfig().setMaxMemory(Math.max(m.estimatedMemoryUsed(), 1024)).setMaxWriteThreads(1).setTimeout(getTimeout(cl), TimeUnit.MILLISECONDS));
-    bw.addMutation(m);
-    bw.close();
-    return 0;
-  }
-  
-  @Override
-  public String description() {
-    return "deletes a record from a table";
-  }
-  
-  @Override
-  public String usage() {
-    return getName() + " <row> <colfamily> <colqualifier>";
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-    
-    deleteOptAuths = new Option("l", "visibility-label", true, "formatted visibility");
-    deleteOptAuths.setArgName("expression");
-    o.addOption(deleteOptAuths);
-    
-    timestampOpt = new Option("ts", "timestamp", true, "timestamp to use for deletion");
-    timestampOpt.setArgName("timestamp");
-    o.addOption(timestampOpt);
-    
-    timeoutOption = new Option(null, "timeout", true,
-        "time before insert should fail if no data is written. If no unit is given assumes seconds.  Units d,h,m,s,and ms are supported.  e.g. 30s or 100ms");
-    timeoutOption.setArgName("timeout");
-    o.addOption(timeoutOption);
-    
-    return o;
-  }
-  
-  @Override
-  public int numArgs() {
-    return 3;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteIterCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteIterCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteIterCommand.java
deleted file mode 100644
index c100325..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteIterCommand.java
+++ /dev/null
@@ -1,114 +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.accumulo.core.util.shell.commands;
-
-import java.util.EnumSet;
-
-import org.apache.accumulo.core.iterators.IteratorUtil.IteratorScope;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.OptionGroup;
-import org.apache.commons.cli.Options;
-
-public class DeleteIterCommand extends Command {
-  private Option allScopeOpt, mincScopeOpt, majcScopeOpt, scanScopeOpt, nameOpt;
-
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-
-    boolean tables = cl.hasOption(OptUtil.tableOpt().getOpt()) || !shellState.getTableName().isEmpty();
-    boolean namespaces = cl.hasOption(OptUtil.namespaceOpt().getOpt());
-
-    final String name = cl.getOptionValue(nameOpt.getOpt());
-
-    if (namespaces) {
-      if (!shellState.getConnector().namespaceOperations().listIterators(OptUtil.getNamespaceOpt(cl, shellState)).containsKey(name)) {
-        Shell.log.warn("no iterators found that match your criteria");
-        return 0;
-      }
-    } else if (tables) {
-      if (!shellState.getConnector().tableOperations().listIterators(OptUtil.getTableOpt(cl, shellState)).containsKey(name)) {
-        Shell.log.warn("no iterators found that match your criteria");
-        return 0;
-      }
-    } else {
-      throw new IllegalArgumentException("No table or namespace specified");
-    }
-
-    final EnumSet<IteratorScope> scopes = EnumSet.noneOf(IteratorScope.class);
-    if (cl.hasOption(allScopeOpt.getOpt()) || cl.hasOption(mincScopeOpt.getOpt())) {
-      scopes.add(IteratorScope.minc);
-    }
-    if (cl.hasOption(allScopeOpt.getOpt()) || cl.hasOption(majcScopeOpt.getOpt())) {
-      scopes.add(IteratorScope.majc);
-    }
-    if (cl.hasOption(allScopeOpt.getOpt()) || cl.hasOption(scanScopeOpt.getOpt())) {
-      scopes.add(IteratorScope.scan);
-    }
-    if (scopes.isEmpty()) {
-      throw new IllegalArgumentException("You must select at least one scope to configure");
-    }
-
-    if (namespaces) {
-      shellState.getConnector().namespaceOperations().removeIterator(OptUtil.getNamespaceOpt(cl, shellState), name, scopes);
-    } else if (tables) {
-      shellState.getConnector().tableOperations().removeIterator(OptUtil.getTableOpt(cl, shellState), name, scopes);
-    } else {
-      throw new IllegalArgumentException("No table or namespace specified");
-    }
-    return 0;
-  }
-
-  @Override
-  public String description() {
-    return "deletes a table-specific or namespace-specific iterator";
-  }
-
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-
-    nameOpt = new Option("n", "name", true, "iterator to delete");
-    nameOpt.setArgName("itername");
-    nameOpt.setRequired(true);
-
-    allScopeOpt = new Option("all", "all-scopes", false, "remove from all scopes");
-    mincScopeOpt = new Option(IteratorScope.minc.name(), "minor-compaction", false, "remove from minor compaction scope");
-    majcScopeOpt = new Option(IteratorScope.majc.name(), "major-compaction", false, "remove from major compaction scope");
-    scanScopeOpt = new Option(IteratorScope.scan.name(), "scan-time", false, "remove from scan scope");
-
-    OptionGroup grp = new OptionGroup();
-    grp.addOption(OptUtil.tableOpt("table to delete the iterator from"));
-    grp.addOption(OptUtil.namespaceOpt("namespace to delete the iterator from"));
-    o.addOptionGroup(grp);
-    o.addOption(nameOpt);
-
-    o.addOption(allScopeOpt);
-    o.addOption(mincScopeOpt);
-    o.addOption(majcScopeOpt);
-    o.addOption(scanScopeOpt);
-
-    return o;
-  }
-
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteManyCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteManyCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteManyCommand.java
deleted file mode 100644
index 7518bf9..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteManyCommand.java
+++ /dev/null
@@ -1,82 +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.accumulo.core.util.shell.commands;
-
-import java.util.concurrent.TimeUnit;
-
-import org.apache.accumulo.core.client.BatchWriter;
-import org.apache.accumulo.core.client.BatchWriterConfig;
-import org.apache.accumulo.core.client.IteratorSetting;
-import org.apache.accumulo.core.client.Scanner;
-import org.apache.accumulo.core.iterators.SortedKeyIterator;
-import org.apache.accumulo.core.security.Authorizations;
-import org.apache.accumulo.core.util.format.DeleterFormatter;
-import org.apache.accumulo.core.util.interpret.ScanInterpreter;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-
-public class DeleteManyCommand extends ScanCommand {
-  private Option forceOpt;
-  
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    final String tableName = OptUtil.getTableOpt(cl, shellState);
-    
-    final ScanInterpreter interpeter = getInterpreter(cl, tableName, shellState);
-
-    // handle first argument, if present, the authorizations list to
-    // scan with
-    final Authorizations auths = getAuths(cl, shellState);
-    final Scanner scanner = shellState.getConnector().createScanner(tableName, auths);
-    
-    scanner.addScanIterator(new IteratorSetting(Integer.MAX_VALUE, "NOVALUE", SortedKeyIterator.class));
-    
-    // handle session-specific scan iterators
-    addScanIterators(shellState, cl, scanner, tableName);
-    
-    // handle remaining optional arguments
-    scanner.setRange(getRange(cl, interpeter));
-    
-    scanner.setTimeout(getTimeout(cl), TimeUnit.MILLISECONDS);
-
-    // handle columns
-    fetchColumns(cl, scanner, interpeter);
-    
-    // output / delete the records
-    final BatchWriter writer = shellState.getConnector()
-        .createBatchWriter(tableName, new BatchWriterConfig().setTimeout(getTimeout(cl), TimeUnit.MILLISECONDS));
-    shellState.printLines(new DeleterFormatter(writer, scanner, cl.hasOption(timestampOpt.getOpt()), shellState, cl.hasOption(forceOpt.getOpt())), false);
-    
-    return 0;
-  }
-  
-  @Override
-  public String description() {
-    return "scans a table and deletes the resulting records";
-  }
-  
-  @Override
-  public Options getOptions() {
-    forceOpt = new Option("f", "force", false, "force deletion without prompting");
-    final Options opts = super.getOptions();
-    opts.addOption(forceOpt);
-    opts.addOption(OptUtil.tableOpt("table to delete entries from"));
-    return opts;
-  }
-  
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteNamespaceCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteNamespaceCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteNamespaceCommand.java
deleted file mode 100644
index 01d7fc0..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteNamespaceCommand.java
+++ /dev/null
@@ -1,100 +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.accumulo.core.util.shell.commands;
-
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.accumulo.core.client.NamespaceNotFoundException;
-import org.apache.accumulo.core.client.impl.Namespaces;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.accumulo.core.util.shell.Token;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-
-public class DeleteNamespaceCommand extends Command {
-  private Option forceOpt;
-
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    boolean force = false;
-    boolean operate = true;
-    if (cl.hasOption(forceOpt.getOpt())) {
-      force = true;
-    }
-    String namespace = cl.getArgs()[0];
-
-    if (!force) {
-      shellState.getReader().flush();
-      String line = shellState.getReader().readLine(getName() + " { " + namespace + " } (yes|no)? ");
-      operate = line != null && (line.equalsIgnoreCase("y") || line.equalsIgnoreCase("yes"));
-    }
-    if (operate) {
-      doTableOp(shellState, namespace, force);
-    }
-    return 0;
-  }
-
-  @Override
-  public String description() {
-    return "deletes a namespace";
-  }
-
-  protected void doTableOp(final Shell shellState, final String namespace, boolean force) throws Exception {
-    boolean resetContext = false;
-    String currentTable = shellState.getTableName();
-    if (!Namespaces.getNameToIdMap(shellState.getInstance()).containsKey(namespace)) {
-      throw new NamespaceNotFoundException(null, namespace, null);
-    }
-
-    String namespaceId = Namespaces.getNamespaceId(shellState.getInstance(), namespace);
-    List<String> tables = Namespaces.getTableNames(shellState.getInstance(), namespaceId);
-    resetContext = tables.contains(currentTable);
-
-    if (force)
-      for (String table : shellState.getConnector().tableOperations().list())
-        if (table.startsWith(namespace + "."))
-          shellState.getConnector().tableOperations().delete(table);
-
-    shellState.getConnector().namespaceOperations().delete(namespace);
-    if (resetContext) {
-      shellState.setTableName("");
-    }
-  }
-
-  @Override
-  public Options getOptions() {
-    forceOpt = new Option("f", "force", false, "force deletion without prompting");
-    final Options opts = super.getOptions();
-
-    opts.addOption(forceOpt);
-    return opts;
-  }
-
-  @Override
-  public int numArgs() {
-    return 1;
-  }
-
-  @Override
-  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> special) {
-    registerCompletionForNamespaces(root, special);
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteRowsCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteRowsCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteRowsCommand.java
deleted file mode 100644
index 1414b4d..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteRowsCommand.java
+++ /dev/null
@@ -1,65 +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.accumulo.core.util.shell.commands;
-
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-import org.apache.hadoop.io.Text;
-
-public class DeleteRowsCommand extends Command {
-  private Option forceOpt;
-  private Option startRowOptExclusive;
- 
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    final String tableName = OptUtil.getTableOpt(cl, shellState);
-    final Text startRow = OptUtil.getStartRow(cl);
-    final Text endRow = OptUtil.getEndRow(cl);
-    if (!cl.hasOption(forceOpt.getOpt()) && (startRow == null || endRow == null)) {
-      shellState.getReader().println("Not deleting unbounded range. Specify both ends, or use --force");
-      return 1;
-    }
-    shellState.getConnector().tableOperations().deleteRows(tableName, startRow, endRow);
-    return 0;
-  }
-  
-  @Override
-  public String description() {
-    return "deletes a range of rows in a table.  Note that rows matching the start row ARE NOT deleted, but rows matching the end row ARE deleted.";
-  }
-  
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-    forceOpt = new Option("f", "force", false, "delete data even if start or end are not specified");
-    startRowOptExclusive = new Option(OptUtil.START_ROW_OPT, "begin-row", true, "begin row (exclusive)");
-    startRowOptExclusive.setArgName("begin-row");
-    o.addOption(startRowOptExclusive);
-    o.addOption(OptUtil.endRowOpt());
-    o.addOption(OptUtil.tableOpt("table to delete a row range from"));
-    o.addOption(forceOpt);
-    return o;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteScanIterCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteScanIterCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteScanIterCommand.java
deleted file mode 100644
index 9b8699b..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteScanIterCommand.java
+++ /dev/null
@@ -1,102 +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.accumulo.core.util.shell.commands;
-
-import java.util.Iterator;
-import java.util.List;
-
-import org.apache.accumulo.core.client.IteratorSetting;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.OptionGroup;
-import org.apache.commons.cli.Options;
-
-public class DeleteScanIterCommand extends Command {
-  private Option nameOpt, allOpt;
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    final String tableName = OptUtil.getTableOpt(cl, shellState);
-    
-    if (cl.hasOption(allOpt.getOpt())) {
-      final List<IteratorSetting> tableScanIterators = shellState.scanIteratorOptions.remove(tableName);
-      if (tableScanIterators == null) {
-        Shell.log.info("No scan iterators set on table " + tableName);
-      } else {
-        Shell.log.info("Removed the following scan iterators from table " + tableName + ":" + tableScanIterators);
-      }
-    } else if (cl.hasOption(nameOpt.getOpt())) {
-      final String name = cl.getOptionValue(nameOpt.getOpt());
-      final List<IteratorSetting> tableScanIterators = shellState.scanIteratorOptions.get(tableName);
-      if (tableScanIterators != null) {
-        boolean found = false;
-        for (Iterator<IteratorSetting> iter = tableScanIterators.iterator(); iter.hasNext();) {
-          if (iter.next().getName().equals(name)) {
-            iter.remove();
-            found = true;
-            break;
-          }
-        }
-        if (!found) {
-          Shell.log.info("No iterator named " + name + " found for table " + tableName);
-        } else {
-          Shell.log.info("Removed scan iterator " + name + " from table " + tableName + " (" + shellState.scanIteratorOptions.get(tableName).size() + " left)");
-          if (shellState.scanIteratorOptions.get(tableName).size() == 0) {
-            shellState.scanIteratorOptions.remove(tableName);
-          }
-        }
-      } else {
-        Shell.log.info("No iterator named " + name + " found for table " + tableName);
-      }
-    }
-    
-    return 0;
-  }
-  
-  @Override
-  public String description() {
-    return "deletes a table-specific scan iterator so it is no longer used during this shell session";
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-    
-    OptionGroup nameGroup = new OptionGroup();
-    
-    nameOpt = new Option("n", "name", true, "iterator to delete");
-    nameOpt.setArgName("itername");
-    
-    allOpt = new Option("a", "all", false, "delete all scan iterators");
-    allOpt.setArgName("all");
-    
-    nameGroup.addOption(nameOpt);
-    nameGroup.addOption(allOpt);
-    nameGroup.setRequired(true);
-    o.addOptionGroup(nameGroup);
-    o.addOption(OptUtil.tableOpt("table to delete scan iterators from"));
-    
-    return o;
-  }
-  
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteShellIterCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteShellIterCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteShellIterCommand.java
deleted file mode 100644
index 89060c1..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteShellIterCommand.java
+++ /dev/null
@@ -1,100 +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.accumulo.core.util.shell.commands;
-
-import java.util.Iterator;
-import java.util.List;
-
-import org.apache.accumulo.core.client.IteratorSetting;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.OptionGroup;
-import org.apache.commons.cli.Options;
-
-public class DeleteShellIterCommand extends Command {
-  private Option nameOpt, allOpt, profileOpt;
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-
-    String profile = cl.getOptionValue(profileOpt.getOpt());
-    if (shellState.iteratorProfiles.containsKey(profile)) {
-      if (cl.hasOption(allOpt.getOpt())) {
-        shellState.iteratorProfiles.remove(profile);
-        Shell.log.info("Removed profile " + profile);
-      } else {
-        List<IteratorSetting> iterSettings = shellState.iteratorProfiles.get(profile);
-        String name = cl.getOptionValue(nameOpt.getOpt());
-        boolean found = false;
-        for (Iterator<IteratorSetting> iter = iterSettings.iterator(); iter.hasNext();) {
-          if (iter.next().getName().equals(name)) {
-            iter.remove();
-            found = true;
-            break;
-          }
-        }
-        if (!found) {
-          Shell.log.info("No iterator named " + name + " found");
-        } else {
-          Shell.log.info("Removed iterator " + name + " from profile " + profile + " (" + iterSettings.size() + " left)");
-        }
-      }
-      
-    } else {
-      Shell.log.info("No profile named " + profile);
-    }
-    
-    return 0;
-  }
-  
-  @Override
-  public String description() {
-    return "deletes iterators profiles configured in this shell session";
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-    
-    OptionGroup nameGroup = new OptionGroup();
-    
-    nameOpt = new Option("n", "name", true, "iterator to delete");
-    nameOpt.setArgName("itername");
-    
-    allOpt = new Option("a", "all", false, "delete all scan iterators");
-    allOpt.setArgName("all");
-    
-    nameGroup.addOption(nameOpt);
-    nameGroup.addOption(allOpt);
-    nameGroup.setRequired(true);
-    o.addOptionGroup(nameGroup);
-    
-    profileOpt = new Option("pn", "profile", true, "iterator profile name");
-    profileOpt.setRequired(true);
-    profileOpt.setArgName("profile");
-    o.addOption(profileOpt);
-
-    return o;
-  }
-  
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteTableCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteTableCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteTableCommand.java
deleted file mode 100644
index a5aa32a..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteTableCommand.java
+++ /dev/null
@@ -1,60 +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.accumulo.core.util.shell.commands;
-
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-
-public class DeleteTableCommand extends TableOperation {
-  private Option forceOpt;
-
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    if (cl.hasOption(forceOpt.getOpt())) {
-      super.force();
-    } else {
-      super.noForce();
-    }
-    return super.execute(fullCommand, cl, shellState);
-  }
-
-  @Override
-  public String description() {
-    return "deletes a table";
-  }
-
-  @Override
-  protected void doTableOp(final Shell shellState, final String tableName) throws Exception {
-    shellState.getConnector().tableOperations().delete(tableName);
-    shellState.getReader().println("Table: [" + tableName + "] has been deleted.");
-
-    if (shellState.getTableName().equals(tableName)) {
-      shellState.setTableName("");
-    }
-  }
-
-  @Override
-  public Options getOptions() {
-    forceOpt = new Option("f", "force", false, "force deletion without prompting");
-    final Options opts = super.getOptions();
-
-    opts.addOption(forceOpt);
-    return opts;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteUserCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteUserCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteUserCommand.java
deleted file mode 100644
index 4bc563e..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteUserCommand.java
+++ /dev/null
@@ -1,19 +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.accumulo.core.util.shell.commands;
-
-public class DeleteUserCommand extends DropUserCommand {}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DropTableCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DropTableCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DropTableCommand.java
deleted file mode 100644
index 3120d6b..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DropTableCommand.java
+++ /dev/null
@@ -1,19 +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.accumulo.core.util.shell.commands;
-
-public class DropTableCommand extends DeleteTableCommand {}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DropUserCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DropUserCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DropUserCommand.java
deleted file mode 100644
index 5aa0fb6..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DropUserCommand.java
+++ /dev/null
@@ -1,61 +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.accumulo.core.util.shell.commands;
-
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.util.BadArgumentException;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.accumulo.core.util.shell.Token;
-import org.apache.commons.cli.CommandLine;
-
-public class DropUserCommand extends Command {
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException {
-    final String user = cl.getArgs()[0];
-    if (shellState.getConnector().whoami().equals(user)) {
-      throw new BadArgumentException("You cannot delete yourself", fullCommand, fullCommand.indexOf(user));
-    }
-    shellState.getConnector().securityOperations().dropLocalUser(user);
-    Shell.log.debug("Deleted user " + user);
-    return 0;
-  }
-  
-  @Override
-  public String description() {
-    return "deletes a user";
-  }
-  
-  @Override
-  public String usage() {
-    return getName() + " <username>";
-  }
-  
-  @Override
-  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> completionSet) {
-    registerCompletionForUsers(root, completionSet);
-  }
-  
-  @Override
-  public int numArgs() {
-    return 1;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/EGrepCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/EGrepCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/EGrepCommand.java
deleted file mode 100644
index d63991a..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/EGrepCommand.java
+++ /dev/null
@@ -1,59 +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.accumulo.core.util.shell.commands;
-
-import java.io.IOException;
-
-import org.apache.accumulo.core.client.BatchScanner;
-import org.apache.accumulo.core.client.IteratorSetting;
-import org.apache.accumulo.core.iterators.user.RegExFilter;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-
-public class EGrepCommand extends GrepCommand {
-  
-  private Option matchSubstringOption;
-  
-  @Override
-  protected void setUpIterator(final int prio, final String name, final String term, final BatchScanner scanner, CommandLine cl) throws IOException {
-    if (prio < 0) {
-      throw new IllegalArgumentException("Priority < 0 " + prio);
-    }
-    final IteratorSetting si = new IteratorSetting(prio, name, RegExFilter.class);
-    RegExFilter.setRegexs(si, term, term, term, term, true, cl.hasOption(matchSubstringOption.getOpt()));
-    scanner.addScanIterator(si);
-  }
-  
-  @Override
-  public String description() {
-    return "searches each row, column family, column qualifier and value, in parallel, on the server side (using a java Matcher, so put .* before and after your term if you're not matching the whole element)";
-  }
-  
-  @Override
-  public String usage() {
-    return getName() + " <regex>{ <regex>}";
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options opts = super.getOptions();
-    matchSubstringOption = new Option("g", "global", false, "forces the use of the find() expression matcher, causing substring matches to return true");
-    opts.addOption(matchSubstringOption);
-    return opts;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ExecfileCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ExecfileCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ExecfileCommand.java
deleted file mode 100644
index f4a2632..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ExecfileCommand.java
+++ /dev/null
@@ -1,67 +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.accumulo.core.util.shell.commands;
-
-import java.io.File;
-import java.nio.charset.StandardCharsets;
-import java.util.Scanner;
-
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-
-public class ExecfileCommand extends Command {
-  private Option verboseOption;
-  
-  @Override
-  public String description() {
-    return "specifies a file containing accumulo commands to execute";
-  }
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    Scanner scanner = new Scanner(new File(cl.getArgs()[0]), StandardCharsets.UTF_8.name());
-    try {
-      while (scanner.hasNextLine()) {
-        shellState.execCommand(scanner.nextLine(), true, cl.hasOption(verboseOption.getOpt()));
-      }
-    } finally {
-      scanner.close();
-    }
-    return 0;
-  }
-  
-  @Override
-  public String usage() {
-    return getName() + " <fileName>";
-  }
-  
-  @Override
-  public int numArgs() {
-    return 1;
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options opts = new Options();
-    verboseOption = new Option("v", "verbose", false, "display command prompt as commands are executed");
-    opts.addOption(verboseOption);
-    return opts;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ExitCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ExitCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ExitCommand.java
deleted file mode 100644
index c78b020..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ExitCommand.java
+++ /dev/null
@@ -1,39 +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.accumulo.core.util.shell.commands;
-
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-
-public class ExitCommand extends Command {
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) {
-    shellState.setExit(true);
-    return 0;
-  }
-  
-  @Override
-  public String description() {
-    return "exits the shell";
-  }
-  
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ExportTableCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ExportTableCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ExportTableCommand.java
deleted file mode 100644
index 5fd5abb..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ExportTableCommand.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.accumulo.core.util.shell.commands;
-
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.TableExistsException;
-import org.apache.accumulo.core.client.TableNotFoundException;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.accumulo.core.util.shell.Token;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-
-public class ExportTableCommand extends Command {
-  
-  private Option tableOpt;
-
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException, TableNotFoundException,
-      TableExistsException {
-    
-    final String tableName = OptUtil.getTableOpt(cl, shellState);
-
-    shellState.getConnector().tableOperations().exportTable(tableName, cl.getArgs()[0]);
-    return 0;
-  }
-  
-  @Override
-  public String usage() {
-    return getName() + " <export dir>";
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-    
-    tableOpt = new Option(Shell.tableOption, "table", true, "table to export");
-    
-    tableOpt.setArgName("table");
-    
-    o.addOption(tableOpt);
-
-    return o;
-  }
-  
-  @Override
-  public String description() {
-    return "exports a table";
-  }
-  
-  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> completionSet) {
-    registerCompletionForTables(root, completionSet);
-  }
-  
-  @Override
-  public int numArgs() {
-    return 1;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ExtensionCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ExtensionCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ExtensionCommand.java
deleted file mode 100644
index ab29d19..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ExtensionCommand.java
+++ /dev/null
@@ -1,102 +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.accumulo.core.util.shell.commands;
-
-import java.util.HashSet;
-import java.util.ServiceLoader;
-import java.util.Set;
-import java.util.TreeSet;
-
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.accumulo.core.util.shell.ShellExtension;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-
-public class ExtensionCommand extends Command {
-  
-  protected Option enable, disable, list;
-  
-  private static ServiceLoader<ShellExtension> extensions = null;
-  
-  private Set<String> loadedHeaders = new HashSet<String>();
-  private Set<String> loadedCommands = new HashSet<String>();
-  private Set<String> loadedExtensions = new TreeSet<String>();
-  
-  public int execute(String fullCommand, CommandLine cl, Shell shellState) throws Exception {
-    if (cl.hasOption(enable.getOpt())) {
-      extensions = ServiceLoader.load(ShellExtension.class);
-      for (ShellExtension se : extensions) {
-        
-        loadedExtensions.add(se.getExtensionName());
-        String header = "-- " + se.getExtensionName() + " Extension Commands ---------";
-        loadedHeaders.add(header);
-        shellState.commandGrouping.put(header, se.getCommands());
-        
-        for (Command cmd : se.getCommands()) {
-          String name = se.getExtensionName() + "::" + cmd.getName();
-          loadedCommands.add(name);
-          shellState.commandFactory.put(name, cmd);
-        }
-      }
-    } else if (cl.hasOption(disable.getOpt())) {
-      //Remove the headers
-      for (String header : loadedHeaders) {
-        shellState.commandGrouping.remove(header);
-      }
-      //remove the commands
-      for (String name : loadedCommands) {
-        shellState.commandFactory.remove(name);
-      }
-      //Reset state
-      loadedExtensions.clear();
-      extensions.reload();
-    } else if (cl.hasOption(list.getOpt())) {
-      shellState.printLines(loadedExtensions.iterator(), true);
-    } else {
-      printHelp(shellState);
-    }
-    return 0;
-  }
-  
-  public String description() {
-    return "Enable, disable, or list shell extensions";
-  }
-  
-  public int numArgs() {
-    return 0;
-  }
-  
-  @Override
-  public String getName() {
-    return "extensions";
-  }
-
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-    enable = new Option("e", "enable", false, "enable shell extensions");
-    disable = new Option("d", "disable", false, "disable shell extensions");
-    list = new Option("l", "list", false, "list shell extensions");
-    o.addOption(enable);
-    o.addOption(disable);
-    o.addOption(list);
-    return o;
-  }
-    
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/FateCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/FateCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/FateCommand.java
deleted file mode 100644
index 0196baf..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/FateCommand.java
+++ /dev/null
@@ -1,180 +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.accumulo.core.util.shell.commands;
-
-import java.io.IOException;
-import java.util.Collections;
-import java.util.EnumSet;
-import java.util.Formatter;
-import java.util.HashSet;
-import java.util.Set;
-
-import org.apache.accumulo.core.Constants;
-import org.apache.accumulo.core.client.Instance;
-import org.apache.accumulo.core.conf.AccumuloConfiguration;
-import org.apache.accumulo.core.conf.Property;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.accumulo.core.zookeeper.ZooUtil;
-import org.apache.accumulo.fate.AdminUtil;
-import org.apache.accumulo.fate.ReadOnlyTStore.TStatus;
-import org.apache.accumulo.fate.ZooStore;
-import org.apache.accumulo.fate.zookeeper.IZooReaderWriter;
-import org.apache.accumulo.fate.zookeeper.ZooReaderWriter;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-import org.apache.commons.cli.ParseException;
-import org.apache.zookeeper.KeeperException;
-
-/**
- * Manage FATE transactions
- * 
- */
-public class FateCommand extends Command {
-  
-  private static final String SCHEME = "digest";
-  
-  private static final String USER = "accumulo";
-  
-  private Option secretOption;
-  private Option statusOption;
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws ParseException, KeeperException, InterruptedException,
-      IOException {
-    Instance instance = shellState.getInstance();
-    String[] args = cl.getArgs();
-    if (args.length <= 0) {
-      throw new ParseException("Must provide a command to execute");
-    }
-    String cmd = args[0];
-    boolean failedCommand = false;
-    
-    AdminUtil<FateCommand> admin = new AdminUtil<FateCommand>(false);
-    
-    String path = ZooUtil.getRoot(instance) + Constants.ZFATE;
-    String masterPath = ZooUtil.getRoot(instance) + Constants.ZMASTER_LOCK;
-    IZooReaderWriter zk = getZooReaderWriter(shellState.getInstance(), cl.getOptionValue(secretOption.getOpt()));
-    ZooStore<FateCommand> zs = new ZooStore<FateCommand>(path, zk);
-    
-    if ("fail".equals(cmd)) {
-      if (args.length <= 1) {
-        throw new ParseException("Must provide transaction ID");
-      }
-      for (int i = 1; i < args.length; i++) {
-        if (!admin.prepFail(zs, zk, masterPath, args[i])) {
-          System.out.printf("Could not fail transaction: %s%n", args[i]);
-          failedCommand = true;
-        }
-      }
-    } else if ("delete".equals(cmd)) {
-      if (args.length <= 1) {
-        throw new ParseException("Must provide transaction ID");
-      }
-      for (int i = 1; i < args.length; i++) {
-        if (admin.prepDelete(zs, zk, masterPath, args[i])) {
-          admin.deleteLocks(zs, zk, ZooUtil.getRoot(instance) + Constants.ZTABLE_LOCKS, args[i]);
-        } else {
-          System.out.printf("Could not delete transaction: %s%n", args[i]);
-          failedCommand = true;
-        }
-      }
-    } else if ("list".equals(cmd) || "print".equals(cmd)) {
-      // Parse transaction ID filters for print display
-      Set<Long> filterTxid = null;
-      if (args.length >= 2) {
-        filterTxid = new HashSet<Long>(args.length);
-        for (int i = 1; i < args.length; i++) {
-          try {
-            Long val = Long.parseLong(args[i], 16);
-            filterTxid.add(val);
-          } catch (NumberFormatException nfe) {
-            // Failed to parse, will exit instead of displaying everything since the intention was to potentially filter some data
-            System.out.printf("Invalid transaction ID format: %s%n", args[i]);
-            return 1;
-          }
-        }
-      }
-      
-      // Parse TStatus filters for print display
-      EnumSet<TStatus> filterStatus = null;
-      if (cl.hasOption(statusOption.getOpt())) {
-        filterStatus = EnumSet.noneOf(TStatus.class);
-        String[] tstat = cl.getOptionValues(statusOption.getOpt());
-        for (int i = 0; i < tstat.length; i++) {
-          try {
-            filterStatus.add(TStatus.valueOf(tstat[i]));
-          } catch (IllegalArgumentException iae) {
-            System.out.printf("Invalid transaction status name: %s%n", tstat[i]);
-            return 1;
-          }
-        }
-      }
-      
-      StringBuilder buf = new StringBuilder(8096);
-      Formatter fmt = new Formatter(buf);
-      admin.print(zs, zk, ZooUtil.getRoot(instance) + Constants.ZTABLE_LOCKS, fmt, filterTxid, filterStatus);
-      shellState.printLines(Collections.singletonList(buf.toString()).iterator(), true);
-    } else {
-      throw new ParseException("Invalid command option");
-    }
-    
-    return failedCommand ? 1 : 0;
-  }
-  
-  protected synchronized IZooReaderWriter getZooReaderWriter(Instance instance, String secret) {
-    
-    if (secret == null) {
-      @SuppressWarnings("deprecation")
-      AccumuloConfiguration conf = AccumuloConfiguration.getSiteConfiguration();
-      secret = conf.get(Property.INSTANCE_SECRET);
-    }
-    
-    return new ZooReaderWriter(instance.getZooKeepers(), instance.getZooKeepersSessionTimeOut(), SCHEME, (USER + ":" + secret).getBytes());
-  }
-  
-  @Override
-  public String description() {
-    return "manage FATE transactions";
-  }
-  
-  @Override
-  public String usage() {
-    return getName() + " fail <txid>... | delete <txid>... | print [<txid>...]";
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-    secretOption = new Option("s", "secret", true, "specify the instance secret to use");
-    secretOption.setOptionalArg(false);
-    o.addOption(secretOption);
-    statusOption = new Option("t", "status-type", true,
-        "filter 'print' on the transaction status type(s) {NEW, IN_PROGRESS, FAILED_IN_PROGRESS, FAILED, SUCCESSFUL}");
-    statusOption.setArgs(Option.UNLIMITED_VALUES);
-    statusOption.setOptionalArg(false);
-    o.addOption(statusOption);
-    return o;
-  }
-  
-  @Override
-  public int numArgs() {
-    // Arg length varies between 1 to n
-    return -1;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/FlushCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/FlushCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/FlushCommand.java
deleted file mode 100644
index de175eb..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/FlushCommand.java
+++ /dev/null
@@ -1,63 +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.accumulo.core.util.shell.commands;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.TableNotFoundException;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-import org.apache.hadoop.io.Text;
-
-public class FlushCommand extends TableOperation {
-  private Text startRow;
-  private Text endRow;
-  
-  private boolean wait;
-  private Option waitOpt;
-  
-  @Override
-  public String description() {
-    return "flushes a tables data that is currently in memory to disk";
-  }
-  
-  protected void doTableOp(final Shell shellState, final String tableName) throws AccumuloException, AccumuloSecurityException, TableNotFoundException {
-    shellState.getConnector().tableOperations().flush(tableName, startRow, endRow, wait);
-    Shell.log.info("Flush of table " + tableName + (wait ? " completed." : " initiated..."));
-  }
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    wait = cl.hasOption(waitOpt.getLongOpt());
-    startRow = OptUtil.getStartRow(cl);
-    endRow = OptUtil.getEndRow(cl);
-    return super.execute(fullCommand, cl, shellState);
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options opts = super.getOptions();
-    waitOpt = new Option("w", "wait", false, "wait for flush to finish");
-    opts.addOption(waitOpt);
-    opts.addOption(OptUtil.startRowOpt());
-    opts.addOption(OptUtil.endRowOpt());
-    
-    return opts;
-  }
-}


[49/53] [abbrv] ACCUMULO-2573 First stab at changes to IDL for replication

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/accumulo/blob/d257001d/core/src/main/java/org/apache/accumulo/core/replication/thrift/WalEdits.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/replication/thrift/WalEdits.java b/core/src/main/java/org/apache/accumulo/core/replication/thrift/WalEdits.java
new file mode 100644
index 0000000..b4942d4
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/replication/thrift/WalEdits.java
@@ -0,0 +1,456 @@
+/*
+ * 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.
+ */
+/**
+ * Autogenerated by Thrift Compiler (0.9.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ *  @generated
+ */
+package org.apache.accumulo.core.replication.thrift;
+
+import org.apache.thrift.scheme.IScheme;
+import org.apache.thrift.scheme.SchemeFactory;
+import org.apache.thrift.scheme.StandardScheme;
+
+import org.apache.thrift.scheme.TupleScheme;
+import org.apache.thrift.protocol.TTupleProtocol;
+import org.apache.thrift.protocol.TProtocolException;
+import org.apache.thrift.EncodingUtils;
+import org.apache.thrift.TException;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.EnumMap;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.EnumSet;
+import java.util.Collections;
+import java.util.BitSet;
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@SuppressWarnings("all") public class WalEdits implements org.apache.thrift.TBase<WalEdits, WalEdits._Fields>, java.io.Serializable, Cloneable {
+  private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("WalEdits");
+
+  private static final org.apache.thrift.protocol.TField EDITS_FIELD_DESC = new org.apache.thrift.protocol.TField("edits", org.apache.thrift.protocol.TType.LIST, (short)1);
+
+  private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
+  static {
+    schemes.put(StandardScheme.class, new WalEditsStandardSchemeFactory());
+    schemes.put(TupleScheme.class, new WalEditsTupleSchemeFactory());
+  }
+
+  public List<ByteBuffer> edits; // required
+
+  /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+  @SuppressWarnings("all") public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+    EDITS((short)1, "edits");
+
+    private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+
+    static {
+      for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        byName.put(field.getFieldName(), field);
+      }
+    }
+
+    /**
+     * Find the _Fields constant that matches fieldId, or null if its not found.
+     */
+    public static _Fields findByThriftId(int fieldId) {
+      switch(fieldId) {
+        case 1: // EDITS
+          return EDITS;
+        default:
+          return null;
+      }
+    }
+
+    /**
+     * Find the _Fields constant that matches fieldId, throwing an exception
+     * if it is not found.
+     */
+    public static _Fields findByThriftIdOrThrow(int fieldId) {
+      _Fields fields = findByThriftId(fieldId);
+      if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+      return fields;
+    }
+
+    /**
+     * Find the _Fields constant that matches name, or null if its not found.
+     */
+    public static _Fields findByName(String name) {
+      return byName.get(name);
+    }
+
+    private final short _thriftId;
+    private final String _fieldName;
+
+    _Fields(short thriftId, String fieldName) {
+      _thriftId = thriftId;
+      _fieldName = fieldName;
+    }
+
+    public short getThriftFieldId() {
+      return _thriftId;
+    }
+
+    public String getFieldName() {
+      return _fieldName;
+    }
+  }
+
+  // isset id assignments
+  public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+  static {
+    Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+    tmpMap.put(_Fields.EDITS, new org.apache.thrift.meta_data.FieldMetaData("edits", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+        new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
+            new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING            , true))));
+    metaDataMap = Collections.unmodifiableMap(tmpMap);
+    org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(WalEdits.class, metaDataMap);
+  }
+
+  public WalEdits() {
+  }
+
+  public WalEdits(
+    List<ByteBuffer> edits)
+  {
+    this();
+    this.edits = edits;
+  }
+
+  /**
+   * Performs a deep copy on <i>other</i>.
+   */
+  public WalEdits(WalEdits other) {
+    if (other.isSetEdits()) {
+      List<ByteBuffer> __this__edits = new ArrayList<ByteBuffer>();
+      for (ByteBuffer other_element : other.edits) {
+        ByteBuffer temp_binary_element = org.apache.thrift.TBaseHelper.copyBinary(other_element);
+;
+        __this__edits.add(temp_binary_element);
+      }
+      this.edits = __this__edits;
+    }
+  }
+
+  public WalEdits deepCopy() {
+    return new WalEdits(this);
+  }
+
+  @Override
+  public void clear() {
+    this.edits = null;
+  }
+
+  public int getEditsSize() {
+    return (this.edits == null) ? 0 : this.edits.size();
+  }
+
+  public java.util.Iterator<ByteBuffer> getEditsIterator() {
+    return (this.edits == null) ? null : this.edits.iterator();
+  }
+
+  public void addToEdits(ByteBuffer elem) {
+    if (this.edits == null) {
+      this.edits = new ArrayList<ByteBuffer>();
+    }
+    this.edits.add(elem);
+  }
+
+  public List<ByteBuffer> getEdits() {
+    return this.edits;
+  }
+
+  public WalEdits setEdits(List<ByteBuffer> edits) {
+    this.edits = edits;
+    return this;
+  }
+
+  public void unsetEdits() {
+    this.edits = null;
+  }
+
+  /** Returns true if field edits is set (has been assigned a value) and false otherwise */
+  public boolean isSetEdits() {
+    return this.edits != null;
+  }
+
+  public void setEditsIsSet(boolean value) {
+    if (!value) {
+      this.edits = null;
+    }
+  }
+
+  public void setFieldValue(_Fields field, Object value) {
+    switch (field) {
+    case EDITS:
+      if (value == null) {
+        unsetEdits();
+      } else {
+        setEdits((List<ByteBuffer>)value);
+      }
+      break;
+
+    }
+  }
+
+  public Object getFieldValue(_Fields field) {
+    switch (field) {
+    case EDITS:
+      return getEdits();
+
+    }
+    throw new IllegalStateException();
+  }
+
+  /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+  public boolean isSet(_Fields field) {
+    if (field == null) {
+      throw new IllegalArgumentException();
+    }
+
+    switch (field) {
+    case EDITS:
+      return isSetEdits();
+    }
+    throw new IllegalStateException();
+  }
+
+  @Override
+  public boolean equals(Object that) {
+    if (that == null)
+      return false;
+    if (that instanceof WalEdits)
+      return this.equals((WalEdits)that);
+    return false;
+  }
+
+  public boolean equals(WalEdits that) {
+    if (that == null)
+      return false;
+
+    boolean this_present_edits = true && this.isSetEdits();
+    boolean that_present_edits = true && that.isSetEdits();
+    if (this_present_edits || that_present_edits) {
+      if (!(this_present_edits && that_present_edits))
+        return false;
+      if (!this.edits.equals(that.edits))
+        return false;
+    }
+
+    return true;
+  }
+
+  @Override
+  public int hashCode() {
+    return 0;
+  }
+
+  public int compareTo(WalEdits other) {
+    if (!getClass().equals(other.getClass())) {
+      return getClass().getName().compareTo(other.getClass().getName());
+    }
+
+    int lastComparison = 0;
+    WalEdits typedOther = (WalEdits)other;
+
+    lastComparison = Boolean.valueOf(isSetEdits()).compareTo(typedOther.isSetEdits());
+    if (lastComparison != 0) {
+      return lastComparison;
+    }
+    if (isSetEdits()) {
+      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.edits, typedOther.edits);
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+    }
+    return 0;
+  }
+
+  public _Fields fieldForId(int fieldId) {
+    return _Fields.findByThriftId(fieldId);
+  }
+
+  public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+    schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+  }
+
+  public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+    schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
+  }
+
+  @Override
+  public String toString() {
+    StringBuilder sb = new StringBuilder("WalEdits(");
+    boolean first = true;
+
+    sb.append("edits:");
+    if (this.edits == null) {
+      sb.append("null");
+    } else {
+      sb.append(this.edits);
+    }
+    first = false;
+    sb.append(")");
+    return sb.toString();
+  }
+
+  public void validate() throws org.apache.thrift.TException {
+    // check for required fields
+    // check for sub-struct validity
+  }
+
+  private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+    try {
+      write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+    } catch (org.apache.thrift.TException te) {
+      throw new java.io.IOException(te);
+    }
+  }
+
+  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    try {
+      read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+    } catch (org.apache.thrift.TException te) {
+      throw new java.io.IOException(te);
+    }
+  }
+
+  private static class WalEditsStandardSchemeFactory implements SchemeFactory {
+    public WalEditsStandardScheme getScheme() {
+      return new WalEditsStandardScheme();
+    }
+  }
+
+  private static class WalEditsStandardScheme extends StandardScheme<WalEdits> {
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot, WalEdits struct) throws org.apache.thrift.TException {
+      org.apache.thrift.protocol.TField schemeField;
+      iprot.readStructBegin();
+      while (true)
+      {
+        schemeField = iprot.readFieldBegin();
+        if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+          break;
+        }
+        switch (schemeField.id) {
+          case 1: // EDITS
+            if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
+              {
+                org.apache.thrift.protocol.TList _list0 = iprot.readListBegin();
+                struct.edits = new ArrayList<ByteBuffer>(_list0.size);
+                for (int _i1 = 0; _i1 < _list0.size; ++_i1)
+                {
+                  ByteBuffer _elem2; // required
+                  _elem2 = iprot.readBinary();
+                  struct.edits.add(_elem2);
+                }
+                iprot.readListEnd();
+              }
+              struct.setEditsIsSet(true);
+            } else { 
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+            }
+            break;
+          default:
+            org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+        }
+        iprot.readFieldEnd();
+      }
+      iprot.readStructEnd();
+
+      // check for required fields of primitive type, which can't be checked in the validate method
+      struct.validate();
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot, WalEdits struct) throws org.apache.thrift.TException {
+      struct.validate();
+
+      oprot.writeStructBegin(STRUCT_DESC);
+      if (struct.edits != null) {
+        oprot.writeFieldBegin(EDITS_FIELD_DESC);
+        {
+          oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRING, struct.edits.size()));
+          for (ByteBuffer _iter3 : struct.edits)
+          {
+            oprot.writeBinary(_iter3);
+          }
+          oprot.writeListEnd();
+        }
+        oprot.writeFieldEnd();
+      }
+      oprot.writeFieldStop();
+      oprot.writeStructEnd();
+    }
+
+  }
+
+  private static class WalEditsTupleSchemeFactory implements SchemeFactory {
+    public WalEditsTupleScheme getScheme() {
+      return new WalEditsTupleScheme();
+    }
+  }
+
+  private static class WalEditsTupleScheme extends TupleScheme<WalEdits> {
+
+    @Override
+    public void write(org.apache.thrift.protocol.TProtocol prot, WalEdits struct) throws org.apache.thrift.TException {
+      TTupleProtocol oprot = (TTupleProtocol) prot;
+      BitSet optionals = new BitSet();
+      if (struct.isSetEdits()) {
+        optionals.set(0);
+      }
+      oprot.writeBitSet(optionals, 1);
+      if (struct.isSetEdits()) {
+        {
+          oprot.writeI32(struct.edits.size());
+          for (ByteBuffer _iter4 : struct.edits)
+          {
+            oprot.writeBinary(_iter4);
+          }
+        }
+      }
+    }
+
+    @Override
+    public void read(org.apache.thrift.protocol.TProtocol prot, WalEdits struct) throws org.apache.thrift.TException {
+      TTupleProtocol iprot = (TTupleProtocol) prot;
+      BitSet incoming = iprot.readBitSet(1);
+      if (incoming.get(0)) {
+        {
+          org.apache.thrift.protocol.TList _list5 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRING, iprot.readI32());
+          struct.edits = new ArrayList<ByteBuffer>(_list5.size);
+          for (int _i6 = 0; _i6 < _list5.size; ++_i6)
+          {
+            ByteBuffer _elem7; // required
+            _elem7 = iprot.readBinary();
+            struct.edits.add(_elem7);
+          }
+        }
+        struct.setEditsIsSet(true);
+      }
+    }
+  }
+
+}
+

http://git-wip-us.apache.org/repos/asf/accumulo/blob/d257001d/core/src/main/java/org/apache/accumulo/core/tabletserver/thrift/ReplicationFailedException.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/tabletserver/thrift/ReplicationFailedException.java b/core/src/main/java/org/apache/accumulo/core/tabletserver/thrift/ReplicationFailedException.java
new file mode 100644
index 0000000..63c6e00
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/tabletserver/thrift/ReplicationFailedException.java
@@ -0,0 +1,402 @@
+/*
+ * 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.
+ */
+/**
+ * Autogenerated by Thrift Compiler (0.9.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ *  @generated
+ */
+package org.apache.accumulo.core.tabletserver.thrift;
+
+import org.apache.thrift.scheme.IScheme;
+import org.apache.thrift.scheme.SchemeFactory;
+import org.apache.thrift.scheme.StandardScheme;
+
+import org.apache.thrift.scheme.TupleScheme;
+import org.apache.thrift.protocol.TTupleProtocol;
+import org.apache.thrift.protocol.TProtocolException;
+import org.apache.thrift.EncodingUtils;
+import org.apache.thrift.TException;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.EnumMap;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.EnumSet;
+import java.util.Collections;
+import java.util.BitSet;
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@SuppressWarnings("all") public class ReplicationFailedException extends TException implements org.apache.thrift.TBase<ReplicationFailedException, ReplicationFailedException._Fields>, java.io.Serializable, Cloneable {
+  private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("ReplicationFailedException");
+
+  private static final org.apache.thrift.protocol.TField REASON_FIELD_DESC = new org.apache.thrift.protocol.TField("reason", org.apache.thrift.protocol.TType.STRING, (short)1);
+
+  private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
+  static {
+    schemes.put(StandardScheme.class, new ReplicationFailedExceptionStandardSchemeFactory());
+    schemes.put(TupleScheme.class, new ReplicationFailedExceptionTupleSchemeFactory());
+  }
+
+  public String reason; // required
+
+  /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+  @SuppressWarnings("all") public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+    REASON((short)1, "reason");
+
+    private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+
+    static {
+      for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        byName.put(field.getFieldName(), field);
+      }
+    }
+
+    /**
+     * Find the _Fields constant that matches fieldId, or null if its not found.
+     */
+    public static _Fields findByThriftId(int fieldId) {
+      switch(fieldId) {
+        case 1: // REASON
+          return REASON;
+        default:
+          return null;
+      }
+    }
+
+    /**
+     * Find the _Fields constant that matches fieldId, throwing an exception
+     * if it is not found.
+     */
+    public static _Fields findByThriftIdOrThrow(int fieldId) {
+      _Fields fields = findByThriftId(fieldId);
+      if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+      return fields;
+    }
+
+    /**
+     * Find the _Fields constant that matches name, or null if its not found.
+     */
+    public static _Fields findByName(String name) {
+      return byName.get(name);
+    }
+
+    private final short _thriftId;
+    private final String _fieldName;
+
+    _Fields(short thriftId, String fieldName) {
+      _thriftId = thriftId;
+      _fieldName = fieldName;
+    }
+
+    public short getThriftFieldId() {
+      return _thriftId;
+    }
+
+    public String getFieldName() {
+      return _fieldName;
+    }
+  }
+
+  // isset id assignments
+  public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+  static {
+    Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+    tmpMap.put(_Fields.REASON, new org.apache.thrift.meta_data.FieldMetaData("reason", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
+    metaDataMap = Collections.unmodifiableMap(tmpMap);
+    org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(ReplicationFailedException.class, metaDataMap);
+  }
+
+  public ReplicationFailedException() {
+  }
+
+  public ReplicationFailedException(
+    String reason)
+  {
+    this();
+    this.reason = reason;
+  }
+
+  /**
+   * Performs a deep copy on <i>other</i>.
+   */
+  public ReplicationFailedException(ReplicationFailedException other) {
+    if (other.isSetReason()) {
+      this.reason = other.reason;
+    }
+  }
+
+  public ReplicationFailedException deepCopy() {
+    return new ReplicationFailedException(this);
+  }
+
+  @Override
+  public void clear() {
+    this.reason = null;
+  }
+
+  public String getReason() {
+    return this.reason;
+  }
+
+  public ReplicationFailedException setReason(String reason) {
+    this.reason = reason;
+    return this;
+  }
+
+  public void unsetReason() {
+    this.reason = null;
+  }
+
+  /** Returns true if field reason is set (has been assigned a value) and false otherwise */
+  public boolean isSetReason() {
+    return this.reason != null;
+  }
+
+  public void setReasonIsSet(boolean value) {
+    if (!value) {
+      this.reason = null;
+    }
+  }
+
+  public void setFieldValue(_Fields field, Object value) {
+    switch (field) {
+    case REASON:
+      if (value == null) {
+        unsetReason();
+      } else {
+        setReason((String)value);
+      }
+      break;
+
+    }
+  }
+
+  public Object getFieldValue(_Fields field) {
+    switch (field) {
+    case REASON:
+      return getReason();
+
+    }
+    throw new IllegalStateException();
+  }
+
+  /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+  public boolean isSet(_Fields field) {
+    if (field == null) {
+      throw new IllegalArgumentException();
+    }
+
+    switch (field) {
+    case REASON:
+      return isSetReason();
+    }
+    throw new IllegalStateException();
+  }
+
+  @Override
+  public boolean equals(Object that) {
+    if (that == null)
+      return false;
+    if (that instanceof ReplicationFailedException)
+      return this.equals((ReplicationFailedException)that);
+    return false;
+  }
+
+  public boolean equals(ReplicationFailedException that) {
+    if (that == null)
+      return false;
+
+    boolean this_present_reason = true && this.isSetReason();
+    boolean that_present_reason = true && that.isSetReason();
+    if (this_present_reason || that_present_reason) {
+      if (!(this_present_reason && that_present_reason))
+        return false;
+      if (!this.reason.equals(that.reason))
+        return false;
+    }
+
+    return true;
+  }
+
+  @Override
+  public int hashCode() {
+    return 0;
+  }
+
+  public int compareTo(ReplicationFailedException other) {
+    if (!getClass().equals(other.getClass())) {
+      return getClass().getName().compareTo(other.getClass().getName());
+    }
+
+    int lastComparison = 0;
+    ReplicationFailedException typedOther = (ReplicationFailedException)other;
+
+    lastComparison = Boolean.valueOf(isSetReason()).compareTo(typedOther.isSetReason());
+    if (lastComparison != 0) {
+      return lastComparison;
+    }
+    if (isSetReason()) {
+      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.reason, typedOther.reason);
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+    }
+    return 0;
+  }
+
+  public _Fields fieldForId(int fieldId) {
+    return _Fields.findByThriftId(fieldId);
+  }
+
+  public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+    schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+  }
+
+  public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+    schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
+  }
+
+  @Override
+  public String toString() {
+    StringBuilder sb = new StringBuilder("ReplicationFailedException(");
+    boolean first = true;
+
+    sb.append("reason:");
+    if (this.reason == null) {
+      sb.append("null");
+    } else {
+      sb.append(this.reason);
+    }
+    first = false;
+    sb.append(")");
+    return sb.toString();
+  }
+
+  public void validate() throws org.apache.thrift.TException {
+    // check for required fields
+    // check for sub-struct validity
+  }
+
+  private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+    try {
+      write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+    } catch (org.apache.thrift.TException te) {
+      throw new java.io.IOException(te);
+    }
+  }
+
+  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    try {
+      read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+    } catch (org.apache.thrift.TException te) {
+      throw new java.io.IOException(te);
+    }
+  }
+
+  private static class ReplicationFailedExceptionStandardSchemeFactory implements SchemeFactory {
+    public ReplicationFailedExceptionStandardScheme getScheme() {
+      return new ReplicationFailedExceptionStandardScheme();
+    }
+  }
+
+  private static class ReplicationFailedExceptionStandardScheme extends StandardScheme<ReplicationFailedException> {
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot, ReplicationFailedException struct) throws org.apache.thrift.TException {
+      org.apache.thrift.protocol.TField schemeField;
+      iprot.readStructBegin();
+      while (true)
+      {
+        schemeField = iprot.readFieldBegin();
+        if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+          break;
+        }
+        switch (schemeField.id) {
+          case 1: // REASON
+            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+              struct.reason = iprot.readString();
+              struct.setReasonIsSet(true);
+            } else { 
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+            }
+            break;
+          default:
+            org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+        }
+        iprot.readFieldEnd();
+      }
+      iprot.readStructEnd();
+
+      // check for required fields of primitive type, which can't be checked in the validate method
+      struct.validate();
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot, ReplicationFailedException struct) throws org.apache.thrift.TException {
+      struct.validate();
+
+      oprot.writeStructBegin(STRUCT_DESC);
+      if (struct.reason != null) {
+        oprot.writeFieldBegin(REASON_FIELD_DESC);
+        oprot.writeString(struct.reason);
+        oprot.writeFieldEnd();
+      }
+      oprot.writeFieldStop();
+      oprot.writeStructEnd();
+    }
+
+  }
+
+  private static class ReplicationFailedExceptionTupleSchemeFactory implements SchemeFactory {
+    public ReplicationFailedExceptionTupleScheme getScheme() {
+      return new ReplicationFailedExceptionTupleScheme();
+    }
+  }
+
+  private static class ReplicationFailedExceptionTupleScheme extends TupleScheme<ReplicationFailedException> {
+
+    @Override
+    public void write(org.apache.thrift.protocol.TProtocol prot, ReplicationFailedException struct) throws org.apache.thrift.TException {
+      TTupleProtocol oprot = (TTupleProtocol) prot;
+      BitSet optionals = new BitSet();
+      if (struct.isSetReason()) {
+        optionals.set(0);
+      }
+      oprot.writeBitSet(optionals, 1);
+      if (struct.isSetReason()) {
+        oprot.writeString(struct.reason);
+      }
+    }
+
+    @Override
+    public void read(org.apache.thrift.protocol.TProtocol prot, ReplicationFailedException struct) throws org.apache.thrift.TException {
+      TTupleProtocol iprot = (TTupleProtocol) prot;
+      BitSet incoming = iprot.readBitSet(1);
+      if (incoming.get(0)) {
+        struct.reason = iprot.readString();
+        struct.setReasonIsSet(true);
+      }
+    }
+  }
+
+}
+

http://git-wip-us.apache.org/repos/asf/accumulo/blob/d257001d/core/src/main/java/org/apache/accumulo/core/tabletserver/thrift/TabletClientService.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/tabletserver/thrift/TabletClientService.java b/core/src/main/java/org/apache/accumulo/core/tabletserver/thrift/TabletClientService.java
index d02b5da..9b9d17c 100644
--- a/core/src/main/java/org/apache/accumulo/core/tabletserver/thrift/TabletClientService.java
+++ b/core/src/main/java/org/apache/accumulo/core/tabletserver/thrift/TabletClientService.java
@@ -110,6 +110,8 @@ import org.slf4j.LoggerFactory;
 
     public void removeLogs(org.apache.accumulo.trace.thrift.TInfo tinfo, org.apache.accumulo.core.security.thrift.TCredentials credentials, List<String> filenames) throws org.apache.thrift.TException;
 
+    public boolean replicateData(org.apache.accumulo.trace.thrift.TInfo tinfo, org.apache.accumulo.core.security.thrift.TCredentials credentials, String file, long offset, long count) throws org.apache.accumulo.core.client.impl.thrift.ThriftSecurityException, ReplicationFailedException, org.apache.thrift.TException;
+
   }
 
   public interface AsyncIface extends org.apache.accumulo.core.client.impl.thrift.ClientService .AsyncIface {
@@ -174,6 +176,8 @@ import org.slf4j.LoggerFactory;
 
     public void removeLogs(org.apache.accumulo.trace.thrift.TInfo tinfo, org.apache.accumulo.core.security.thrift.TCredentials credentials, List<String> filenames, org.apache.thrift.async.AsyncMethodCallback<AsyncClient.removeLogs_call> resultHandler) throws org.apache.thrift.TException;
 
+    public void replicateData(org.apache.accumulo.trace.thrift.TInfo tinfo, org.apache.accumulo.core.security.thrift.TCredentials credentials, String file, long offset, long count, org.apache.thrift.async.AsyncMethodCallback<AsyncClient.replicateData_call> resultHandler) throws org.apache.thrift.TException;
+
   }
 
   public static class Client extends org.apache.accumulo.core.client.impl.thrift.ClientService.Client implements Iface {
@@ -905,6 +909,39 @@ import org.slf4j.LoggerFactory;
       sendBase("removeLogs", args);
     }
 
+    public boolean replicateData(org.apache.accumulo.trace.thrift.TInfo tinfo, org.apache.accumulo.core.security.thrift.TCredentials credentials, String file, long offset, long count) throws org.apache.accumulo.core.client.impl.thrift.ThriftSecurityException, ReplicationFailedException, org.apache.thrift.TException
+    {
+      send_replicateData(tinfo, credentials, file, offset, count);
+      return recv_replicateData();
+    }
+
+    public void send_replicateData(org.apache.accumulo.trace.thrift.TInfo tinfo, org.apache.accumulo.core.security.thrift.TCredentials credentials, String file, long offset, long count) throws org.apache.thrift.TException
+    {
+      replicateData_args args = new replicateData_args();
+      args.setTinfo(tinfo);
+      args.setCredentials(credentials);
+      args.setFile(file);
+      args.setOffset(offset);
+      args.setCount(count);
+      sendBase("replicateData", args);
+    }
+
+    public boolean recv_replicateData() throws org.apache.accumulo.core.client.impl.thrift.ThriftSecurityException, ReplicationFailedException, org.apache.thrift.TException
+    {
+      replicateData_result result = new replicateData_result();
+      receiveBase(result, "replicateData");
+      if (result.isSetSuccess()) {
+        return result.success;
+      }
+      if (result.sec != null) {
+        throw result.sec;
+      }
+      if (result.rfe != null) {
+        throw result.rfe;
+      }
+      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "replicateData failed: unknown result");
+    }
+
   }
   public static class AsyncClient extends org.apache.accumulo.core.client.impl.thrift.ClientService.AsyncClient implements AsyncIface {
     public static class Factory implements org.apache.thrift.async.TAsyncClientFactory<AsyncClient> {
@@ -2112,6 +2149,50 @@ import org.slf4j.LoggerFactory;
       }
     }
 
+    public void replicateData(org.apache.accumulo.trace.thrift.TInfo tinfo, org.apache.accumulo.core.security.thrift.TCredentials credentials, String file, long offset, long count, org.apache.thrift.async.AsyncMethodCallback<replicateData_call> resultHandler) throws org.apache.thrift.TException {
+      checkReady();
+      replicateData_call method_call = new replicateData_call(tinfo, credentials, file, offset, count, resultHandler, this, ___protocolFactory, ___transport);
+      this.___currentMethod = method_call;
+      ___manager.call(method_call);
+    }
+
+    public static class replicateData_call extends org.apache.thrift.async.TAsyncMethodCall {
+      private org.apache.accumulo.trace.thrift.TInfo tinfo;
+      private org.apache.accumulo.core.security.thrift.TCredentials credentials;
+      private String file;
+      private long offset;
+      private long count;
+      public replicateData_call(org.apache.accumulo.trace.thrift.TInfo tinfo, org.apache.accumulo.core.security.thrift.TCredentials credentials, String file, long offset, long count, org.apache.thrift.async.AsyncMethodCallback<replicateData_call> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
+        super(client, protocolFactory, transport, resultHandler, false);
+        this.tinfo = tinfo;
+        this.credentials = credentials;
+        this.file = file;
+        this.offset = offset;
+        this.count = count;
+      }
+
+      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
+        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("replicateData", org.apache.thrift.protocol.TMessageType.CALL, 0));
+        replicateData_args args = new replicateData_args();
+        args.setTinfo(tinfo);
+        args.setCredentials(credentials);
+        args.setFile(file);
+        args.setOffset(offset);
+        args.setCount(count);
+        args.write(prot);
+        prot.writeMessageEnd();
+      }
+
+      public boolean getResult() throws org.apache.accumulo.core.client.impl.thrift.ThriftSecurityException, ReplicationFailedException, org.apache.thrift.TException {
+        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
+          throw new IllegalStateException("Method call not finished!");
+        }
+        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
+        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
+        return (new Client(prot)).recv_replicateData();
+      }
+    }
+
   }
 
   public static class Processor<I extends Iface> extends org.apache.accumulo.core.client.impl.thrift.ClientService.Processor<I> implements org.apache.thrift.TProcessor {
@@ -2155,6 +2236,7 @@ import org.slf4j.LoggerFactory;
       processMap.put("getActiveScans", new getActiveScans());
       processMap.put("getActiveCompactions", new getActiveCompactions());
       processMap.put("removeLogs", new removeLogs());
+      processMap.put("replicateData", new replicateData());
       return processMap;
     }
 
@@ -2834,6 +2916,33 @@ import org.slf4j.LoggerFactory;
       }
     }
 
+    public static class replicateData<I extends Iface> extends org.apache.thrift.ProcessFunction<I, replicateData_args> {
+      public replicateData() {
+        super("replicateData");
+      }
+
+      public replicateData_args getEmptyArgsInstance() {
+        return new replicateData_args();
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      public replicateData_result getResult(I iface, replicateData_args args) throws org.apache.thrift.TException {
+        replicateData_result result = new replicateData_result();
+        try {
+          result.success = iface.replicateData(args.tinfo, args.credentials, args.file, args.offset, args.count);
+          result.setSuccessIsSet(true);
+        } catch (org.apache.accumulo.core.client.impl.thrift.ThriftSecurityException sec) {
+          result.sec = sec;
+        } catch (ReplicationFailedException rfe) {
+          result.rfe = rfe;
+        }
+        return result;
+      }
+    }
+
   }
 
   public static class startScan_args implements org.apache.thrift.TBase<startScan_args, startScan_args._Fields>, java.io.Serializable, Cloneable   {
@@ -31869,4 +31978,1318 @@ import org.slf4j.LoggerFactory;
 
   }
 
+  public static class replicateData_args implements org.apache.thrift.TBase<replicateData_args, replicateData_args._Fields>, java.io.Serializable, Cloneable   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("replicateData_args");
+
+    private static final org.apache.thrift.protocol.TField TINFO_FIELD_DESC = new org.apache.thrift.protocol.TField("tinfo", org.apache.thrift.protocol.TType.STRUCT, (short)1);
+    private static final org.apache.thrift.protocol.TField CREDENTIALS_FIELD_DESC = new org.apache.thrift.protocol.TField("credentials", org.apache.thrift.protocol.TType.STRUCT, (short)2);
+    private static final org.apache.thrift.protocol.TField FILE_FIELD_DESC = new org.apache.thrift.protocol.TField("file", org.apache.thrift.protocol.TType.STRING, (short)3);
+    private static final org.apache.thrift.protocol.TField OFFSET_FIELD_DESC = new org.apache.thrift.protocol.TField("offset", org.apache.thrift.protocol.TType.I64, (short)4);
+    private static final org.apache.thrift.protocol.TField COUNT_FIELD_DESC = new org.apache.thrift.protocol.TField("count", org.apache.thrift.protocol.TType.I64, (short)5);
+
+    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
+    static {
+      schemes.put(StandardScheme.class, new replicateData_argsStandardSchemeFactory());
+      schemes.put(TupleScheme.class, new replicateData_argsTupleSchemeFactory());
+    }
+
+    public org.apache.accumulo.trace.thrift.TInfo tinfo; // required
+    public org.apache.accumulo.core.security.thrift.TCredentials credentials; // required
+    public String file; // required
+    public long offset; // required
+    public long count; // required
+
+    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+    @SuppressWarnings("all") public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+      TINFO((short)1, "tinfo"),
+      CREDENTIALS((short)2, "credentials"),
+      FILE((short)3, "file"),
+      OFFSET((short)4, "offset"),
+      COUNT((short)5, "count");
+
+      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+
+      static {
+        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+          byName.put(field.getFieldName(), field);
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, or null if its not found.
+       */
+      public static _Fields findByThriftId(int fieldId) {
+        switch(fieldId) {
+          case 1: // TINFO
+            return TINFO;
+          case 2: // CREDENTIALS
+            return CREDENTIALS;
+          case 3: // FILE
+            return FILE;
+          case 4: // OFFSET
+            return OFFSET;
+          case 5: // COUNT
+            return COUNT;
+          default:
+            return null;
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, throwing an exception
+       * if it is not found.
+       */
+      public static _Fields findByThriftIdOrThrow(int fieldId) {
+        _Fields fields = findByThriftId(fieldId);
+        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    private static final int __OFFSET_ISSET_ID = 0;
+    private static final int __COUNT_ISSET_ID = 1;
+    private byte __isset_bitfield = 0;
+    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    static {
+      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+      tmpMap.put(_Fields.TINFO, new org.apache.thrift.meta_data.FieldMetaData("tinfo", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.accumulo.trace.thrift.TInfo.class)));
+      tmpMap.put(_Fields.CREDENTIALS, new org.apache.thrift.meta_data.FieldMetaData("credentials", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.accumulo.core.security.thrift.TCredentials.class)));
+      tmpMap.put(_Fields.FILE, new org.apache.thrift.meta_data.FieldMetaData("file", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
+      tmpMap.put(_Fields.OFFSET, new org.apache.thrift.meta_data.FieldMetaData("offset", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64)));
+      tmpMap.put(_Fields.COUNT, new org.apache.thrift.meta_data.FieldMetaData("count", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64)));
+      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(replicateData_args.class, metaDataMap);
+    }
+
+    public replicateData_args() {
+    }
+
+    public replicateData_args(
+      org.apache.accumulo.trace.thrift.TInfo tinfo,
+      org.apache.accumulo.core.security.thrift.TCredentials credentials,
+      String file,
+      long offset,
+      long count)
+    {
+      this();
+      this.tinfo = tinfo;
+      this.credentials = credentials;
+      this.file = file;
+      this.offset = offset;
+      setOffsetIsSet(true);
+      this.count = count;
+      setCountIsSet(true);
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public replicateData_args(replicateData_args other) {
+      __isset_bitfield = other.__isset_bitfield;
+      if (other.isSetTinfo()) {
+        this.tinfo = new org.apache.accumulo.trace.thrift.TInfo(other.tinfo);
+      }
+      if (other.isSetCredentials()) {
+        this.credentials = new org.apache.accumulo.core.security.thrift.TCredentials(other.credentials);
+      }
+      if (other.isSetFile()) {
+        this.file = other.file;
+      }
+      this.offset = other.offset;
+      this.count = other.count;
+    }
+
+    public replicateData_args deepCopy() {
+      return new replicateData_args(this);
+    }
+
+    @Override
+    public void clear() {
+      this.tinfo = null;
+      this.credentials = null;
+      this.file = null;
+      setOffsetIsSet(false);
+      this.offset = 0;
+      setCountIsSet(false);
+      this.count = 0;
+    }
+
+    public org.apache.accumulo.trace.thrift.TInfo getTinfo() {
+      return this.tinfo;
+    }
+
+    public replicateData_args setTinfo(org.apache.accumulo.trace.thrift.TInfo tinfo) {
+      this.tinfo = tinfo;
+      return this;
+    }
+
+    public void unsetTinfo() {
+      this.tinfo = null;
+    }
+
+    /** Returns true if field tinfo is set (has been assigned a value) and false otherwise */
+    public boolean isSetTinfo() {
+      return this.tinfo != null;
+    }
+
+    public void setTinfoIsSet(boolean value) {
+      if (!value) {
+        this.tinfo = null;
+      }
+    }
+
+    public org.apache.accumulo.core.security.thrift.TCredentials getCredentials() {
+      return this.credentials;
+    }
+
+    public replicateData_args setCredentials(org.apache.accumulo.core.security.thrift.TCredentials credentials) {
+      this.credentials = credentials;
+      return this;
+    }
+
+    public void unsetCredentials() {
+      this.credentials = null;
+    }
+
+    /** Returns true if field credentials is set (has been assigned a value) and false otherwise */
+    public boolean isSetCredentials() {
+      return this.credentials != null;
+    }
+
+    public void setCredentialsIsSet(boolean value) {
+      if (!value) {
+        this.credentials = null;
+      }
+    }
+
+    public String getFile() {
+      return this.file;
+    }
+
+    public replicateData_args setFile(String file) {
+      this.file = file;
+      return this;
+    }
+
+    public void unsetFile() {
+      this.file = null;
+    }
+
+    /** Returns true if field file is set (has been assigned a value) and false otherwise */
+    public boolean isSetFile() {
+      return this.file != null;
+    }
+
+    public void setFileIsSet(boolean value) {
+      if (!value) {
+        this.file = null;
+      }
+    }
+
+    public long getOffset() {
+      return this.offset;
+    }
+
+    public replicateData_args setOffset(long offset) {
+      this.offset = offset;
+      setOffsetIsSet(true);
+      return this;
+    }
+
+    public void unsetOffset() {
+      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __OFFSET_ISSET_ID);
+    }
+
+    /** Returns true if field offset is set (has been assigned a value) and false otherwise */
+    public boolean isSetOffset() {
+      return EncodingUtils.testBit(__isset_bitfield, __OFFSET_ISSET_ID);
+    }
+
+    public void setOffsetIsSet(boolean value) {
+      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __OFFSET_ISSET_ID, value);
+    }
+
+    public long getCount() {
+      return this.count;
+    }
+
+    public replicateData_args setCount(long count) {
+      this.count = count;
+      setCountIsSet(true);
+      return this;
+    }
+
+    public void unsetCount() {
+      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __COUNT_ISSET_ID);
+    }
+
+    /** Returns true if field count is set (has been assigned a value) and false otherwise */
+    public boolean isSetCount() {
+      return EncodingUtils.testBit(__isset_bitfield, __COUNT_ISSET_ID);
+    }
+
+    public void setCountIsSet(boolean value) {
+      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __COUNT_ISSET_ID, value);
+    }
+
+    public void setFieldValue(_Fields field, Object value) {
+      switch (field) {
+      case TINFO:
+        if (value == null) {
+          unsetTinfo();
+        } else {
+          setTinfo((org.apache.accumulo.trace.thrift.TInfo)value);
+        }
+        break;
+
+      case CREDENTIALS:
+        if (value == null) {
+          unsetCredentials();
+        } else {
+          setCredentials((org.apache.accumulo.core.security.thrift.TCredentials)value);
+        }
+        break;
+
+      case FILE:
+        if (value == null) {
+          unsetFile();
+        } else {
+          setFile((String)value);
+        }
+        break;
+
+      case OFFSET:
+        if (value == null) {
+          unsetOffset();
+        } else {
+          setOffset((Long)value);
+        }
+        break;
+
+      case COUNT:
+        if (value == null) {
+          unsetCount();
+        } else {
+          setCount((Long)value);
+        }
+        break;
+
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      case TINFO:
+        return getTinfo();
+
+      case CREDENTIALS:
+        return getCredentials();
+
+      case FILE:
+        return getFile();
+
+      case OFFSET:
+        return Long.valueOf(getOffset());
+
+      case COUNT:
+        return Long.valueOf(getCount());
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case TINFO:
+        return isSetTinfo();
+      case CREDENTIALS:
+        return isSetCredentials();
+      case FILE:
+        return isSetFile();
+      case OFFSET:
+        return isSetOffset();
+      case COUNT:
+        return isSetCount();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof replicateData_args)
+        return this.equals((replicateData_args)that);
+      return false;
+    }
+
+    public boolean equals(replicateData_args that) {
+      if (that == null)
+        return false;
+
+      boolean this_present_tinfo = true && this.isSetTinfo();
+      boolean that_present_tinfo = true && that.isSetTinfo();
+      if (this_present_tinfo || that_present_tinfo) {
+        if (!(this_present_tinfo && that_present_tinfo))
+          return false;
+        if (!this.tinfo.equals(that.tinfo))
+          return false;
+      }
+
+      boolean this_present_credentials = true && this.isSetCredentials();
+      boolean that_present_credentials = true && that.isSetCredentials();
+      if (this_present_credentials || that_present_credentials) {
+        if (!(this_present_credentials && that_present_credentials))
+          return false;
+        if (!this.credentials.equals(that.credentials))
+          return false;
+      }
+
+      boolean this_present_file = true && this.isSetFile();
+      boolean that_present_file = true && that.isSetFile();
+      if (this_present_file || that_present_file) {
+        if (!(this_present_file && that_present_file))
+          return false;
+        if (!this.file.equals(that.file))
+          return false;
+      }
+
+      boolean this_present_offset = true;
+      boolean that_present_offset = true;
+      if (this_present_offset || that_present_offset) {
+        if (!(this_present_offset && that_present_offset))
+          return false;
+        if (this.offset != that.offset)
+          return false;
+      }
+
+      boolean this_present_count = true;
+      boolean that_present_count = true;
+      if (this_present_count || that_present_count) {
+        if (!(this_present_count && that_present_count))
+          return false;
+        if (this.count != that.count)
+          return false;
+      }
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      return 0;
+    }
+
+    public int compareTo(replicateData_args other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+      replicateData_args typedOther = (replicateData_args)other;
+
+      lastComparison = Boolean.valueOf(isSetTinfo()).compareTo(typedOther.isSetTinfo());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetTinfo()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.tinfo, typedOther.tinfo);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetCredentials()).compareTo(typedOther.isSetCredentials());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetCredentials()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.credentials, typedOther.credentials);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetFile()).compareTo(typedOther.isSetFile());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetFile()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.file, typedOther.file);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetOffset()).compareTo(typedOther.isSetOffset());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetOffset()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.offset, typedOther.offset);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetCount()).compareTo(typedOther.isSetCount());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetCount()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.count, typedOther.count);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      return 0;
+    }
+
+    public _Fields fieldForId(int fieldId) {
+      return _Fields.findByThriftId(fieldId);
+    }
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
+    }
+
+    @Override
+    public String toString() {
+      StringBuilder sb = new StringBuilder("replicateData_args(");
+      boolean first = true;
+
+      sb.append("tinfo:");
+      if (this.tinfo == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.tinfo);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("credentials:");
+      if (this.credentials == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.credentials);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("file:");
+      if (this.file == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.file);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("offset:");
+      sb.append(this.offset);
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("count:");
+      sb.append(this.count);
+      first = false;
+      sb.append(")");
+      return sb.toString();
+    }
+
+    public void validate() throws org.apache.thrift.TException {
+      // check for required fields
+      // check for sub-struct validity
+      if (tinfo != null) {
+        tinfo.validate();
+      }
+      if (credentials != null) {
+        credentials.validate();
+      }
+    }
+
+    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+      try {
+        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+      try {
+        // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor.
+        __isset_bitfield = 0;
+        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private static class replicateData_argsStandardSchemeFactory implements SchemeFactory {
+      public replicateData_argsStandardScheme getScheme() {
+        return new replicateData_argsStandardScheme();
+      }
+    }
+
+    private static class replicateData_argsStandardScheme extends StandardScheme<replicateData_args> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, replicateData_args struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TField schemeField;
+        iprot.readStructBegin();
+        while (true)
+        {
+          schemeField = iprot.readFieldBegin();
+          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+            break;
+          }
+          switch (schemeField.id) {
+            case 1: // TINFO
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.tinfo = new org.apache.accumulo.trace.thrift.TInfo();
+                struct.tinfo.read(iprot);
+                struct.setTinfoIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 2: // CREDENTIALS
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.credentials = new org.apache.accumulo.core.security.thrift.TCredentials();
+                struct.credentials.read(iprot);
+                struct.setCredentialsIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 3: // FILE
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+                struct.file = iprot.readString();
+                struct.setFileIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 4: // OFFSET
+              if (schemeField.type == org.apache.thrift.protocol.TType.I64) {
+                struct.offset = iprot.readI64();
+                struct.setOffsetIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 5: // COUNT
+              if (schemeField.type == org.apache.thrift.protocol.TType.I64) {
+                struct.count = iprot.readI64();
+                struct.setCountIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            default:
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+          }
+          iprot.readFieldEnd();
+        }
+        iprot.readStructEnd();
+
+        // check for required fields of primitive type, which can't be checked in the validate method
+        struct.validate();
+      }
+
+      public void write(org.apache.thrift.protocol.TProtocol oprot, replicateData_args struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        if (struct.tinfo != null) {
+          oprot.writeFieldBegin(TINFO_FIELD_DESC);
+          struct.tinfo.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        if (struct.credentials != null) {
+          oprot.writeFieldBegin(CREDENTIALS_FIELD_DESC);
+          struct.credentials.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        if (struct.file != null) {
+          oprot.writeFieldBegin(FILE_FIELD_DESC);
+          oprot.writeString(struct.file);
+          oprot.writeFieldEnd();
+        }
+        oprot.writeFieldBegin(OFFSET_FIELD_DESC);
+        oprot.writeI64(struct.offset);
+        oprot.writeFieldEnd();
+        oprot.writeFieldBegin(COUNT_FIELD_DESC);
+        oprot.writeI64(struct.count);
+        oprot.writeFieldEnd();
+        oprot.writeFieldStop();
+        oprot.writeStructEnd();
+      }
+
+    }
+
+    private static class replicateData_argsTupleSchemeFactory implements SchemeFactory {
+      public replicateData_argsTupleScheme getScheme() {
+        return new replicateData_argsTupleScheme();
+      }
+    }
+
+    private static class replicateData_argsTupleScheme extends TupleScheme<replicateData_args> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, replicateData_args struct) throws org.apache.thrift.TException {
+        TTupleProtocol oprot = (TTupleProtocol) prot;
+        BitSet optionals = new BitSet();
+        if (struct.isSetTinfo()) {
+          optionals.set(0);
+        }
+        if (struct.isSetCredentials()) {
+          optionals.set(1);
+        }
+        if (struct.isSetFile()) {
+          optionals.set(2);
+        }
+        if (struct.isSetOffset()) {
+          optionals.set(3);
+        }
+        if (struct.isSetCount()) {
+          optionals.set(4);
+        }
+        oprot.writeBitSet(optionals, 5);
+        if (struct.isSetTinfo()) {
+          struct.tinfo.write(oprot);
+        }
+        if (struct.isSetCredentials()) {
+          struct.credentials.write(oprot);
+        }
+        if (struct.isSetFile()) {
+          oprot.writeString(struct.file);
+        }
+        if (struct.isSetOffset()) {
+          oprot.writeI64(struct.offset);
+        }
+        if (struct.isSetCount()) {
+          oprot.writeI64(struct.count);
+        }
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, replicateData_args struct) throws org.apache.thrift.TException {
+        TTupleProtocol iprot = (TTupleProtocol) prot;
+        BitSet incoming = iprot.readBitSet(5);
+        if (incoming.get(0)) {
+          struct.tinfo = new org.apache.accumulo.trace.thrift.TInfo();
+          struct.tinfo.read(iprot);
+          struct.setTinfoIsSet(true);
+        }
+        if (incoming.get(1)) {
+          struct.credentials = new org.apache.accumulo.core.security.thrift.TCredentials();
+          struct.credentials.read(iprot);
+          struct.setCredentialsIsSet(true);
+        }
+        if (incoming.get(2)) {
+          struct.file = iprot.readString();
+          struct.setFileIsSet(true);
+        }
+        if (incoming.get(3)) {
+          struct.offset = iprot.readI64();
+          struct.setOffsetIsSet(true);
+        }
+        if (incoming.get(4)) {
+          struct.count = iprot.readI64();
+          struct.setCountIsSet(true);
+        }
+      }
+    }
+
+  }
+
+  public static class replicateData_result implements org.apache.thrift.TBase<replicateData_result, replicateData_result._Fields>, java.io.Serializable, Cloneable   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("replicateData_result");
+
+    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.BOOL, (short)0);
+    private static final org.apache.thrift.protocol.TField SEC_FIELD_DESC = new org.apache.thrift.protocol.TField("sec", org.apache.thrift.protocol.TType.STRUCT, (short)1);
+    private static final org.apache.thrift.protocol.TField RFE_FIELD_DESC = new org.apache.thrift.protocol.TField("rfe", org.apache.thrift.protocol.TType.STRUCT, (short)2);
+
+    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
+    static {
+      schemes.put(StandardScheme.class, new replicateData_resultStandardSchemeFactory());
+      schemes.put(TupleScheme.class, new replicateData_resultTupleSchemeFactory());
+    }
+
+    public boolean success; // required
+    public org.apache.accumulo.core.client.impl.thrift.ThriftSecurityException sec; // required
+    public ReplicationFailedException rfe; // required
+
+    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+    @SuppressWarnings("all") public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+      SUCCESS((short)0, "success"),
+      SEC((short)1, "sec"),
+      RFE((short)2, "rfe");
+
+      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+
+      static {
+        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+          byName.put(field.getFieldName(), field);
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, or null if its not found.
+       */
+      public static _Fields findByThriftId(int fieldId) {
+        switch(fieldId) {
+          case 0: // SUCCESS
+            return SUCCESS;
+          case 1: // SEC
+            return SEC;
+          case 2: // RFE
+            return RFE;
+          default:
+            return null;
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, throwing an exception
+       * if it is not found.
+       */
+      public static _Fields findByThriftIdOrThrow(int fieldId) {
+        _Fields fields = findByThriftId(fieldId);
+        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    private static final int __SUCCESS_ISSET_ID = 0;
+    private byte __isset_bitfield = 0;
+    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    static {
+      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
+      tmpMap.put(_Fields.SEC, new org.apache.thrift.meta_data.FieldMetaData("sec", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
+      tmpMap.put(_Fields.RFE, new org.apache.thrift.meta_data.FieldMetaData("rfe", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
+      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(replicateData_result.class, metaDataMap);
+    }
+
+    public replicateData_result() {
+    }
+
+    public replicateData_result(
+      boolean success,
+      org.apache.accumulo.core.client.impl.thrift.ThriftSecurityException sec,
+      ReplicationFailedException rfe)
+    {
+      this();
+      this.success = success;
+      setSuccessIsSet(true);
+      this.sec = sec;
+      this.rfe = rfe;
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public replicateData_result(replicateData_result other) {
+      __isset_bitfield = other.__isset_bitfield;
+      this.success = other.success;
+      if (other.isSetSec()) {
+        this.sec = new org.apache.accumulo.core.client.impl.thrift.ThriftSecurityException(other.sec);
+      }
+      if (other.isSetRfe()) {
+        this.rfe = new ReplicationFailedException(other.rfe);
+      }
+    }
+
+    public replicateData_result deepCopy() {
+      return new replicateData_result(this);
+    }
+
+    @Override
+    public void clear() {
+      setSuccessIsSet(false);
+      this.success = false;
+      this.sec = null;
+      this.rfe = null;
+    }
+
+    public boolean isSuccess() {
+      return this.success;
+    }
+
+    public replicateData_result setSuccess(boolean success) {
+      this.success = success;
+      setSuccessIsSet(true);
+      return this;
+    }
+
+    public void unsetSuccess() {
+      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
+    }
+
+    /** Returns true if field success is set (has been assigned a value) and false otherwise */
+    public boolean isSetSuccess() {
+      return EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
+    }
+
+    public void setSuccessIsSet(boolean value) {
+      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
+    }
+
+    public org.apache.accumulo.core.client.impl.thrift.ThriftSecurityException getSec() {
+      return this.sec;
+    }
+
+    public replicateData_result setSec(org.apache.accumulo.core.client.impl.thrift.ThriftSecurityException sec) {
+      this.sec = sec;
+      return this;
+    }
+
+    public void unsetSec() {
+      this.sec = null;
+    }
+
+    /** Returns true if field sec is set (has been assigned a value) and false otherwise */
+    public boolean isSetSec() {
+      return this.sec != null;
+    }
+
+    public void setSecIsSet(boolean value) {
+      if (!value) {
+        this.sec = null;
+      }
+    }
+
+    public ReplicationFailedException getRfe() {
+      return this.rfe;
+    }
+
+    public replicateData_result setRfe(ReplicationFailedException rfe) {
+      this.rfe = rfe;
+      return this;
+    }
+
+    public void unsetRfe() {
+      this.rfe = null;
+    }
+
+    /** Returns true if field rfe is set (has been assigned a value) and false otherwise */
+    public boolean isSetRfe() {
+      return this.rfe != null;
+    }
+
+    public void setRfeIsSet(boolean value) {
+      if (!value) {
+        this.rfe = null;
+      }
+    }
+
+    public void setFieldValue(_Fields field, Object value) {
+      switch (field) {
+      case SUCCESS:
+        if (value == null) {
+          unsetSuccess();
+        } else {
+          setSuccess((Boolean)value);
+        }
+        break;
+
+      case SEC:
+        if (value == null) {
+          unsetSec();
+        } else {
+          setSec((org.apache.accumulo.core.client.impl.thrift.ThriftSecurityException)value);
+        }
+        break;
+
+      case RFE:
+        if (value == null) {
+          unsetRfe();
+        } else {
+          setRfe((ReplicationFailedException)value);
+        }
+        break;
+
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      case SUCCESS:
+        return Boolean.valueOf(isSuccess());
+
+      case SEC:
+        return getSec();
+
+      case RFE:
+        return getRfe();
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case SUCCESS:
+        return isSetSuccess();
+      case SEC:
+        return isSetSec();
+      case RFE:
+        return isSetRfe();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof replicateData_result)
+        return this.equals((replicateData_result)that);
+      return false;
+    }
+
+    public boolean equals(replicateData_result that) {
+      if (that == null)
+        return false;
+
+      boolean this_present_success = true;
+      boolean that_present_success = true;
+      if (this_present_success || that_present_success) {
+        if (!(this_present_success && that_present_success))
+          return false;
+        if (this.success != that.success)
+          return false;
+      }
+
+      boolean this_present_sec = true && this.isSetSec();
+      boolean that_present_sec = true && that.isSetSec();
+      if (this_present_sec || that_present_sec) {
+        if (!(this_present_sec && that_present_sec))
+          return false;
+        if (!this.sec.equals(that.sec))
+          return false;
+      }
+
+      boolean this_present_rfe = true && this.isSetRfe();
+      boolean that_present_rfe = true && that.isSetRfe();
+      if (this_present_rfe || that_present_rfe) {
+        if (!(this_present_rfe && that_present_rfe))
+          return false;
+        if (!this.rfe.equals(that.rfe))
+          return false;
+      }
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      return 0;
+    }
+
+    public int compareTo(replicateData_result other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+      replicateData_result typedOther = (replicateData_result)other;
+
+      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(typedOther.isSetSuccess());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetSuccess()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, typedOther.success);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetSec()).compareTo(typedOther.isSetSec());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetSec()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sec, typedOther.sec);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetRfe()).compareTo(typedOther.isSetRfe());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetRfe()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.rfe, typedOther.rfe);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      return 0;
+    }
+
+    public _Fields fieldForId(int fieldId) {
+      return _Fields.findByThriftId(fieldId);
+    }
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
+      }
+
+    @Override
+    public String toString() {
+      StringBuilder sb = new StringBuilder("replicateData_result(");
+      boolean first = true;
+
+      sb.append("success:");
+      sb.append(this.success);
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("sec:");
+      if (this.sec == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.sec);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("rfe:");
+      if (this.rfe == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.rfe);
+      }
+      first = false;
+      sb.append(")");
+      return sb.toString();
+    }
+
+    public void validate() throws org.apache.thrift.TException {
+      // check for required fields
+      // check for sub-struct validity
+    }
+
+    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+      try {
+        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+      try {
+        // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor.
+        __isset_bitfield = 0;
+        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private static class replicateData_resultStandardSchemeFactory implements SchemeFactory {
+      public replicateData_resultStandardScheme getScheme() {
+        return new replicateData_resultStandardScheme();
+      }
+    }
+
+    private static class replicateData_resultStandardScheme extends StandardScheme<replicateData_result> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, replicateData_result struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TField schemeField;
+        iprot.readStructBegin();
+        while (true)
+        {
+          schemeField = iprot.readFieldBegin();
+          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+            break;
+          }
+          switch (schemeField.id) {
+            case 0: // SUCCESS
+              if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
+                struct.success = iprot.readBool();
+                struct.setSuccessIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 1: // SEC
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.sec = new org.apache.accumulo.core.client.impl.thrift.ThriftSecurityException();
+                struct.sec.read(iprot);
+                struct.setSecIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 2: // RFE
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.rfe = new ReplicationFailedException();
+                struct.rfe.read(iprot);
+                struct.setRfeIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            default:
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+          }
+          iprot.readFieldEnd();
+        }
+        iprot.readStructEnd();
+
+        // check for required fields of primitive type, which can't be checked in the validate method
+        struct.validate();
+      }
+
+      public void write(org.apache.thrift.protocol.TProtocol oprot, replicateData_result struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        if (struct.isSetSuccess()) {
+          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
+          oprot.writeBool(struct.success);
+          oprot.writeFieldEnd();
+        }
+        if (struct.sec != null) {
+          oprot.writeFieldBegin(SEC_FIELD_DESC);
+          struct.sec.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        if (struct.rfe != null) {
+          oprot.writeFieldBegin(RFE_FIELD_DESC);
+          struct.rfe.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        oprot.writeFieldStop();
+        oprot.writeStructEnd();
+      }
+
+    }
+
+    private static class replicateData_resultTupleSchemeFactory implements SchemeFactory {
+      public replicateData_resultTupleScheme getScheme() {
+        return new replicateData_resultTupleScheme();
+      }
+    }
+
+    private static class replicateData_resultTupleScheme extends TupleScheme<replicateData_result> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, replicateData_result struct) throws org.apache.thrift.TException {
+        TTupleProtocol oprot = (TTupleProtocol) prot;
+        BitSet optionals = new BitSet();
+        if (struct.isSetSuccess()) {
+          optionals.set(0);
+        }
+        if (struct.isSetSec()) {
+          optionals.set(1);
+        }
+        if (struct.isSetRfe()) {
+          optionals.set(2);
+        }
+        oprot.writeBitSet(optionals, 3);
+        if (struct.isSetSuccess()) {
+          oprot.writeBool(struct.success);
+        }
+        if (struct.isSetSec()) {
+          struct.sec.write(oprot);
+        }
+        if (struct.isSetRfe()) {
+          struct.rfe.write(oprot);
+        }
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, replicateData_result struct) throws org.apache.thrift.TException {
+        TTupleProtocol iprot = (TTupleProtocol) prot;
+        BitSet incoming = iprot.readBitSet(3);
+        if (incoming.get(0)) {
+          struct.success = iprot.readBool();
+          struct.setSuccessIsSet(true);
+        }
+        if (incoming.get(1)) {
+          struct.sec = new org.apache.accumulo.core.client.impl.thrift.ThriftSecurityException();
+          struct.sec.read(iprot);
+          struct.setSecIsSet(true);
+        }
+        if (incoming.get(2)) {
+          struct.rfe = new ReplicationFailedException();
+          struct.rfe.read(iprot);
+          struct.setRfeIsSet(true);
+        }
+      }
+    }
+
+  }
+
 }

http://git-wip-us.apache.org/repos/asf/accumulo/blob/d257001d/core/src/main/scripts/generate-thrift.sh
----------------------------------------------------------------------
diff --git a/core/src/main/scripts/generate-thrift.sh b/core/src/main/scripts/generate-thrift.sh
index 5a5d69f..ee51b11 100755
--- a/core/src/main/scripts/generate-thrift.sh
+++ b/core/src/main/scripts/generate-thrift.sh
@@ -29,7 +29,7 @@
 [ -z $REQUIRED_THRIFT_VERSION ] && REQUIRED_THRIFT_VERSION='0.9'
 [ -z $INCLUDED_MODULES ]        && INCLUDED_MODULES=(../trace)
 [ -z $BASE_OUTPUT_PACKAGE ]     && BASE_OUTPUT_PACKAGE='org.apache.accumulo.core'
-[ -z $PACKAGES_TO_GENERATE ]    && PACKAGES_TO_GENERATE=(gc master tabletserver security client.impl data)
+[ -z $PACKAGES_TO_GENERATE ]    && PACKAGES_TO_GENERATE=(gc master tabletserver security client.impl data replication)
 [ -z $BUILD_DIR ]               && BUILD_DIR='target'
 [ -z $LANGUAGES_TO_GENERATE ]   && LANGUAGES_TO_GENERATE=(java)
 [ -z $FINAL_DIR ]               && FINAL_DIR='src/main'

http://git-wip-us.apache.org/repos/asf/accumulo/blob/d257001d/core/src/main/thrift/replication.thrift
----------------------------------------------------------------------
diff --git a/core/src/main/thrift/replication.thrift b/core/src/main/thrift/replication.thrift
new file mode 100644
index 0000000..a71d200
--- /dev/null
+++ b/core/src/main/thrift/replication.thrift
@@ -0,0 +1,39 @@
+/*
+* 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.
+*/
+
+namespace java org.apache.accumulo.core.replication.thrift
+namespace cpp org.apache.accumulo.core.replication.thrift
+
+include "data.thrift"
+
+struct WalEdits {
+    1:list<binary> edits
+}
+
+struct KeyValues {
+    1:list<data.TKeyValue> keyValues
+}
+
+exception RemoteReplicationException {
+    1:i32 code,
+    2:string reason
+}
+
+service RemoteReplication {
+    void replicateLog(1:i32 remoteTableId, 2:WalEdits data) throws (1:RemoteReplicationException e),
+    void replicateKeyValues(1:i32 remoteTableId, 2:KeyValues data) throws (1:RemoteReplicationException e)
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/accumulo/blob/d257001d/core/src/main/thrift/tabletserver.thrift
----------------------------------------------------------------------
diff --git a/core/src/main/thrift/tabletserver.thrift b/core/src/main/thrift/tabletserver.thrift
index 25e0b10..8f85ab3 100644
--- a/core/src/main/thrift/tabletserver.thrift
+++ b/core/src/main/thrift/tabletserver.thrift
@@ -38,6 +38,10 @@ exception ConstraintViolationException {
   1:list<data.TConstraintViolationSummary> violationSummaries
 }
 
+exception ReplicationFailedException {
+  1:string reason
+}
+
 struct ActionStats {
     1:i32 status
     2:double elapsed
@@ -197,6 +201,8 @@ service TabletClientService extends client.ClientService {
   list<ActiveScan> getActiveScans(2:trace.TInfo tinfo, 1:security.TCredentials credentials) throws (1:client.ThriftSecurityException sec)
   list<ActiveCompaction> getActiveCompactions(2:trace.TInfo tinfo, 1:security.TCredentials credentials) throws (1:client.ThriftSecurityException sec)
   oneway void removeLogs(1:trace.TInfo tinfo, 2:security.TCredentials credentials, 3:list<string> filenames)
+
+  bool replicateData(1:trace.TInfo tinfo, 2:security.TCredentials credentials, 3:string file, 4:i64 offset, 5:i64 count) throws (1:client.ThriftSecurityException sec, 2:ReplicationFailedException rfe) 
 }
 
 typedef i32 TabletID

http://git-wip-us.apache.org/repos/asf/accumulo/blob/d257001d/server/tserver/src/main/java/org/apache/accumulo/tserver/TabletServer.java
----------------------------------------------------------------------
diff --git a/server/tserver/src/main/java/org/apache/accumulo/tserver/TabletServer.java b/server/tserver/src/main/java/org/apache/accumulo/tserver/TabletServer.java
index 9a4b46f..b14c13b 100644
--- a/server/tserver/src/main/java/org/apache/accumulo/tserver/TabletServer.java
+++ b/server/tserver/src/main/java/org/apache/accumulo/tserver/TabletServer.java
@@ -125,6 +125,7 @@ import org.apache.accumulo.core.tabletserver.thrift.ActiveScan;
 import org.apache.accumulo.core.tabletserver.thrift.ConstraintViolationException;
 import org.apache.accumulo.core.tabletserver.thrift.NoSuchScanIDException;
 import org.apache.accumulo.core.tabletserver.thrift.NotServingTabletException;
+import org.apache.accumulo.core.tabletserver.thrift.ReplicationFailedException;
 import org.apache.accumulo.core.tabletserver.thrift.ScanState;
 import org.apache.accumulo.core.tabletserver.thrift.ScanType;
 import org.apache.accumulo.core.tabletserver.thrift.TabletClientService;
@@ -222,6 +223,7 @@ import org.apache.accumulo.tserver.metrics.TabletServerMinCMetrics;
 import org.apache.accumulo.tserver.metrics.TabletServerScanMetrics;
 import org.apache.accumulo.tserver.metrics.TabletServerUpdateMetrics;
 import org.apache.commons.collections.map.LRUMap;
+import org.apache.commons.lang.NotImplementedException;
 import org.apache.hadoop.fs.FSError;
 import org.apache.hadoop.fs.FileSystem;
 import org.apache.hadoop.fs.Path;
@@ -2542,6 +2544,13 @@ public class TabletServer extends AbstractMetricsImpl implements org.apache.accu
 
       return ret;
     }
+
+    @Override
+    public boolean replicateData(TInfo tinfo, TCredentials credentials, String file, long offset, long count) throws ThriftSecurityException,
+        ReplicationFailedException, TException {
+      // TODO ACCUMULO-2581
+      throw new UnsupportedOperationException("Not yet implemented");
+    }
   }
 
   private class SplitRunner implements Runnable {


[17/53] [abbrv] git commit: ACCUMULO-2648 Make AccumuloInputFormat use correct RangeInputSplit

Posted by el...@apache.org.
ACCUMULO-2648 Make AccumuloInputFormat use correct RangeInputSplit


Project: http://git-wip-us.apache.org/repos/asf/accumulo/repo
Commit: http://git-wip-us.apache.org/repos/asf/accumulo/commit/e33c1f49
Tree: http://git-wip-us.apache.org/repos/asf/accumulo/tree/e33c1f49
Diff: http://git-wip-us.apache.org/repos/asf/accumulo/diff/e33c1f49

Branch: refs/heads/ACCUMULO-378
Commit: e33c1f4951faac982acc48f18a0e1256c1d11ea5
Parents: 7ffa80a
Author: Christopher Tubbs <ct...@apache.org>
Authored: Mon Apr 7 20:06:31 2014 -0400
Committer: Christopher Tubbs <ct...@apache.org>
Committed: Mon Apr 7 20:06:31 2014 -0400

----------------------------------------------------------------------
 .../apache/accumulo/core/client/mapred/InputFormatBase.java    | 1 +
 .../accumulo/core/client/mapreduce/AccumuloInputFormat.java    | 6 +++---
 .../apache/accumulo/core/client/mapreduce/InputFormatBase.java | 5 +++--
 .../core/client/mapreduce/EmptySplitsAccumuloInputFormat.java  | 6 +++---
 4 files changed, 10 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/accumulo/blob/e33c1f49/core/src/main/java/org/apache/accumulo/core/client/mapred/InputFormatBase.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/client/mapred/InputFormatBase.java b/core/src/main/java/org/apache/accumulo/core/client/mapred/InputFormatBase.java
index 0438b78..16efa89 100644
--- a/core/src/main/java/org/apache/accumulo/core/client/mapred/InputFormatBase.java
+++ b/core/src/main/java/org/apache/accumulo/core/client/mapred/InputFormatBase.java
@@ -909,6 +909,7 @@ public abstract class InputFormatBase<K,V> implements InputFormat<K,V> {
   }
 
   /**
+   * @deprecated since 1.5.2; Use {@link org.apache.accumulo.core.client.mapred.RangeInputSplit} instead.
    * @see org.apache.accumulo.core.client.mapred.RangeInputSplit
    */
   @Deprecated

http://git-wip-us.apache.org/repos/asf/accumulo/blob/e33c1f49/core/src/main/java/org/apache/accumulo/core/client/mapreduce/AccumuloInputFormat.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/client/mapreduce/AccumuloInputFormat.java b/core/src/main/java/org/apache/accumulo/core/client/mapreduce/AccumuloInputFormat.java
index 0220339..c08b50b 100644
--- a/core/src/main/java/org/apache/accumulo/core/client/mapreduce/AccumuloInputFormat.java
+++ b/core/src/main/java/org/apache/accumulo/core/client/mapreduce/AccumuloInputFormat.java
@@ -50,10 +50,10 @@ public class AccumuloInputFormat extends InputFormatBase<Key,Value> {
   @Override
   public RecordReader<Key,Value> createRecordReader(InputSplit split, TaskAttemptContext context) throws IOException, InterruptedException {
     log.setLevel(getLogLevel(context));
-    
+
     // Override the log level from the configuration as if the RangeInputSplit has one it's the more correct one to use.
-    if (split instanceof RangeInputSplit) {
-      RangeInputSplit risplit = (RangeInputSplit) split;
+    if (split instanceof org.apache.accumulo.core.client.mapreduce.RangeInputSplit) {
+      org.apache.accumulo.core.client.mapreduce.RangeInputSplit risplit = (org.apache.accumulo.core.client.mapreduce.RangeInputSplit) split;
       Level level = risplit.getLogLevel();
       if (null != level) {
         log.setLevel(level);

http://git-wip-us.apache.org/repos/asf/accumulo/blob/e33c1f49/core/src/main/java/org/apache/accumulo/core/client/mapreduce/InputFormatBase.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/client/mapreduce/InputFormatBase.java b/core/src/main/java/org/apache/accumulo/core/client/mapreduce/InputFormatBase.java
index 5066620..0e9444d 100644
--- a/core/src/main/java/org/apache/accumulo/core/client/mapreduce/InputFormatBase.java
+++ b/core/src/main/java/org/apache/accumulo/core/client/mapreduce/InputFormatBase.java
@@ -1198,8 +1198,8 @@ public abstract class InputFormatBase<K,V> extends InputFormat<K,V> {
       for (Entry<String,String> opt : setting.getOptions().entrySet()) {
         String deprecatedOption;
         try {
-          deprecatedOption = setting.getName() + AccumuloIteratorOption.FIELD_SEP + URLEncoder.encode(opt.getKey(), "UTF-8")
-              + AccumuloIteratorOption.FIELD_SEP + URLEncoder.encode(opt.getValue(), "UTF-8");
+          deprecatedOption = setting.getName() + AccumuloIteratorOption.FIELD_SEP + URLEncoder.encode(opt.getKey(), "UTF-8") + AccumuloIteratorOption.FIELD_SEP
+              + URLEncoder.encode(opt.getValue(), "UTF-8");
         } catch (UnsupportedEncodingException e) {
           throw new RuntimeException(e);
         }
@@ -1320,6 +1320,7 @@ public abstract class InputFormatBase<K,V> extends InputFormat<K,V> {
   }
 
   /**
+   * @deprecated since 1.5.2; Use {@link org.apache.accumulo.core.client.mapreduce.RangeInputSplit} instead.
    * @see org.apache.accumulo.core.client.mapreduce.RangeInputSplit
    */
   @Deprecated

http://git-wip-us.apache.org/repos/asf/accumulo/blob/e33c1f49/core/src/test/java/org/apache/accumulo/core/client/mapreduce/EmptySplitsAccumuloInputFormat.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/accumulo/core/client/mapreduce/EmptySplitsAccumuloInputFormat.java b/core/src/test/java/org/apache/accumulo/core/client/mapreduce/EmptySplitsAccumuloInputFormat.java
index 440dbf7..68ac78f 100644
--- a/core/src/test/java/org/apache/accumulo/core/client/mapreduce/EmptySplitsAccumuloInputFormat.java
+++ b/core/src/test/java/org/apache/accumulo/core/client/mapreduce/EmptySplitsAccumuloInputFormat.java
@@ -27,11 +27,11 @@ import org.apache.hadoop.mapreduce.JobContext;
  * AccumuloInputFormat which returns an "empty" RangeInputSplit
  */
 public class EmptySplitsAccumuloInputFormat extends AccumuloInputFormat {
-  
+
   @Override
   public List<InputSplit> getSplits(JobContext context) throws IOException {
     super.getSplits(context);
-    
-    return Arrays.<InputSplit> asList(new RangeInputSplit());
+
+    return Arrays.<InputSplit> asList(new org.apache.accumulo.core.client.mapreduce.RangeInputSplit());
   }
 }


[09/53] [abbrv] ACCUMULO-1897 Move shell into new package and module

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SetIterCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SetIterCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SetIterCommand.java
deleted file mode 100644
index 3d8a5a7..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SetIterCommand.java
+++ /dev/null
@@ -1,453 +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.accumulo.core.util.shell.commands;
-
-import java.io.IOException;
-import java.util.EnumSet;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Map.Entry;
-
-import jline.console.ConsoleReader;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.IteratorSetting;
-import org.apache.accumulo.core.client.NamespaceNotFoundException;
-import org.apache.accumulo.core.client.TableNotFoundException;
-import org.apache.accumulo.core.conf.Property;
-import org.apache.accumulo.core.data.Key;
-import org.apache.accumulo.core.data.Value;
-import org.apache.accumulo.core.iterators.IteratorUtil.IteratorScope;
-import org.apache.accumulo.core.iterators.OptionDescriber;
-import org.apache.accumulo.core.iterators.OptionDescriber.IteratorOptions;
-import org.apache.accumulo.core.iterators.SortedKeyValueIterator;
-import org.apache.accumulo.core.iterators.user.AgeOffFilter;
-import org.apache.accumulo.core.iterators.user.RegExFilter;
-import org.apache.accumulo.core.iterators.user.ReqVisFilter;
-import org.apache.accumulo.core.iterators.user.VersioningIterator;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.accumulo.core.util.shell.ShellCommandException;
-import org.apache.accumulo.core.util.shell.ShellCommandException.ErrorCode;
-import org.apache.accumulo.start.classloader.vfs.AccumuloVFSClassLoader;
-import org.apache.accumulo.start.classloader.vfs.ContextManager;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.OptionGroup;
-import org.apache.commons.cli.Options;
-import org.apache.commons.lang.StringUtils;
-import org.apache.commons.vfs2.FileSystemException;
-
-public class SetIterCommand extends Command {
-
-  private Option allScopeOpt, mincScopeOpt, majcScopeOpt, scanScopeOpt, nameOpt, priorityOpt;
-  private Option aggTypeOpt, ageoffTypeOpt, regexTypeOpt, versionTypeOpt, reqvisTypeOpt, classnameTypeOpt;
-
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException,
-      TableNotFoundException, IOException, ShellCommandException {
-
-    boolean tables = cl.hasOption(OptUtil.tableOpt().getOpt()) || !shellState.getTableName().isEmpty();
-    boolean namespaces = cl.hasOption(OptUtil.namespaceOpt().getOpt());
-
-    final int priority = Integer.parseInt(cl.getOptionValue(priorityOpt.getOpt()));
-
-    final Map<String,String> options = new HashMap<String,String>();
-    String classname = cl.getOptionValue(classnameTypeOpt.getOpt());
-    if (cl.hasOption(aggTypeOpt.getOpt())) {
-      Shell.log.warn("aggregators are deprecated");
-      @SuppressWarnings("deprecation")
-      String deprecatedClassName = org.apache.accumulo.core.iterators.AggregatingIterator.class.getName();
-      classname = deprecatedClassName;
-    } else if (cl.hasOption(regexTypeOpt.getOpt())) {
-      classname = RegExFilter.class.getName();
-    } else if (cl.hasOption(ageoffTypeOpt.getOpt())) {
-      classname = AgeOffFilter.class.getName();
-    } else if (cl.hasOption(versionTypeOpt.getOpt())) {
-      classname = VersioningIterator.class.getName();
-    } else if (cl.hasOption(reqvisTypeOpt.getOpt())) {
-      classname = ReqVisFilter.class.getName();
-    }
-
-    ClassLoader classloader = getClassLoader(cl, shellState);
-
-    // Get the iterator options, with potentially a name provided by the OptionDescriber impl or through user input
-    String configuredName = setUpOptions(classloader, shellState.getReader(), classname, options);
-
-    // Try to get the name provided by the setiter command
-    String name = cl.getOptionValue(nameOpt.getOpt(), null);
-    
-    // Cannot continue if no name is provided
-    if (null == name && null == configuredName) {
-      throw new IllegalArgumentException("No provided or default name for iterator");
-    } else if (null == name) {
-      // Fall back to the name from OptionDescriber or user input if none is provided on setiter option
-      name = configuredName;
-    }
-
-    if (namespaces) {
-      try {
-        setNamespaceProperties(cl, shellState, priority, options, classname, name);
-      } catch (NamespaceNotFoundException e) {
-        throw new IllegalArgumentException(e);
-      }
-    } else if (tables) {
-      setTableProperties(cl, shellState, priority, options, classname, name);
-    } else {
-      throw new IllegalArgumentException("No table or namespace specified");
-    }
-    return 0;
-  }
-
-  private ClassLoader getClassLoader(final CommandLine cl, final Shell shellState) throws AccumuloException, TableNotFoundException, AccumuloSecurityException,
-      IOException, FileSystemException {
-
-    boolean tables = cl.hasOption(OptUtil.tableOpt().getOpt()) || !shellState.getTableName().isEmpty();
-    boolean namespaces = cl.hasOption(OptUtil.namespaceOpt().getOpt());
-
-    String classpath = null;
-    Iterable<Entry<String,String>> tableProps;
-
-    if (namespaces) {
-      try {
-        tableProps = shellState.getConnector().namespaceOperations().getProperties(OptUtil.getNamespaceOpt(cl, shellState));
-      } catch (NamespaceNotFoundException e) {
-        throw new IllegalArgumentException(e);
-      }
-    } else if (tables) {
-      tableProps = shellState.getConnector().tableOperations().getProperties(OptUtil.getTableOpt(cl, shellState));
-    } else {
-      throw new IllegalArgumentException("No table or namespace specified");
-    }
-    for (Entry<String,String> entry : tableProps) {
-      if (entry.getKey().equals(Property.TABLE_CLASSPATH.getKey())) {
-        classpath = entry.getValue();
-      }
-    }
-
-    ClassLoader classloader;
-
-    if (classpath != null && !classpath.equals("")) {
-      shellState.getConnector().instanceOperations().getSystemConfiguration().get(Property.VFS_CONTEXT_CLASSPATH_PROPERTY.getKey() + classpath);
-
-      try {
-        AccumuloVFSClassLoader.getContextManager().setContextConfig(new ContextManager.DefaultContextsConfig(new Iterable<Map.Entry<String,String>>() {
-          @Override
-          public Iterator<Entry<String,String>> iterator() {
-            try {
-              return shellState.getConnector().instanceOperations().getSystemConfiguration().entrySet().iterator();
-            } catch (AccumuloException e) {
-              throw new RuntimeException(e);
-            } catch (AccumuloSecurityException e) {
-              throw new RuntimeException(e);
-            }
-          }
-        }));
-      } catch (IllegalStateException ise) {}
-
-      classloader = AccumuloVFSClassLoader.getContextManager().getClassLoader(classpath);
-    } else {
-      classloader = AccumuloVFSClassLoader.getClassLoader();
-    }
-    return classloader;
-  }
-
-  protected void setTableProperties(final CommandLine cl, final Shell shellState, final int priority, final Map<String,String> options, final String classname,
-      final String name) throws AccumuloException, AccumuloSecurityException, ShellCommandException, TableNotFoundException {
-    // remove empty values
-
-    final String tableName = OptUtil.getTableOpt(cl, shellState);
-
-    if (!shellState.getConnector().tableOperations().testClassLoad(tableName, classname, SortedKeyValueIterator.class.getName())) {
-      throw new ShellCommandException(ErrorCode.INITIALIZATION_FAILURE, "Servers are unable to load " + classname + " as type "
-          + SortedKeyValueIterator.class.getName());
-    }
-
-    final String aggregatorClass = options.get("aggregatorClass");
-    @SuppressWarnings("deprecation")
-    String deprecatedAggregatorClassName = org.apache.accumulo.core.iterators.aggregation.Aggregator.class.getName();
-    if (aggregatorClass != null && !shellState.getConnector().tableOperations().testClassLoad(tableName, aggregatorClass, deprecatedAggregatorClassName)) {
-      throw new ShellCommandException(ErrorCode.INITIALIZATION_FAILURE, "Servers are unable to load " + aggregatorClass + " as type "
-          + deprecatedAggregatorClassName);
-    }
-
-    for (Iterator<Entry<String,String>> i = options.entrySet().iterator(); i.hasNext();) {
-      final Entry<String,String> entry = i.next();
-      if (entry.getValue() == null || entry.getValue().isEmpty()) {
-        i.remove();
-      }
-    }
-    final EnumSet<IteratorScope> scopes = EnumSet.noneOf(IteratorScope.class);
-    if (cl.hasOption(allScopeOpt.getOpt()) || cl.hasOption(mincScopeOpt.getOpt())) {
-      scopes.add(IteratorScope.minc);
-    }
-    if (cl.hasOption(allScopeOpt.getOpt()) || cl.hasOption(majcScopeOpt.getOpt())) {
-      scopes.add(IteratorScope.majc);
-    }
-    if (cl.hasOption(allScopeOpt.getOpt()) || cl.hasOption(scanScopeOpt.getOpt())) {
-      scopes.add(IteratorScope.scan);
-    }
-    if (scopes.isEmpty()) {
-      throw new IllegalArgumentException("You must select at least one scope to configure");
-    }
-    final IteratorSetting setting = new IteratorSetting(priority, name, classname, options);
-    shellState.getConnector().tableOperations().attachIterator(tableName, setting, scopes);
-  }
-
-  protected void setNamespaceProperties(final CommandLine cl, final Shell shellState, final int priority, final Map<String,String> options,
-      final String classname, final String name) throws AccumuloException, AccumuloSecurityException, ShellCommandException, NamespaceNotFoundException {
-    // remove empty values
-
-    final String namespace = OptUtil.getNamespaceOpt(cl, shellState);
-
-    if (!shellState.getConnector().namespaceOperations().testClassLoad(namespace, classname, SortedKeyValueIterator.class.getName())) {
-      throw new ShellCommandException(ErrorCode.INITIALIZATION_FAILURE, "Servers are unable to load " + classname + " as type "
-          + SortedKeyValueIterator.class.getName());
-    }
-
-    final String aggregatorClass = options.get("aggregatorClass");
-    @SuppressWarnings("deprecation")
-    String deprecatedAggregatorClassName = org.apache.accumulo.core.iterators.aggregation.Aggregator.class.getName();
-    if (aggregatorClass != null && !shellState.getConnector().namespaceOperations().testClassLoad(namespace, aggregatorClass, deprecatedAggregatorClassName)) {
-      throw new ShellCommandException(ErrorCode.INITIALIZATION_FAILURE, "Servers are unable to load " + aggregatorClass + " as type "
-          + deprecatedAggregatorClassName);
-    }
-
-    for (Iterator<Entry<String,String>> i = options.entrySet().iterator(); i.hasNext();) {
-      final Entry<String,String> entry = i.next();
-      if (entry.getValue() == null || entry.getValue().isEmpty()) {
-        i.remove();
-      }
-    }
-    final EnumSet<IteratorScope> scopes = EnumSet.noneOf(IteratorScope.class);
-    if (cl.hasOption(allScopeOpt.getOpt()) || cl.hasOption(mincScopeOpt.getOpt())) {
-      scopes.add(IteratorScope.minc);
-    }
-    if (cl.hasOption(allScopeOpt.getOpt()) || cl.hasOption(majcScopeOpt.getOpt())) {
-      scopes.add(IteratorScope.majc);
-    }
-    if (cl.hasOption(allScopeOpt.getOpt()) || cl.hasOption(scanScopeOpt.getOpt())) {
-      scopes.add(IteratorScope.scan);
-    }
-    if (scopes.isEmpty()) {
-      throw new IllegalArgumentException("You must select at least one scope to configure");
-    }
-    final IteratorSetting setting = new IteratorSetting(priority, name, classname, options);
-    shellState.getConnector().namespaceOperations().attachIterator(namespace, setting, scopes);
-  }
-
-  private static String setUpOptions(ClassLoader classloader, final ConsoleReader reader, final String className, final Map<String,String> options)
-      throws IOException, ShellCommandException {
-    String input;
-    @SuppressWarnings("rawtypes")
-    SortedKeyValueIterator untypedInstance;
-    @SuppressWarnings("rawtypes")
-    Class<? extends SortedKeyValueIterator> clazz;
-    try {
-      clazz = classloader.loadClass(className).asSubclass(SortedKeyValueIterator.class);
-      untypedInstance = clazz.newInstance();
-    } catch (ClassNotFoundException e) {
-      StringBuilder msg = new StringBuilder("Unable to load ").append(className);
-      if (className.indexOf('.') < 0) {
-        msg.append("; did you use a fully qualified package name?");
-      } else {
-        msg.append("; class not found.");
-      }
-      throw new ShellCommandException(ErrorCode.INITIALIZATION_FAILURE, msg.toString());
-    } catch (InstantiationException e) {
-      throw new IllegalArgumentException(e.getMessage());
-    } catch (IllegalAccessException e) {
-      throw new IllegalArgumentException(e.getMessage());
-    } catch (ClassCastException e) {
-      StringBuilder msg = new StringBuilder(50);
-      msg.append(className).append(" loaded successfully but does not implement SortedKeyValueIterator.");
-      msg.append(" This class cannot be used with this command.");
-      throw new ShellCommandException(ErrorCode.INITIALIZATION_FAILURE, msg.toString());
-    }
-
-    @SuppressWarnings("unchecked")
-    SortedKeyValueIterator<Key,Value> skvi = (SortedKeyValueIterator<Key,Value>) untypedInstance;
-    OptionDescriber iterOptions = null;
-    if (OptionDescriber.class.isAssignableFrom(skvi.getClass())) {
-      iterOptions = (OptionDescriber) skvi;
-    }
-
-    String iteratorName;
-    if (null != iterOptions) {
-      final IteratorOptions itopts = iterOptions.describeOptions();
-      iteratorName = itopts.getName();
-      
-      if (iteratorName == null) {
-        throw new IllegalArgumentException(className + " described its default distinguishing name as null");
-      }
-      String shortClassName = className;
-      if (className.contains(".")) {
-        shortClassName = className.substring(className.lastIndexOf('.') + 1);
-      }
-      final Map<String,String> localOptions = new HashMap<String,String>();
-      do {
-        // clean up the overall options that caused things to fail
-        for (String key : localOptions.keySet()) {
-          options.remove(key);
-        }
-        localOptions.clear();
-  
-        reader.println(itopts.getDescription());
-  
-        String prompt;
-        if (itopts.getNamedOptions() != null) {
-          for (Entry<String,String> e : itopts.getNamedOptions().entrySet()) {
-            prompt = Shell.repeat("-", 10) + "> set " + shortClassName + " parameter " + e.getKey() + ", " + e.getValue() + ": ";
-            reader.flush();
-            input = reader.readLine(prompt);
-            if (input == null) {
-              reader.println();
-              throw new IOException("Input stream closed");
-            }
-            // Places all Parameters and Values into the LocalOptions, even if the value is "".
-            // This allows us to check for "" values when setting the iterators and allows us to remove
-            // the parameter and value from the table property.
-            localOptions.put(e.getKey(), input);
-          }
-        }
-  
-        if (itopts.getUnnamedOptionDescriptions() != null) {
-          for (String desc : itopts.getUnnamedOptionDescriptions()) {
-            reader.println(Shell.repeat("-", 10) + "> entering options: " + desc);
-            input = "start";
-            prompt = Shell.repeat("-", 10) + "> set " + shortClassName + " option (<name> <value>, hit enter to skip): ";
-            while (true) {
-              reader.flush();
-              input = reader.readLine(prompt);
-              if (input == null) {
-                reader.println();
-                throw new IOException("Input stream closed");
-              } else {
-                input = new String(input);
-              }
-  
-              if (input.length() == 0)
-                break;
-  
-              String[] sa = input.split(" ", 2);
-              localOptions.put(sa[0], sa[1]);
-            }
-          }
-        }
-  
-        options.putAll(localOptions);
-        if (!iterOptions.validateOptions(options))
-          reader.println("invalid options for " + clazz.getName());
-  
-      } while (!iterOptions.validateOptions(options));
-    } else {
-      reader.flush();
-      reader.println("The iterator class does not implement OptionDescriber. Consider this for better iterator configuration using this setiter command.");
-      iteratorName = reader.readLine("Name for iterator (enter to skip): ");
-      if (null == iteratorName) {
-        reader.println();
-        throw new IOException("Input stream closed");
-      } else if (StringUtils.isWhitespace(iteratorName)) {
-        // Treat whitespace or empty string as no name provided
-        iteratorName = null;
-      }
-      
-      reader.flush();
-      reader.println("Optional, configure name-value options for iterator:");
-      String prompt = Shell.repeat("-", 10) + "> set option (<name> <value>, hit enter to skip): ";
-      final HashMap<String,String> localOptions = new HashMap<String,String>();
-      
-      while (true) {
-        reader.flush();
-        input = reader.readLine(prompt);
-        if (input == null) {
-          reader.println();
-          throw new IOException("Input stream closed");
-        } else if (StringUtils.isWhitespace(input)) {
-          break;
-        } 
-
-        String[] sa = input.split(" ", 2);
-        localOptions.put(sa[0], sa[1]);
-      }
-      
-      options.putAll(localOptions);
-    }
-    
-    return iteratorName;
-  }
-
-  @Override
-  public String description() {
-    return "sets a table-specific or namespace-specific iterator";
-  }
-
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-
-    priorityOpt = new Option("p", "priority", true, "the order in which the iterator is applied");
-    priorityOpt.setArgName("pri");
-    priorityOpt.setRequired(true);
-
-    nameOpt = new Option("n", "name", true, "iterator to set");
-    nameOpt.setArgName("itername");
-
-    allScopeOpt = new Option("all", "all-scopes", false, "applied at scan time, minor and major compactions");
-    mincScopeOpt = new Option(IteratorScope.minc.name(), "minor-compaction", false, "applied at minor compaction");
-    majcScopeOpt = new Option(IteratorScope.majc.name(), "major-compaction", false, "applied at major compaction");
-    scanScopeOpt = new Option(IteratorScope.scan.name(), "scan-time", false, "applied at scan time");
-
-    final OptionGroup typeGroup = new OptionGroup();
-    classnameTypeOpt = new Option("class", "class-name", true, "a java class that implements SortedKeyValueIterator");
-    classnameTypeOpt.setArgName("name");
-    aggTypeOpt = new Option("agg", "aggregator", false, "an aggregating type");
-    regexTypeOpt = new Option("regex", "regular-expression", false, "a regex matching iterator");
-    versionTypeOpt = new Option("vers", "version", false, "a versioning iterator");
-    reqvisTypeOpt = new Option("reqvis", "require-visibility", false, "an iterator that omits entries with empty visibilities");
-    ageoffTypeOpt = new Option("ageoff", "ageoff", false, "an aging off iterator");
-
-    typeGroup.addOption(classnameTypeOpt);
-    typeGroup.addOption(aggTypeOpt);
-    typeGroup.addOption(regexTypeOpt);
-    typeGroup.addOption(versionTypeOpt);
-    typeGroup.addOption(reqvisTypeOpt);
-    typeGroup.addOption(ageoffTypeOpt);
-    typeGroup.setRequired(true);
-
-    final OptionGroup tableGroup = new OptionGroup();
-    tableGroup.addOption(OptUtil.tableOpt("table to configure iterators on"));
-    tableGroup.addOption(OptUtil.namespaceOpt("namespace to configure iterators on"));
-
-    o.addOption(priorityOpt);
-    o.addOption(nameOpt);
-    o.addOption(allScopeOpt);
-    o.addOption(mincScopeOpt);
-    o.addOption(majcScopeOpt);
-    o.addOption(scanScopeOpt);
-    o.addOptionGroup(typeGroup);
-    o.addOptionGroup(tableGroup);
-    return o;
-  }
-
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SetScanIterCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SetScanIterCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SetScanIterCommand.java
deleted file mode 100644
index 513975c..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SetScanIterCommand.java
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.accumulo.core.util.shell.commands;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.IteratorSetting;
-import org.apache.accumulo.core.client.Scanner;
-import org.apache.accumulo.core.client.TableNotFoundException;
-import org.apache.accumulo.core.iterators.IteratorUtil.IteratorScope;
-import org.apache.accumulo.core.iterators.SortedKeyValueIterator;
-import org.apache.accumulo.core.security.Authorizations;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.ShellCommandException;
-import org.apache.accumulo.core.util.shell.ShellCommandException.ErrorCode;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.OptionGroup;
-import org.apache.commons.cli.Options;
-
-public class SetScanIterCommand extends SetIterCommand {
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException, TableNotFoundException,
-      IOException, ShellCommandException {
-    Shell.log.warn("Deprecated, use " + new SetShellIterCommand().getName());
-    return super.execute(fullCommand, cl, shellState);
-  }
-  
-  @Override
-  protected void setTableProperties(final CommandLine cl, final Shell shellState, final int priority, final Map<String,String> options, final String classname,
-      final String name) throws AccumuloException, AccumuloSecurityException, ShellCommandException, TableNotFoundException {
-    
-    final String tableName = OptUtil.getTableOpt(cl, shellState);
-
-    // instead of setting table properties, just put the options in a list to use at scan time
-    Class<?> loadClass;
-    try {
-      loadClass = getClass().getClassLoader().loadClass(classname);
-    } catch (ClassNotFoundException e) {
-      throw new ShellCommandException(ErrorCode.INITIALIZATION_FAILURE, "Unable to load " + classname);
-    }
-    try {
-      loadClass.asSubclass(SortedKeyValueIterator.class);
-    } catch (ClassCastException ex) {
-      throw new ShellCommandException(ErrorCode.INITIALIZATION_FAILURE, "Unable to load " + classname  + " as type "
-          + SortedKeyValueIterator.class.getName());
-    }
-    
-    for (Iterator<Entry<String,String>> i = options.entrySet().iterator(); i.hasNext();) {
-      final Entry<String,String> entry = i.next();
-      if (entry.getValue() == null || entry.getValue().isEmpty()) {
-        i.remove();
-      }
-    }
-
-    List<IteratorSetting> tableScanIterators = shellState.scanIteratorOptions.get(tableName);
-    if (tableScanIterators == null) {
-      tableScanIterators = new ArrayList<IteratorSetting>();
-      shellState.scanIteratorOptions.put(tableName, tableScanIterators);
-    }
-    final IteratorSetting setting = new IteratorSetting(priority, name, classname);
-    setting.addOptions(options);
-    
-    // initialize a scanner to ensure the new setting does not conflict with existing settings
-    final String user = shellState.getConnector().whoami();
-    final Authorizations auths = shellState.getConnector().securityOperations().getUserAuthorizations(user);
-    final Scanner scanner = shellState.getConnector().createScanner(tableName, auths);
-    for (IteratorSetting s : tableScanIterators) {
-      scanner.addScanIterator(s);
-    }
-    scanner.addScanIterator(setting);
-    
-    // if no exception has been thrown, it's safe to add it to the list
-    tableScanIterators.add(setting);
-    Shell.log.debug("Scan iterators :" + shellState.scanIteratorOptions.get(tableName));
-  }
-  
-  @Override
-  public String description() {
-    return "sets a table-specific scan iterator for this shell session";
-  }
-  
-  @Override
-  public Options getOptions() {
-    // Remove the options that specify which type of iterator this is, since
-    // they are all scan iterators with this command.
-    final HashSet<OptionGroup> groups = new HashSet<OptionGroup>();
-    final Options parentOptions = super.getOptions();
-    final Options modifiedOptions = new Options();
-    for (Iterator<?> it = parentOptions.getOptions().iterator(); it.hasNext();) {
-      Option o = (Option) it.next();
-      if (!IteratorScope.majc.name().equals(o.getOpt()) && !IteratorScope.minc.name().equals(o.getOpt()) && !IteratorScope.scan.name().equals(o.getOpt())) {
-        modifiedOptions.addOption(o);
-        OptionGroup group = parentOptions.getOptionGroup(o);
-        if (group != null)
-          groups.add(group);
-      }
-    }
-    for (OptionGroup group : groups) {
-      modifiedOptions.addOptionGroup(group);
-    }
-    return modifiedOptions;
-  }
-  
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SetShellIterCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SetShellIterCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SetShellIterCommand.java
deleted file mode 100644
index b95725a..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SetShellIterCommand.java
+++ /dev/null
@@ -1,131 +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.accumulo.core.util.shell.commands;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.IteratorSetting;
-import org.apache.accumulo.core.client.TableNotFoundException;
-import org.apache.accumulo.core.iterators.IteratorUtil.IteratorScope;
-import org.apache.accumulo.core.iterators.SortedKeyValueIterator;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.ShellCommandException;
-import org.apache.accumulo.core.util.shell.ShellCommandException.ErrorCode;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.OptionGroup;
-import org.apache.commons.cli.Options;
-
-public class SetShellIterCommand extends SetIterCommand {
-  private Option profileOpt;
-
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException,
-      TableNotFoundException, IOException, ShellCommandException {
-    return super.execute(fullCommand, cl, shellState);
-  }
-  
-  @Override
-  protected void setTableProperties(final CommandLine cl, final Shell shellState, final int priority, final Map<String,String> options, final String classname,
-      final String name) throws AccumuloException, AccumuloSecurityException, ShellCommandException, TableNotFoundException {
-    // instead of setting table properties, just put the options in a list to use at scan time
-    
-    String profile = cl.getOptionValue(profileOpt.getOpt());
-
-    // instead of setting table properties, just put the options in a list to use at scan time
-    Class<?> loadClass;
-    try {
-      loadClass = getClass().getClassLoader().loadClass(classname);
-    } catch (ClassNotFoundException e) {
-      throw new ShellCommandException(ErrorCode.INITIALIZATION_FAILURE, "Unable to load " + classname);
-    }
-    try {
-      loadClass.asSubclass(SortedKeyValueIterator.class);
-    } catch (ClassCastException ex) {
-      throw new ShellCommandException(ErrorCode.INITIALIZATION_FAILURE, "xUnable to load " + classname  + " as type "
-          + SortedKeyValueIterator.class.getName());
-    }
-    
-    for (Iterator<Entry<String,String>> i = options.entrySet().iterator(); i.hasNext();) {
-      final Entry<String,String> entry = i.next();
-      if (entry.getValue() == null || entry.getValue().isEmpty()) {
-        i.remove();
-      }
-    }
-
-    List<IteratorSetting> tableScanIterators = shellState.iteratorProfiles.get(profile);
-    if (tableScanIterators == null) {
-      tableScanIterators = new ArrayList<IteratorSetting>();
-      shellState.iteratorProfiles.put(profile, tableScanIterators);
-    }
-    final IteratorSetting setting = new IteratorSetting(priority, name, classname);
-    setting.addOptions(options);
-
-    Iterator<IteratorSetting> iter = tableScanIterators.iterator();
-    while (iter.hasNext()) {
-      if (iter.next().getName().equals(name)) {
-        iter.remove();
-      }
-    }
-
-    tableScanIterators.add(setting);
-  }
-  
-  @Override
-  public String description() {
-    return "adds an iterator to a profile for this shell session";
-  }
-  
-  @Override
-  public Options getOptions() {
-    // Remove the options that specify which type of iterator this is, since
-    // they are all scan iterators with this command.
-    final HashSet<OptionGroup> groups = new HashSet<OptionGroup>();
-    final Options parentOptions = super.getOptions();
-    final Options modifiedOptions = new Options();
-    for (Iterator<?> it = parentOptions.getOptions().iterator(); it.hasNext();) {
-      Option o = (Option) it.next();
-      if (!IteratorScope.majc.name().equals(o.getOpt()) && !IteratorScope.minc.name().equals(o.getOpt()) && !IteratorScope.scan.name().equals(o.getOpt())
-          && !"table".equals(o.getLongOpt())) {
-        modifiedOptions.addOption(o);
-        OptionGroup group = parentOptions.getOptionGroup(o);
-        if (group != null)
-          groups.add(group);
-      }
-    }
-    for (OptionGroup group : groups) {
-      modifiedOptions.addOptionGroup(group);
-    }
-    
-    profileOpt = new Option("pn", "profile", true, "iterator profile name");
-    profileOpt.setRequired(true);
-    profileOpt.setArgName("profile");
-    
-    modifiedOptions.addOption(profileOpt);
-
-    return modifiedOptions;
-  }
-  
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ShellPluginConfigurationCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ShellPluginConfigurationCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ShellPluginConfigurationCommand.java
deleted file mode 100644
index d4c9739..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ShellPluginConfigurationCommand.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.accumulo.core.util.shell.commands;
-
-import java.util.Iterator;
-import java.util.Map.Entry;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.TableNotFoundException;
-import org.apache.accumulo.core.conf.Property;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.accumulo.start.classloader.vfs.AccumuloVFSClassLoader;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.OptionGroup;
-import org.apache.commons.cli.Options;
-import org.apache.log4j.Logger;
-
-public abstract class ShellPluginConfigurationCommand extends Command {
-  private Option removePluginOption, pluginClassOption, listPluginOption;
-  
-  private String pluginType;
-  
-  private Property tableProp;
-  
-  private String classOpt;
-  
-  ShellPluginConfigurationCommand(final String typeName, final Property tableProp, final String classOpt) {
-    this.pluginType = typeName;
-    this.tableProp = tableProp;
-    this.classOpt = classOpt;
-  }
-
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    final String tableName = OptUtil.getTableOpt(cl, shellState);
-    
-    if (cl.hasOption(removePluginOption.getOpt())) {
-      // Remove the property
-      removePlugin(cl, shellState, tableName);
-      
-      shellState.getReader().println("Removed "+pluginType+" on " + tableName);
-    } else if (cl.hasOption(listPluginOption.getOpt())) {
-      // Get the options for this table
-      final Iterator<Entry<String,String>> iter = shellState.getConnector().tableOperations().getProperties(tableName).iterator();
-      
-      while (iter.hasNext()) {
-        Entry<String,String> ent = iter.next();
-        
-        // List all parameters with the property name
-        if (ent.getKey().startsWith(tableProp.toString())) {
-          shellState.getReader().println(ent.getKey() + ": " + ent.getValue());
-        }
-      }
-    } else {
-      // Set the plugin with the provided options
-      String className = cl.getOptionValue(pluginClassOption.getOpt());
-      
-      // Set the plugin property on the table
-      setPlugin(cl, shellState, tableName, className);
-    }
-    
-    return 0;
-  }
-
-  protected void setPlugin(final CommandLine cl, final Shell shellState, final String tableName, final String className) throws AccumuloException, AccumuloSecurityException {
-    shellState.getConnector().tableOperations().setProperty(tableName, tableProp.toString(), className);
-  }
-  
-  protected void removePlugin(final CommandLine cl, final Shell shellState, final String tableName) throws AccumuloException, AccumuloSecurityException {
-    shellState.getConnector().tableOperations().removeProperty(tableName, tableProp.toString());
-  }
-  
-  public static <T> Class<? extends T> getPluginClass(final String tableName, final Shell shellState, final Class<T> clazz, final Property pluginProp) {
-    Iterator<Entry<String,String>> props;
-    try {
-      props = shellState.getConnector().tableOperations().getProperties(tableName).iterator();
-    } catch (AccumuloException e) {
-      return null;
-    } catch (TableNotFoundException e) {
-      return null;
-    }
-    
-    while (props.hasNext()) {
-      final Entry<String,String> ent = props.next();
-      if (ent.getKey().equals(pluginProp.toString())) {
-        Class<? extends T> pluginClazz;
-        try {
-          pluginClazz = AccumuloVFSClassLoader.loadClass(ent.getValue(), clazz);
-        } catch (ClassNotFoundException e) {
-          Logger.getLogger(ShellPluginConfigurationCommand.class).warn("Class not found" + e.getMessage());
-          return null;
-        }
-        
-        return pluginClazz;
-      }
-    }
-    
-    return null;
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-    final OptionGroup actionGroup = new OptionGroup();
-    
-    pluginClassOption = new Option(classOpt, pluginType, true, "fully qualified name of the " + pluginType + " class to use");
-    pluginClassOption.setArgName("className");
-    
-    // Action to take: apply (default), remove, list
-    removePluginOption = new Option("r", "remove", false, "remove the current "+pluginType+"");
-    listPluginOption = new Option("l", "list", false, "display the current "+pluginType+"");
-    
-    actionGroup.addOption(pluginClassOption);
-    actionGroup.addOption(removePluginOption);
-    actionGroup.addOption(listPluginOption);
-    actionGroup.setRequired(true);
-    
-    o.addOptionGroup(actionGroup);
-    o.addOption(OptUtil.tableOpt("table to set the "+pluginType+" on"));
-    
-    return o;
-  }
-  
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-  
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SleepCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SleepCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SleepCommand.java
deleted file mode 100644
index ab69456..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SleepCommand.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.accumulo.core.util.shell.commands;
-
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-
-public class SleepCommand extends Command {
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    final double secs = Double.parseDouble(cl.getArgs()[0]);
-    Thread.sleep((long) (secs * 1000));
-    return 0;
-  }
-  
-  @Override
-  public String description() {
-    return "sleeps for the given number of seconds";
-  }
-  
-  @Override
-  public int numArgs() {
-    return 1;
-  }
-  
-  @Override
-  public String usage() {
-    return getName() + " <seconds>";
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SystemPermissionsCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SystemPermissionsCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SystemPermissionsCommand.java
deleted file mode 100644
index 3dec6fc..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SystemPermissionsCommand.java
+++ /dev/null
@@ -1,44 +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.accumulo.core.util.shell.commands;
-
-import java.io.IOException;
-
-import org.apache.accumulo.core.security.SystemPermission;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-
-public class SystemPermissionsCommand extends Command {
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws IOException {
-    for (String p : SystemPermission.printableValues()) {
-      shellState.getReader().println(p);
-    }
-    return 0;
-  }
-  
-  @Override
-  public String description() {
-    return "displays a list of valid system permissions";
-  }
-  
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/TableCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/TableCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/TableCommand.java
deleted file mode 100644
index d77f6fb..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/TableCommand.java
+++ /dev/null
@@ -1,60 +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.accumulo.core.util.shell.commands;
-
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.TableNotFoundException;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.accumulo.core.util.shell.Token;
-import org.apache.commons.cli.CommandLine;
-
-public class TableCommand extends Command {
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException, TableNotFoundException {
-    final String tableName = cl.getArgs()[0];
-    if (!shellState.getConnector().tableOperations().exists(tableName)) {
-      throw new TableNotFoundException(null, tableName, null);
-    }
-    shellState.setTableName(tableName);
-    return 0;
-  }
-  
-  @Override
-  public String description() {
-    return "switches to the specified table";
-  }
-  
-  @Override
-  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> special) {
-    registerCompletionForTables(root, special);
-  }
-  
-  @Override
-  public String usage() {
-    return getName() + " <tableName>";
-  }
-  
-  @Override
-  public int numArgs() {
-    return 1;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/TableOperation.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/TableOperation.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/TableOperation.java
deleted file mode 100644
index 27946b8..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/TableOperation.java
+++ /dev/null
@@ -1,153 +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.accumulo.core.util.shell.commands;
-
-import java.util.Map;
-import java.util.Set;
-import java.util.SortedSet;
-import java.util.TreeSet;
-
-import org.apache.accumulo.core.client.Instance;
-import org.apache.accumulo.core.client.TableNotFoundException;
-import org.apache.accumulo.core.client.impl.Namespaces;
-import org.apache.accumulo.core.client.impl.Tables;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.accumulo.core.util.shell.Token;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.OptionGroup;
-import org.apache.commons.cli.Options;
-
-public abstract class TableOperation extends Command {
-
-  protected Option optTablePattern, optTableName, optNamespace;
-  private boolean force = true;
-  private boolean useCommandLine = true;
-
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    // populate the tableSet set with the tables you want to operate on
-    final SortedSet<String> tableSet = new TreeSet<String>();
-    if (cl.hasOption(optTablePattern.getOpt())) {
-      for (String table : shellState.getConnector().tableOperations().list())
-        if (table.matches(cl.getOptionValue(optTablePattern.getOpt()))) {
-          tableSet.add(table);
-        }
-    } else if (cl.hasOption(optTableName.getOpt())) {
-      tableSet.add(cl.getOptionValue(optTableName.getOpt()));
-    } else if (cl.hasOption(optNamespace.getOpt())) {
-      Instance instance = shellState.getInstance();
-      String namespaceId = Namespaces.getNamespaceId(instance, cl.getOptionValue(optNamespace.getOpt()));
-      for (String tableId : Namespaces.getTableIds(instance, namespaceId)) {
-        tableSet.add(Tables.getTableName(instance, tableId));
-      }
-    } else if (useCommandLine && cl.getArgs().length > 0) {
-      for (String tableName : cl.getArgs()) {
-        tableSet.add(tableName);
-      }
-    } else {
-      shellState.checkTableState();
-      tableSet.add(shellState.getTableName());
-    }
-
-    if (tableSet.isEmpty())
-      Shell.log.warn("No tables found that match your criteria");
-
-    boolean more = true;
-    // flush the tables
-    for (String tableName : tableSet) {
-      if (!more) {
-        break;
-      }
-      if (!shellState.getConnector().tableOperations().exists(tableName)) {
-        throw new TableNotFoundException(null, tableName, null);
-      }
-      boolean operate = true;
-      if (!force) {
-        shellState.getReader().flush();
-        String line = shellState.getReader().readLine(getName() + " { " + tableName + " } (yes|no)? ");
-        more = line != null;
-        operate = line != null && (line.equalsIgnoreCase("y") || line.equalsIgnoreCase("yes"));
-      }
-      if (operate) {
-        doTableOp(shellState, tableName);
-      }
-    }
-
-    return 0;
-  }
-
-  protected abstract void doTableOp(Shell shellState, String tableName) throws Exception;
-
-  @Override
-  public String description() {
-    return "makes a best effort to flush tables from memory to disk";
-  }
-
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-
-    optTablePattern = new Option("p", "pattern", true, "regex pattern of table names to operate on");
-    optTablePattern.setArgName("pattern");
-
-    optTableName = new Option(Shell.tableOption, "table", true, "name of a table to operate on");
-    optTableName.setArgName("tableName");
-
-    optNamespace = new Option(Shell.namespaceOption, "namespace", true, "name of a namespace to operate on");
-    optNamespace.setArgName("namespace");
-
-    final OptionGroup opg = new OptionGroup();
-
-    opg.addOption(optTablePattern);
-    opg.addOption(optTableName);
-    opg.addOption(optNamespace);
-
-    o.addOptionGroup(opg);
-
-    return o;
-  }
-
-  @Override
-  public int numArgs() {
-    return useCommandLine ? Shell.NO_FIXED_ARG_LENGTH_CHECK : 0;
-  }
-
-  protected void force() {
-    force = true;
-  }
-
-  protected void noForce() {
-    force = false;
-  }
-
-  protected void disableUnflaggedTableOptions() {
-    useCommandLine = false;
-  }
-
-  @Override
-  public String usage() {
-    return getName() + " [<table>{ <table>}]";
-  }
-
-  @Override
-  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> special) {
-    if (useCommandLine)
-      registerCompletionForTables(root, special);
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/TablePermissionsCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/TablePermissionsCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/TablePermissionsCommand.java
deleted file mode 100644
index 1f92f21..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/TablePermissionsCommand.java
+++ /dev/null
@@ -1,44 +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.accumulo.core.util.shell.commands;
-
-import java.io.IOException;
-
-import org.apache.accumulo.core.security.TablePermission;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-
-public class TablePermissionsCommand extends Command {
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws IOException {
-    for (String p : TablePermission.printableValues()) {
-      shellState.getReader().println(p);
-    }
-    return 0;
-  }
-  
-  @Override
-  public String description() {
-    return "displays a list of valid table permissions";
-  }
-  
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/TablesCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/TablesCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/TablesCommand.java
deleted file mode 100644
index a03a986..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/TablesCommand.java
+++ /dev/null
@@ -1,107 +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.accumulo.core.util.shell.commands;
-
-import java.io.IOException;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.TreeMap;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.NamespaceNotFoundException;
-import org.apache.accumulo.core.client.impl.Tables;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-import org.apache.commons.collections.MapUtils;
-
-import com.google.common.base.Function;
-import com.google.common.base.Predicate;
-import com.google.common.collect.Iterators;
-import com.google.common.collect.Maps;
-
-public class TablesCommand extends Command {
-  static final String NAME_AND_ID_FORMAT = "%-20s => %9s%n";
-
-  private Option tableIdOption;
-  private Option sortByTableIdOption;
-  private Option disablePaginationOpt;
-
-  @SuppressWarnings("unchecked")
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException, IOException,
-      NamespaceNotFoundException {
-
-    final String namespace = cl.hasOption(OptUtil.namespaceOpt().getOpt()) ? OptUtil.getNamespaceOpt(cl, shellState) : null;
-    Map<String,String> tables = shellState.getConnector().tableOperations().tableIdMap();
-
-    // filter only specified namespace
-    tables = Maps.filterKeys(tables, new Predicate<String>() {
-      @Override
-      public boolean apply(String tableName) {
-        return namespace == null || Tables.qualify(tableName).getFirst().equals(namespace);
-      }
-    });
-
-    final boolean sortByTableId = cl.hasOption(sortByTableIdOption.getOpt());
-    tables = new TreeMap<String,String>((sortByTableId ? MapUtils.invertMap(tables) : tables));
-
-    Iterator<String> it = Iterators.transform(tables.entrySet().iterator(), new Function<Entry<String,String>,String>() {
-      @Override
-      public String apply(Map.Entry<String,String> entry) {
-        String tableName = String.valueOf(sortByTableId ? entry.getValue() : entry.getKey());
-        String tableId = String.valueOf(sortByTableId ? entry.getKey() : entry.getValue());
-        if (namespace != null)
-          tableName = Tables.qualify(tableName).getSecond();
-        if (cl.hasOption(tableIdOption.getOpt()))
-          return String.format(NAME_AND_ID_FORMAT, tableName, tableId);
-        else
-          return tableName;
-      };
-    });
-
-    shellState.printLines(it, !cl.hasOption(disablePaginationOpt.getOpt()));
-    return 0;
-  }
-
-  @Override
-  public String description() {
-    return "displays a list of all existing tables";
-  }
-
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-    tableIdOption = new Option("l", "list-ids", false, "display internal table ids along with the table name");
-    o.addOption(tableIdOption);
-    sortByTableIdOption = new Option("s", "sort-ids", false, "with -l: sort output by table ids");
-    o.addOption(sortByTableIdOption);
-    disablePaginationOpt = new Option("np", "no-pagination", false, "disable pagination of output");
-    o.addOption(disablePaginationOpt);
-    o.addOption(OptUtil.namespaceOpt("name of namespace to list only its tables"));
-    return o;
-  }
-
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/TraceCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/TraceCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/TraceCommand.java
deleted file mode 100644
index 281a33a..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/TraceCommand.java
+++ /dev/null
@@ -1,101 +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.accumulo.core.util.shell.commands;
-
-import java.io.IOException;
-import java.util.Map;
-
-import org.apache.accumulo.trace.instrument.Trace;
-import org.apache.accumulo.core.client.Scanner;
-import org.apache.accumulo.core.conf.Property;
-import org.apache.accumulo.core.data.Range;
-import org.apache.accumulo.core.security.Authorizations;
-import org.apache.accumulo.core.trace.TraceDump;
-import org.apache.accumulo.core.trace.TraceDump.Printer;
-import org.apache.accumulo.core.util.BadArgumentException;
-import org.apache.accumulo.core.util.UtilWaitThread;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.commons.cli.CommandLine;
-import org.apache.hadoop.io.Text;
-
-public class TraceCommand extends DebugCommand {
-  
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws IOException {
-    if (cl.getArgs().length == 1) {
-      if (cl.getArgs()[0].equalsIgnoreCase("on")) {
-        Trace.on("shell:" + shellState.getPrincipal());
-      } else if (cl.getArgs()[0].equalsIgnoreCase("off")) {
-        if (Trace.isTracing()) {
-          final long trace = Trace.currentTrace().traceId();
-          Trace.off();
-          StringBuffer sb = new StringBuffer();
-          int traceCount = 0;
-          for (int i = 0; i < 30; i++) {
-            sb = new StringBuffer();
-            try {
-              final Map<String,String> properties = shellState.getConnector().instanceOperations().getSystemConfiguration();
-              final String table = properties.get(Property.TRACE_TABLE.getKey());
-              final String user = shellState.getConnector().whoami();
-              final Authorizations auths = shellState.getConnector().securityOperations().getUserAuthorizations(user);
-              final Scanner scanner = shellState.getConnector().createScanner(table, auths);
-              scanner.setRange(new Range(new Text(Long.toHexString(trace))));
-              final StringBuffer finalSB = sb;
-              traceCount = TraceDump.printTrace(scanner, new Printer() {
-                @Override
-                public void print(final String line) {
-                  try {
-                    finalSB.append(line + "\n");
-                  } catch (Exception ex) {
-                    throw new RuntimeException(ex);
-                  }
-                }
-              });
-              if (traceCount > 0) {
-                shellState.getReader().print(sb.toString());
-                break;
-              }
-            } catch (Exception ex) {
-              shellState.printException(ex);
-            }
-            shellState.getReader().println("Waiting for trace information");
-            shellState.getReader().flush();
-            UtilWaitThread.sleep(500);
-          }
-          if (traceCount < 0) {
-            // display the trace even though there are unrooted spans
-            shellState.getReader().print(sb.toString());
-          }
-        } else {
-          shellState.getReader().println("Not tracing");
-        }
-      } else
-        throw new BadArgumentException("Argument must be 'on' or 'off'", fullCommand, fullCommand.indexOf(cl.getArgs()[0]));
-    } else if (cl.getArgs().length == 0) {
-      shellState.getReader().println(Trace.isTracing() ? "on" : "off");
-    } else {
-      shellState.printException(new IllegalArgumentException("Expected 0 or 1 argument. There were " + cl.getArgs().length + "."));
-      printHelp(shellState);
-      return 1;
-    }
-    return 0;
-  }
-  
-  @Override
-  public String description() {
-    return "turns trace logging on or off";
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/UserCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/UserCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/UserCommand.java
deleted file mode 100644
index 07da450..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/UserCommand.java
+++ /dev/null
@@ -1,71 +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.accumulo.core.util.shell.commands;
-
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.security.tokens.PasswordToken;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.accumulo.core.util.shell.Token;
-import org.apache.commons.cli.CommandLine;
-
-public class UserCommand extends Command {
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException, IOException {
-    // save old credentials and connection in case of failure
-    String user = cl.getArgs()[0];
-    byte[] pass;
-    
-    // We can't let the wrapping try around the execute method deal
-    // with the exceptions because we have to do something if one
-    // of these methods fails
-    final String p = shellState.readMaskedLine("Enter password for user " + user + ": ", '*');
-    if (p == null) {
-      shellState.getReader().println();
-      return 0;
-    } // user canceled
-    pass = p.getBytes(StandardCharsets.UTF_8);
-    shellState.updateUser(user, new PasswordToken(pass));
-    return 0;
-  }
-  
-  @Override
-  public String description() {
-    return "switches to the specified user";
-  }
-  
-  @Override
-  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> special) {
-    registerCompletionForUsers(root, special);
-  }
-  
-  @Override
-  public String usage() {
-    return getName() + " <username>";
-  }
-  
-  @Override
-  public int numArgs() {
-    return 1;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/UserPermissionsCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/UserPermissionsCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/UserPermissionsCommand.java
deleted file mode 100644
index a126159..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/UserPermissionsCommand.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.accumulo.core.util.shell.commands;
-
-import java.io.IOException;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.security.NamespacePermission;
-import org.apache.accumulo.core.security.SystemPermission;
-import org.apache.accumulo.core.security.TablePermission;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-
-public class UserPermissionsCommand extends Command {
-  private Option userOpt;
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException, IOException {
-    final String user = cl.getOptionValue(userOpt.getOpt(), shellState.getConnector().whoami());
-
-    String delim = "";
-    shellState.getReader().print("System permissions: ");
-    for (SystemPermission p : SystemPermission.values()) {
-      if (p != null && shellState.getConnector().securityOperations().hasSystemPermission(user, p)) {
-        shellState.getReader().print(delim + "System." + p.name());
-        delim = ", ";
-      }
-    }
-    shellState.getReader().println();
-
-    boolean runOnce = true;
-    for (String n : shellState.getConnector().namespaceOperations().list()) {
-      delim = "";
-      for (NamespacePermission p : NamespacePermission.values()) {
-        if (p != null && shellState.getConnector().securityOperations().hasNamespacePermission(user, n, p)) {
-          if (runOnce) {
-            shellState.getReader().print("\nNamespace permissions (" + n + "): ");
-            runOnce = false;
-          }
-          shellState.getReader().print(delim + "Namespace." + p.name());
-          delim = ", ";
-        }
-      }
-      runOnce = true;
-    }
-    shellState.getReader().println();
-
-    
-    runOnce = true;
-    for (String t : shellState.getConnector().tableOperations().list()) {
-      delim = "";
-      for (TablePermission p : TablePermission.values()) {
-        if (shellState.getConnector().securityOperations().hasTablePermission(user, t, p) && p != null) {
-          if (runOnce) {
-            shellState.getReader().print("\nTable permissions (" + t + "): ");
-            runOnce = false;
-          }
-          shellState.getReader().print(delim + "Table." + p.name());
-          delim = ", ";
-        }
-
-      }
-      runOnce = true;
-    }
-    shellState.getReader().println();
-
-    return 0;
-  }
-
-  @Override
-  public String description() {
-    return "displays a user's system, table, and namespace permissions";
-  }
-
-  @Override
-  public Options getOptions() {
-    Options o = new Options();
-    userOpt = new Option(Shell.userOption, "user", true, "user to operate on");
-    userOpt.setArgName("user");
-    o.addOption(userOpt);
-    return o;
-  }
-
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/UsersCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/UsersCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/UsersCommand.java
deleted file mode 100644
index 023c38b..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/UsersCommand.java
+++ /dev/null
@@ -1,45 +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.accumulo.core.util.shell.commands;
-
-import java.io.IOException;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-
-public class UsersCommand extends Command {
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException, IOException {
-    for (String user : shellState.getConnector().securityOperations().listLocalUsers()) {
-      shellState.getReader().println(user);
-    }
-    return 0;
-  }
-  
-  @Override
-  public String description() {
-    return "displays a list of existing users";
-  }
-  
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/WhoAmICommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/WhoAmICommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/WhoAmICommand.java
deleted file mode 100644
index e7bb29d..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/WhoAmICommand.java
+++ /dev/null
@@ -1,41 +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.accumulo.core.util.shell.commands;
-
-import java.io.IOException;
-
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-
-public class WhoAmICommand extends Command {
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws IOException {
-    shellState.getReader().println(shellState.getConnector().whoami());
-    return 0;
-  }
-  
-  @Override
-  public String description() {
-    return "reports the current user name";
-  }
-  
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/test/java/org/apache/accumulo/core/util/format/DeleterFormatterTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/accumulo/core/util/format/DeleterFormatterTest.java b/core/src/test/java/org/apache/accumulo/core/util/format/DeleterFormatterTest.java
deleted file mode 100644
index 9223166..0000000
--- a/core/src/test/java/org/apache/accumulo/core/util/format/DeleterFormatterTest.java
+++ /dev/null
@@ -1,176 +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.accumulo.core.util.format;
-
-import static org.easymock.EasyMock.anyObject;
-import static org.easymock.EasyMock.createMock;
-import static org.easymock.EasyMock.createNiceMock;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.expectLastCall;
-import static org.easymock.EasyMock.replay;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.charset.StandardCharsets;
-import java.util.Collections;
-import java.util.Map;
-import java.util.TreeMap;
-
-import jline.UnsupportedTerminal;
-import jline.console.ConsoleReader;
-
-import org.apache.accumulo.core.client.BatchWriter;
-import org.apache.accumulo.core.client.MutationsRejectedException;
-import org.apache.accumulo.core.data.Key;
-import org.apache.accumulo.core.data.Mutation;
-import org.apache.accumulo.core.data.Value;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.junit.Before;
-import org.junit.Test;
-
-public class DeleterFormatterTest {
-  DeleterFormatter formatter;
-  Map<Key,Value> data;
-  BatchWriter writer;
-  BatchWriter exceptionWriter;
-  Shell shellState;
-
-  ByteArrayOutputStream baos;
-  ConsoleReader reader;
-
-  SettableInputStream input;
-
-  class SettableInputStream extends InputStream {
-    ByteArrayInputStream bais;
-
-    @Override
-    public int read() throws IOException {
-      return bais.read();
-    }
-
-    public void set(String in) {
-      bais = new ByteArrayInputStream(in.getBytes(StandardCharsets.UTF_8));
-    }
-  };
-
-  @Before
-  public void setUp() throws IOException, MutationsRejectedException {
-    input = new SettableInputStream();
-    baos = new ByteArrayOutputStream();
-
-    MutationsRejectedException mre = createMock(MutationsRejectedException.class);
-
-    writer = createNiceMock(BatchWriter.class);
-    exceptionWriter = createNiceMock(BatchWriter.class);
-    exceptionWriter.close();
-    expectLastCall().andThrow(mre);
-    exceptionWriter.addMutation(anyObject(Mutation.class));
-    expectLastCall().andThrow(mre);
-
-    shellState = createNiceMock(Shell.class);
-
-    reader = new ConsoleReader(input, baos, new UnsupportedTerminal());
-    expect(shellState.getReader()).andReturn(reader).anyTimes();
-
-    replay(writer, exceptionWriter, shellState);
-
-    data = new TreeMap<Key,Value>();
-    data.put(new Key("r", "cf", "cq"), new Value("value".getBytes(StandardCharsets.UTF_8)));
-  }
-
-  @Test
-  public void testEmpty() {
-    formatter = new DeleterFormatter(writer, Collections.<Key,Value> emptyMap().entrySet(), true, shellState, true);
-    assertFalse(formatter.hasNext());
-  }
-
-  @Test
-  public void testSingle() throws IOException {
-    formatter = new DeleterFormatter(writer, data.entrySet(), true, shellState, true);
-
-    assertTrue(formatter.hasNext());
-    assertNull(formatter.next());
-
-    verify("[DELETED]", " r ", "cf", "cq", "value");
-  }
-
-  @Test
-  public void testNo() throws IOException {
-    input.set("no\n");
-    data.put(new Key("z"), new Value("v2".getBytes(StandardCharsets.UTF_8)));
-    formatter = new DeleterFormatter(writer, data.entrySet(), true, shellState, false);
-
-    assertTrue(formatter.hasNext());
-    assertNull(formatter.next());
-
-    verify("[SKIPPED]", " r ", "cf", "cq", "value");
-
-    assertTrue(formatter.hasNext());
-  }
-
-  @Test
-  public void testNoConfirmation() throws IOException {
-    input.set("");
-    data.put(new Key("z"), new Value("v2".getBytes(StandardCharsets.UTF_8)));
-    formatter = new DeleterFormatter(writer, data.entrySet(), true, shellState, false);
-
-    assertTrue(formatter.hasNext());
-    assertNull(formatter.next());
-
-    verify("[SKIPPED]", " r ", "cf", "cq", "value");
-
-    assertFalse(formatter.hasNext());
-  }
-
-  @Test
-  public void testYes() throws IOException {
-    input.set("y\nyes\n");
-    data.put(new Key("z"), new Value("v2".getBytes(StandardCharsets.UTF_8)));
-    formatter = new DeleterFormatter(writer, data.entrySet(), true, shellState, false);
-
-    assertTrue(formatter.hasNext());
-    assertNull(formatter.next());
-    verify("[DELETED]", " r ", "cf", "cq", "value");
-
-    assertTrue(formatter.hasNext());
-    assertNull(formatter.next());
-    verify("[DELETED]", " z ", "v2");
-  }
-
-  @Test
-  public void testMutationException() {
-    formatter = new DeleterFormatter(exceptionWriter, data.entrySet(), true, shellState, true);
-
-    assertTrue(formatter.hasNext());
-    assertNull(formatter.next());
-    assertFalse(formatter.hasNext());
-  }
-
-  private void verify(String... chunks) throws IOException {
-    reader.flush();
-
-    String output = baos.toString();
-    for (String chunk : chunks) {
-      assertTrue(output.contains(chunk));
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/test/java/org/apache/accumulo/core/util/shell/PasswordConverterTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/accumulo/core/util/shell/PasswordConverterTest.java b/core/src/test/java/org/apache/accumulo/core/util/shell/PasswordConverterTest.java
deleted file mode 100644
index d1d24a6..0000000
--- a/core/src/test/java/org/apache/accumulo/core/util/shell/PasswordConverterTest.java
+++ /dev/null
@@ -1,113 +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.accumulo.core.util.shell;
-
-import static org.junit.Assert.assertEquals;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStreamWriter;
-import java.io.PipedInputStream;
-import java.io.PipedOutputStream;
-import java.util.Scanner;
-
-import org.apache.accumulo.core.util.shell.ShellOptionsJC.PasswordConverter;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-
-import com.beust.jcommander.JCommander;
-import com.beust.jcommander.Parameter;
-import com.beust.jcommander.ParameterException;
-
-public class PasswordConverterTest {
-  
-  private class Password {
-    @Parameter(names = "--password", converter = PasswordConverter.class)
-    String password;
-  }
-  
-  private String[] argv;
-  private Password password;
-  private static InputStream realIn;
-  
-  @BeforeClass
-  public static void saveIn() {
-    realIn = System.in;
-  }
-  
-  @Before
-  public void setup() throws IOException {
-    argv = new String[] {"--password", ""};
-    password = new Password();
-    
-    PipedInputStream in = new PipedInputStream();
-    PipedOutputStream out = new PipedOutputStream(in);
-    OutputStreamWriter osw = new OutputStreamWriter(out);
-    osw.write("secret");
-    osw.close();
-    
-    System.setIn(in);
-  }
-  
-  @After
-  public void teardown() {
-    System.setIn(realIn);
-  }
-  
-  @Test
-  public void testPass() {
-    String expected = String.valueOf(Math.random());
-    argv[1] = "pass:" + expected;
-    new JCommander(password, argv);
-    assertEquals(expected, password.password);
-  }
-  
-  @Test
-  public void testEnv() {
-    String name = System.getenv().keySet().iterator().next();
-    argv[1] = "env:" + name;
-    new JCommander(password, argv);
-    assertEquals(System.getenv(name), password.password);
-  }
-  
-  @Test
-  public void testFile() throws FileNotFoundException {
-    argv[1] = "file:pom.xml";
-    Scanner scan = new Scanner(new File("pom.xml"));
-    String expected = scan.nextLine();
-    scan.close();
-    new JCommander(password, argv);
-    assertEquals(expected, password.password);
-  }
-  
-  @Test(expected=ParameterException.class)
-  public void testNoFile() throws FileNotFoundException {
-    argv[1] = "file:doesnotexist";
-    new JCommander(password, argv);
-  }
-
-  @Test
-  public void testStdin() {
-    argv[1] = "stdin";
-    new JCommander(password, argv);
-    assertEquals("stdin", password.password);
-  }
-}


[51/53] [abbrv] git commit: ACCUMULO-2573 First stab at changes to IDL for replication

Posted by el...@apache.org.
ACCUMULO-2573 First stab at changes to IDL for replication


Project: http://git-wip-us.apache.org/repos/asf/accumulo/repo
Commit: http://git-wip-us.apache.org/repos/asf/accumulo/commit/d257001d
Tree: http://git-wip-us.apache.org/repos/asf/accumulo/tree/d257001d
Diff: http://git-wip-us.apache.org/repos/asf/accumulo/diff/d257001d

Branch: refs/heads/ACCUMULO-378
Commit: d257001db45d3de4b9f21514d11d713e41753778
Parents: 71475cf
Author: Josh Elser <el...@apache.org>
Authored: Mon Apr 7 22:54:16 2014 -0400
Committer: Josh Elser <el...@apache.org>
Committed: Mon Apr 7 23:01:24 2014 -0400

----------------------------------------------------------------------
 .../core/replication/thrift/KeyValues.java      |  456 +++++
 .../replication/thrift/RemoteReplication.java   | 1917 ++++++++++++++++++
 .../thrift/RemoteReplicationException.java      |  500 +++++
 .../core/replication/thrift/Replication.java    | 1917 ++++++++++++++++++
 .../core/replication/thrift/WalEdits.java       |  456 +++++
 .../thrift/ReplicationFailedException.java      |  402 ++++
 .../thrift/TabletClientService.java             | 1423 +++++++++++++
 core/src/main/scripts/generate-thrift.sh        |    2 +-
 core/src/main/thrift/replication.thrift         |   39 +
 core/src/main/thrift/tabletserver.thrift        |    6 +
 .../apache/accumulo/tserver/TabletServer.java   |    9 +
 11 files changed, 7126 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/accumulo/blob/d257001d/core/src/main/java/org/apache/accumulo/core/replication/thrift/KeyValues.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/replication/thrift/KeyValues.java b/core/src/main/java/org/apache/accumulo/core/replication/thrift/KeyValues.java
new file mode 100644
index 0000000..b11f3b2
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/replication/thrift/KeyValues.java
@@ -0,0 +1,456 @@
+/*
+ * 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.
+ */
+/**
+ * Autogenerated by Thrift Compiler (0.9.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ *  @generated
+ */
+package org.apache.accumulo.core.replication.thrift;
+
+import org.apache.thrift.scheme.IScheme;
+import org.apache.thrift.scheme.SchemeFactory;
+import org.apache.thrift.scheme.StandardScheme;
+
+import org.apache.thrift.scheme.TupleScheme;
+import org.apache.thrift.protocol.TTupleProtocol;
+import org.apache.thrift.protocol.TProtocolException;
+import org.apache.thrift.EncodingUtils;
+import org.apache.thrift.TException;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.EnumMap;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.EnumSet;
+import java.util.Collections;
+import java.util.BitSet;
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@SuppressWarnings("all") public class KeyValues implements org.apache.thrift.TBase<KeyValues, KeyValues._Fields>, java.io.Serializable, Cloneable {
+  private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("KeyValues");
+
+  private static final org.apache.thrift.protocol.TField KEY_VALUES_FIELD_DESC = new org.apache.thrift.protocol.TField("keyValues", org.apache.thrift.protocol.TType.LIST, (short)1);
+
+  private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
+  static {
+    schemes.put(StandardScheme.class, new KeyValuesStandardSchemeFactory());
+    schemes.put(TupleScheme.class, new KeyValuesTupleSchemeFactory());
+  }
+
+  public List<org.apache.accumulo.core.data.thrift.TKeyValue> keyValues; // required
+
+  /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+  @SuppressWarnings("all") public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+    KEY_VALUES((short)1, "keyValues");
+
+    private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+
+    static {
+      for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        byName.put(field.getFieldName(), field);
+      }
+    }
+
+    /**
+     * Find the _Fields constant that matches fieldId, or null if its not found.
+     */
+    public static _Fields findByThriftId(int fieldId) {
+      switch(fieldId) {
+        case 1: // KEY_VALUES
+          return KEY_VALUES;
+        default:
+          return null;
+      }
+    }
+
+    /**
+     * Find the _Fields constant that matches fieldId, throwing an exception
+     * if it is not found.
+     */
+    public static _Fields findByThriftIdOrThrow(int fieldId) {
+      _Fields fields = findByThriftId(fieldId);
+      if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+      return fields;
+    }
+
+    /**
+     * Find the _Fields constant that matches name, or null if its not found.
+     */
+    public static _Fields findByName(String name) {
+      return byName.get(name);
+    }
+
+    private final short _thriftId;
+    private final String _fieldName;
+
+    _Fields(short thriftId, String fieldName) {
+      _thriftId = thriftId;
+      _fieldName = fieldName;
+    }
+
+    public short getThriftFieldId() {
+      return _thriftId;
+    }
+
+    public String getFieldName() {
+      return _fieldName;
+    }
+  }
+
+  // isset id assignments
+  public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+  static {
+    Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+    tmpMap.put(_Fields.KEY_VALUES, new org.apache.thrift.meta_data.FieldMetaData("keyValues", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+        new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
+            new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.accumulo.core.data.thrift.TKeyValue.class))));
+    metaDataMap = Collections.unmodifiableMap(tmpMap);
+    org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(KeyValues.class, metaDataMap);
+  }
+
+  public KeyValues() {
+  }
+
+  public KeyValues(
+    List<org.apache.accumulo.core.data.thrift.TKeyValue> keyValues)
+  {
+    this();
+    this.keyValues = keyValues;
+  }
+
+  /**
+   * Performs a deep copy on <i>other</i>.
+   */
+  public KeyValues(KeyValues other) {
+    if (other.isSetKeyValues()) {
+      List<org.apache.accumulo.core.data.thrift.TKeyValue> __this__keyValues = new ArrayList<org.apache.accumulo.core.data.thrift.TKeyValue>();
+      for (org.apache.accumulo.core.data.thrift.TKeyValue other_element : other.keyValues) {
+        __this__keyValues.add(new org.apache.accumulo.core.data.thrift.TKeyValue(other_element));
+      }
+      this.keyValues = __this__keyValues;
+    }
+  }
+
+  public KeyValues deepCopy() {
+    return new KeyValues(this);
+  }
+
+  @Override
+  public void clear() {
+    this.keyValues = null;
+  }
+
+  public int getKeyValuesSize() {
+    return (this.keyValues == null) ? 0 : this.keyValues.size();
+  }
+
+  public java.util.Iterator<org.apache.accumulo.core.data.thrift.TKeyValue> getKeyValuesIterator() {
+    return (this.keyValues == null) ? null : this.keyValues.iterator();
+  }
+
+  public void addToKeyValues(org.apache.accumulo.core.data.thrift.TKeyValue elem) {
+    if (this.keyValues == null) {
+      this.keyValues = new ArrayList<org.apache.accumulo.core.data.thrift.TKeyValue>();
+    }
+    this.keyValues.add(elem);
+  }
+
+  public List<org.apache.accumulo.core.data.thrift.TKeyValue> getKeyValues() {
+    return this.keyValues;
+  }
+
+  public KeyValues setKeyValues(List<org.apache.accumulo.core.data.thrift.TKeyValue> keyValues) {
+    this.keyValues = keyValues;
+    return this;
+  }
+
+  public void unsetKeyValues() {
+    this.keyValues = null;
+  }
+
+  /** Returns true if field keyValues is set (has been assigned a value) and false otherwise */
+  public boolean isSetKeyValues() {
+    return this.keyValues != null;
+  }
+
+  public void setKeyValuesIsSet(boolean value) {
+    if (!value) {
+      this.keyValues = null;
+    }
+  }
+
+  public void setFieldValue(_Fields field, Object value) {
+    switch (field) {
+    case KEY_VALUES:
+      if (value == null) {
+        unsetKeyValues();
+      } else {
+        setKeyValues((List<org.apache.accumulo.core.data.thrift.TKeyValue>)value);
+      }
+      break;
+
+    }
+  }
+
+  public Object getFieldValue(_Fields field) {
+    switch (field) {
+    case KEY_VALUES:
+      return getKeyValues();
+
+    }
+    throw new IllegalStateException();
+  }
+
+  /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+  public boolean isSet(_Fields field) {
+    if (field == null) {
+      throw new IllegalArgumentException();
+    }
+
+    switch (field) {
+    case KEY_VALUES:
+      return isSetKeyValues();
+    }
+    throw new IllegalStateException();
+  }
+
+  @Override
+  public boolean equals(Object that) {
+    if (that == null)
+      return false;
+    if (that instanceof KeyValues)
+      return this.equals((KeyValues)that);
+    return false;
+  }
+
+  public boolean equals(KeyValues that) {
+    if (that == null)
+      return false;
+
+    boolean this_present_keyValues = true && this.isSetKeyValues();
+    boolean that_present_keyValues = true && that.isSetKeyValues();
+    if (this_present_keyValues || that_present_keyValues) {
+      if (!(this_present_keyValues && that_present_keyValues))
+        return false;
+      if (!this.keyValues.equals(that.keyValues))
+        return false;
+    }
+
+    return true;
+  }
+
+  @Override
+  public int hashCode() {
+    return 0;
+  }
+
+  public int compareTo(KeyValues other) {
+    if (!getClass().equals(other.getClass())) {
+      return getClass().getName().compareTo(other.getClass().getName());
+    }
+
+    int lastComparison = 0;
+    KeyValues typedOther = (KeyValues)other;
+
+    lastComparison = Boolean.valueOf(isSetKeyValues()).compareTo(typedOther.isSetKeyValues());
+    if (lastComparison != 0) {
+      return lastComparison;
+    }
+    if (isSetKeyValues()) {
+      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.keyValues, typedOther.keyValues);
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+    }
+    return 0;
+  }
+
+  public _Fields fieldForId(int fieldId) {
+    return _Fields.findByThriftId(fieldId);
+  }
+
+  public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+    schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+  }
+
+  public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+    schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
+  }
+
+  @Override
+  public String toString() {
+    StringBuilder sb = new StringBuilder("KeyValues(");
+    boolean first = true;
+
+    sb.append("keyValues:");
+    if (this.keyValues == null) {
+      sb.append("null");
+    } else {
+      sb.append(this.keyValues);
+    }
+    first = false;
+    sb.append(")");
+    return sb.toString();
+  }
+
+  public void validate() throws org.apache.thrift.TException {
+    // check for required fields
+    // check for sub-struct validity
+  }
+
+  private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+    try {
+      write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+    } catch (org.apache.thrift.TException te) {
+      throw new java.io.IOException(te);
+    }
+  }
+
+  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    try {
+      read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+    } catch (org.apache.thrift.TException te) {
+      throw new java.io.IOException(te);
+    }
+  }
+
+  private static class KeyValuesStandardSchemeFactory implements SchemeFactory {
+    public KeyValuesStandardScheme getScheme() {
+      return new KeyValuesStandardScheme();
+    }
+  }
+
+  private static class KeyValuesStandardScheme extends StandardScheme<KeyValues> {
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot, KeyValues struct) throws org.apache.thrift.TException {
+      org.apache.thrift.protocol.TField schemeField;
+      iprot.readStructBegin();
+      while (true)
+      {
+        schemeField = iprot.readFieldBegin();
+        if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+          break;
+        }
+        switch (schemeField.id) {
+          case 1: // KEY_VALUES
+            if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
+              {
+                org.apache.thrift.protocol.TList _list8 = iprot.readListBegin();
+                struct.keyValues = new ArrayList<org.apache.accumulo.core.data.thrift.TKeyValue>(_list8.size);
+                for (int _i9 = 0; _i9 < _list8.size; ++_i9)
+                {
+                  org.apache.accumulo.core.data.thrift.TKeyValue _elem10; // required
+                  _elem10 = new org.apache.accumulo.core.data.thrift.TKeyValue();
+                  _elem10.read(iprot);
+                  struct.keyValues.add(_elem10);
+                }
+                iprot.readListEnd();
+              }
+              struct.setKeyValuesIsSet(true);
+            } else { 
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+            }
+            break;
+          default:
+            org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+        }
+        iprot.readFieldEnd();
+      }
+      iprot.readStructEnd();
+
+      // check for required fields of primitive type, which can't be checked in the validate method
+      struct.validate();
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot, KeyValues struct) throws org.apache.thrift.TException {
+      struct.validate();
+
+      oprot.writeStructBegin(STRUCT_DESC);
+      if (struct.keyValues != null) {
+        oprot.writeFieldBegin(KEY_VALUES_FIELD_DESC);
+        {
+          oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, struct.keyValues.size()));
+          for (org.apache.accumulo.core.data.thrift.TKeyValue _iter11 : struct.keyValues)
+          {
+            _iter11.write(oprot);
+          }
+          oprot.writeListEnd();
+        }
+        oprot.writeFieldEnd();
+      }
+      oprot.writeFieldStop();
+      oprot.writeStructEnd();
+    }
+
+  }
+
+  private static class KeyValuesTupleSchemeFactory implements SchemeFactory {
+    public KeyValuesTupleScheme getScheme() {
+      return new KeyValuesTupleScheme();
+    }
+  }
+
+  private static class KeyValuesTupleScheme extends TupleScheme<KeyValues> {
+
+    @Override
+    public void write(org.apache.thrift.protocol.TProtocol prot, KeyValues struct) throws org.apache.thrift.TException {
+      TTupleProtocol oprot = (TTupleProtocol) prot;
+      BitSet optionals = new BitSet();
+      if (struct.isSetKeyValues()) {
+        optionals.set(0);
+      }
+      oprot.writeBitSet(optionals, 1);
+      if (struct.isSetKeyValues()) {
+        {
+          oprot.writeI32(struct.keyValues.size());
+          for (org.apache.accumulo.core.data.thrift.TKeyValue _iter12 : struct.keyValues)
+          {
+            _iter12.write(oprot);
+          }
+        }
+      }
+    }
+
+    @Override
+    public void read(org.apache.thrift.protocol.TProtocol prot, KeyValues struct) throws org.apache.thrift.TException {
+      TTupleProtocol iprot = (TTupleProtocol) prot;
+      BitSet incoming = iprot.readBitSet(1);
+      if (incoming.get(0)) {
+        {
+          org.apache.thrift.protocol.TList _list13 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
+          struct.keyValues = new ArrayList<org.apache.accumulo.core.data.thrift.TKeyValue>(_list13.size);
+          for (int _i14 = 0; _i14 < _list13.size; ++_i14)
+          {
+            org.apache.accumulo.core.data.thrift.TKeyValue _elem15; // required
+            _elem15 = new org.apache.accumulo.core.data.thrift.TKeyValue();
+            _elem15.read(iprot);
+            struct.keyValues.add(_elem15);
+          }
+        }
+        struct.setKeyValuesIsSet(true);
+      }
+    }
+  }
+
+}
+

http://git-wip-us.apache.org/repos/asf/accumulo/blob/d257001d/core/src/main/java/org/apache/accumulo/core/replication/thrift/RemoteReplication.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/replication/thrift/RemoteReplication.java b/core/src/main/java/org/apache/accumulo/core/replication/thrift/RemoteReplication.java
new file mode 100644
index 0000000..e82240f
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/replication/thrift/RemoteReplication.java
@@ -0,0 +1,1917 @@
+/*
+ * 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.
+ */
+/**
+ * Autogenerated by Thrift Compiler (0.9.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ *  @generated
+ */
+package org.apache.accumulo.core.replication.thrift;
+
+import org.apache.thrift.scheme.IScheme;
+import org.apache.thrift.scheme.SchemeFactory;
+import org.apache.thrift.scheme.StandardScheme;
+
+import org.apache.thrift.scheme.TupleScheme;
+import org.apache.thrift.protocol.TTupleProtocol;
+import org.apache.thrift.protocol.TProtocolException;
+import org.apache.thrift.EncodingUtils;
+import org.apache.thrift.TException;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.EnumMap;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.EnumSet;
+import java.util.Collections;
+import java.util.BitSet;
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@SuppressWarnings("all") public class RemoteReplication {
+
+  public interface Iface {
+
+    public void replicateLog(int remoteTableId, WalEdits data) throws RemoteReplicationException, org.apache.thrift.TException;
+
+    public void replicateKeyValues(int remoteTableId, KeyValues data) throws RemoteReplicationException, org.apache.thrift.TException;
+
+  }
+
+  public interface AsyncIface {
+
+    public void replicateLog(int remoteTableId, WalEdits data, org.apache.thrift.async.AsyncMethodCallback<AsyncClient.replicateLog_call> resultHandler) throws org.apache.thrift.TException;
+
+    public void replicateKeyValues(int remoteTableId, KeyValues data, org.apache.thrift.async.AsyncMethodCallback<AsyncClient.replicateKeyValues_call> resultHandler) throws org.apache.thrift.TException;
+
+  }
+
+  public static class Client extends org.apache.thrift.TServiceClient implements Iface {
+    public static class Factory implements org.apache.thrift.TServiceClientFactory<Client> {
+      public Factory() {}
+      public Client getClient(org.apache.thrift.protocol.TProtocol prot) {
+        return new Client(prot);
+      }
+      public Client getClient(org.apache.thrift.protocol.TProtocol iprot, org.apache.thrift.protocol.TProtocol oprot) {
+        return new Client(iprot, oprot);
+      }
+    }
+
+    public Client(org.apache.thrift.protocol.TProtocol prot)
+    {
+      super(prot, prot);
+    }
+
+    public Client(org.apache.thrift.protocol.TProtocol iprot, org.apache.thrift.protocol.TProtocol oprot) {
+      super(iprot, oprot);
+    }
+
+    public void replicateLog(int remoteTableId, WalEdits data) throws RemoteReplicationException, org.apache.thrift.TException
+    {
+      send_replicateLog(remoteTableId, data);
+      recv_replicateLog();
+    }
+
+    public void send_replicateLog(int remoteTableId, WalEdits data) throws org.apache.thrift.TException
+    {
+      replicateLog_args args = new replicateLog_args();
+      args.setRemoteTableId(remoteTableId);
+      args.setData(data);
+      sendBase("replicateLog", args);
+    }
+
+    public void recv_replicateLog() throws RemoteReplicationException, org.apache.thrift.TException
+    {
+      replicateLog_result result = new replicateLog_result();
+      receiveBase(result, "replicateLog");
+      if (result.e != null) {
+        throw result.e;
+      }
+      return;
+    }
+
+    public void replicateKeyValues(int remoteTableId, KeyValues data) throws RemoteReplicationException, org.apache.thrift.TException
+    {
+      send_replicateKeyValues(remoteTableId, data);
+      recv_replicateKeyValues();
+    }
+
+    public void send_replicateKeyValues(int remoteTableId, KeyValues data) throws org.apache.thrift.TException
+    {
+      replicateKeyValues_args args = new replicateKeyValues_args();
+      args.setRemoteTableId(remoteTableId);
+      args.setData(data);
+      sendBase("replicateKeyValues", args);
+    }
+
+    public void recv_replicateKeyValues() throws RemoteReplicationException, org.apache.thrift.TException
+    {
+      replicateKeyValues_result result = new replicateKeyValues_result();
+      receiveBase(result, "replicateKeyValues");
+      if (result.e != null) {
+        throw result.e;
+      }
+      return;
+    }
+
+  }
+  public static class AsyncClient extends org.apache.thrift.async.TAsyncClient implements AsyncIface {
+    public static class Factory implements org.apache.thrift.async.TAsyncClientFactory<AsyncClient> {
+      private org.apache.thrift.async.TAsyncClientManager clientManager;
+      private org.apache.thrift.protocol.TProtocolFactory protocolFactory;
+      public Factory(org.apache.thrift.async.TAsyncClientManager clientManager, org.apache.thrift.protocol.TProtocolFactory protocolFactory) {
+        this.clientManager = clientManager;
+        this.protocolFactory = protocolFactory;
+      }
+      public AsyncClient getAsyncClient(org.apache.thrift.transport.TNonblockingTransport transport) {
+        return new AsyncClient(protocolFactory, clientManager, transport);
+      }
+    }
+
+    public AsyncClient(org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.async.TAsyncClientManager clientManager, org.apache.thrift.transport.TNonblockingTransport transport) {
+      super(protocolFactory, clientManager, transport);
+    }
+
+    public void replicateLog(int remoteTableId, WalEdits data, org.apache.thrift.async.AsyncMethodCallback<replicateLog_call> resultHandler) throws org.apache.thrift.TException {
+      checkReady();
+      replicateLog_call method_call = new replicateLog_call(remoteTableId, data, resultHandler, this, ___protocolFactory, ___transport);
+      this.___currentMethod = method_call;
+      ___manager.call(method_call);
+    }
+
+    public static class replicateLog_call extends org.apache.thrift.async.TAsyncMethodCall {
+      private int remoteTableId;
+      private WalEdits data;
+      public replicateLog_call(int remoteTableId, WalEdits data, org.apache.thrift.async.AsyncMethodCallback<replicateLog_call> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
+        super(client, protocolFactory, transport, resultHandler, false);
+        this.remoteTableId = remoteTableId;
+        this.data = data;
+      }
+
+      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
+        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("replicateLog", org.apache.thrift.protocol.TMessageType.CALL, 0));
+        replicateLog_args args = new replicateLog_args();
+        args.setRemoteTableId(remoteTableId);
+        args.setData(data);
+        args.write(prot);
+        prot.writeMessageEnd();
+      }
+
+      public void getResult() throws RemoteReplicationException, org.apache.thrift.TException {
+        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
+          throw new IllegalStateException("Method call not finished!");
+        }
+        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
+        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
+        (new Client(prot)).recv_replicateLog();
+      }
+    }
+
+    public void replicateKeyValues(int remoteTableId, KeyValues data, org.apache.thrift.async.AsyncMethodCallback<replicateKeyValues_call> resultHandler) throws org.apache.thrift.TException {
+      checkReady();
+      replicateKeyValues_call method_call = new replicateKeyValues_call(remoteTableId, data, resultHandler, this, ___protocolFactory, ___transport);
+      this.___currentMethod = method_call;
+      ___manager.call(method_call);
+    }
+
+    public static class replicateKeyValues_call extends org.apache.thrift.async.TAsyncMethodCall {
+      private int remoteTableId;
+      private KeyValues data;
+      public replicateKeyValues_call(int remoteTableId, KeyValues data, org.apache.thrift.async.AsyncMethodCallback<replicateKeyValues_call> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
+        super(client, protocolFactory, transport, resultHandler, false);
+        this.remoteTableId = remoteTableId;
+        this.data = data;
+      }
+
+      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
+        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("replicateKeyValues", org.apache.thrift.protocol.TMessageType.CALL, 0));
+        replicateKeyValues_args args = new replicateKeyValues_args();
+        args.setRemoteTableId(remoteTableId);
+        args.setData(data);
+        args.write(prot);
+        prot.writeMessageEnd();
+      }
+
+      public void getResult() throws RemoteReplicationException, org.apache.thrift.TException {
+        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
+          throw new IllegalStateException("Method call not finished!");
+        }
+        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
+        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
+        (new Client(prot)).recv_replicateKeyValues();
+      }
+    }
+
+  }
+
+  public static class Processor<I extends Iface> extends org.apache.thrift.TBaseProcessor<I> implements org.apache.thrift.TProcessor {
+    private static final Logger LOGGER = LoggerFactory.getLogger(Processor.class.getName());
+    public Processor(I iface) {
+      super(iface, getProcessMap(new HashMap<String, org.apache.thrift.ProcessFunction<I, ? extends org.apache.thrift.TBase>>()));
+    }
+
+    protected Processor(I iface, Map<String,  org.apache.thrift.ProcessFunction<I, ? extends  org.apache.thrift.TBase>> processMap) {
+      super(iface, getProcessMap(processMap));
+    }
+
+    private static <I extends Iface> Map<String,  org.apache.thrift.ProcessFunction<I, ? extends  org.apache.thrift.TBase>> getProcessMap(Map<String,  org.apache.thrift.ProcessFunction<I, ? extends  org.apache.thrift.TBase>> processMap) {
+      processMap.put("replicateLog", new replicateLog());
+      processMap.put("replicateKeyValues", new replicateKeyValues());
+      return processMap;
+    }
+
+    public static class replicateLog<I extends Iface> extends org.apache.thrift.ProcessFunction<I, replicateLog_args> {
+      public replicateLog() {
+        super("replicateLog");
+      }
+
+      public replicateLog_args getEmptyArgsInstance() {
+        return new replicateLog_args();
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      public replicateLog_result getResult(I iface, replicateLog_args args) throws org.apache.thrift.TException {
+        replicateLog_result result = new replicateLog_result();
+        try {
+          iface.replicateLog(args.remoteTableId, args.data);
+        } catch (RemoteReplicationException e) {
+          result.e = e;
+        }
+        return result;
+      }
+    }
+
+    public static class replicateKeyValues<I extends Iface> extends org.apache.thrift.ProcessFunction<I, replicateKeyValues_args> {
+      public replicateKeyValues() {
+        super("replicateKeyValues");
+      }
+
+      public replicateKeyValues_args getEmptyArgsInstance() {
+        return new replicateKeyValues_args();
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      public replicateKeyValues_result getResult(I iface, replicateKeyValues_args args) throws org.apache.thrift.TException {
+        replicateKeyValues_result result = new replicateKeyValues_result();
+        try {
+          iface.replicateKeyValues(args.remoteTableId, args.data);
+        } catch (RemoteReplicationException e) {
+          result.e = e;
+        }
+        return result;
+      }
+    }
+
+  }
+
+  public static class replicateLog_args implements org.apache.thrift.TBase<replicateLog_args, replicateLog_args._Fields>, java.io.Serializable, Cloneable   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("replicateLog_args");
+
+    private static final org.apache.thrift.protocol.TField REMOTE_TABLE_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("remoteTableId", org.apache.thrift.protocol.TType.I32, (short)1);
+    private static final org.apache.thrift.protocol.TField DATA_FIELD_DESC = new org.apache.thrift.protocol.TField("data", org.apache.thrift.protocol.TType.STRUCT, (short)2);
+
+    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
+    static {
+      schemes.put(StandardScheme.class, new replicateLog_argsStandardSchemeFactory());
+      schemes.put(TupleScheme.class, new replicateLog_argsTupleSchemeFactory());
+    }
+
+    public int remoteTableId; // required
+    public WalEdits data; // required
+
+    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+    @SuppressWarnings("all") public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+      REMOTE_TABLE_ID((short)1, "remoteTableId"),
+      DATA((short)2, "data");
+
+      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+
+      static {
+        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+          byName.put(field.getFieldName(), field);
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, or null if its not found.
+       */
+      public static _Fields findByThriftId(int fieldId) {
+        switch(fieldId) {
+          case 1: // REMOTE_TABLE_ID
+            return REMOTE_TABLE_ID;
+          case 2: // DATA
+            return DATA;
+          default:
+            return null;
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, throwing an exception
+       * if it is not found.
+       */
+      public static _Fields findByThriftIdOrThrow(int fieldId) {
+        _Fields fields = findByThriftId(fieldId);
+        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    private static final int __REMOTETABLEID_ISSET_ID = 0;
+    private byte __isset_bitfield = 0;
+    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    static {
+      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+      tmpMap.put(_Fields.REMOTE_TABLE_ID, new org.apache.thrift.meta_data.FieldMetaData("remoteTableId", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
+      tmpMap.put(_Fields.DATA, new org.apache.thrift.meta_data.FieldMetaData("data", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, WalEdits.class)));
+      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(replicateLog_args.class, metaDataMap);
+    }
+
+    public replicateLog_args() {
+    }
+
+    public replicateLog_args(
+      int remoteTableId,
+      WalEdits data)
+    {
+      this();
+      this.remoteTableId = remoteTableId;
+      setRemoteTableIdIsSet(true);
+      this.data = data;
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public replicateLog_args(replicateLog_args other) {
+      __isset_bitfield = other.__isset_bitfield;
+      this.remoteTableId = other.remoteTableId;
+      if (other.isSetData()) {
+        this.data = new WalEdits(other.data);
+      }
+    }
+
+    public replicateLog_args deepCopy() {
+      return new replicateLog_args(this);
+    }
+
+    @Override
+    public void clear() {
+      setRemoteTableIdIsSet(false);
+      this.remoteTableId = 0;
+      this.data = null;
+    }
+
+    public int getRemoteTableId() {
+      return this.remoteTableId;
+    }
+
+    public replicateLog_args setRemoteTableId(int remoteTableId) {
+      this.remoteTableId = remoteTableId;
+      setRemoteTableIdIsSet(true);
+      return this;
+    }
+
+    public void unsetRemoteTableId() {
+      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __REMOTETABLEID_ISSET_ID);
+    }
+
+    /** Returns true if field remoteTableId is set (has been assigned a value) and false otherwise */
+    public boolean isSetRemoteTableId() {
+      return EncodingUtils.testBit(__isset_bitfield, __REMOTETABLEID_ISSET_ID);
+    }
+
+    public void setRemoteTableIdIsSet(boolean value) {
+      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __REMOTETABLEID_ISSET_ID, value);
+    }
+
+    public WalEdits getData() {
+      return this.data;
+    }
+
+    public replicateLog_args setData(WalEdits data) {
+      this.data = data;
+      return this;
+    }
+
+    public void unsetData() {
+      this.data = null;
+    }
+
+    /** Returns true if field data is set (has been assigned a value) and false otherwise */
+    public boolean isSetData() {
+      return this.data != null;
+    }
+
+    public void setDataIsSet(boolean value) {
+      if (!value) {
+        this.data = null;
+      }
+    }
+
+    public void setFieldValue(_Fields field, Object value) {
+      switch (field) {
+      case REMOTE_TABLE_ID:
+        if (value == null) {
+          unsetRemoteTableId();
+        } else {
+          setRemoteTableId((Integer)value);
+        }
+        break;
+
+      case DATA:
+        if (value == null) {
+          unsetData();
+        } else {
+          setData((WalEdits)value);
+        }
+        break;
+
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      case REMOTE_TABLE_ID:
+        return Integer.valueOf(getRemoteTableId());
+
+      case DATA:
+        return getData();
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case REMOTE_TABLE_ID:
+        return isSetRemoteTableId();
+      case DATA:
+        return isSetData();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof replicateLog_args)
+        return this.equals((replicateLog_args)that);
+      return false;
+    }
+
+    public boolean equals(replicateLog_args that) {
+      if (that == null)
+        return false;
+
+      boolean this_present_remoteTableId = true;
+      boolean that_present_remoteTableId = true;
+      if (this_present_remoteTableId || that_present_remoteTableId) {
+        if (!(this_present_remoteTableId && that_present_remoteTableId))
+          return false;
+        if (this.remoteTableId != that.remoteTableId)
+          return false;
+      }
+
+      boolean this_present_data = true && this.isSetData();
+      boolean that_present_data = true && that.isSetData();
+      if (this_present_data || that_present_data) {
+        if (!(this_present_data && that_present_data))
+          return false;
+        if (!this.data.equals(that.data))
+          return false;
+      }
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      return 0;
+    }
+
+    public int compareTo(replicateLog_args other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+      replicateLog_args typedOther = (replicateLog_args)other;
+
+      lastComparison = Boolean.valueOf(isSetRemoteTableId()).compareTo(typedOther.isSetRemoteTableId());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetRemoteTableId()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.remoteTableId, typedOther.remoteTableId);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetData()).compareTo(typedOther.isSetData());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetData()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.data, typedOther.data);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      return 0;
+    }
+
+    public _Fields fieldForId(int fieldId) {
+      return _Fields.findByThriftId(fieldId);
+    }
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
+    }
+
+    @Override
+    public String toString() {
+      StringBuilder sb = new StringBuilder("replicateLog_args(");
+      boolean first = true;
+
+      sb.append("remoteTableId:");
+      sb.append(this.remoteTableId);
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("data:");
+      if (this.data == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.data);
+      }
+      first = false;
+      sb.append(")");
+      return sb.toString();
+    }
+
+    public void validate() throws org.apache.thrift.TException {
+      // check for required fields
+      // check for sub-struct validity
+      if (data != null) {
+        data.validate();
+      }
+    }
+
+    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+      try {
+        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+      try {
+        // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor.
+        __isset_bitfield = 0;
+        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private static class replicateLog_argsStandardSchemeFactory implements SchemeFactory {
+      public replicateLog_argsStandardScheme getScheme() {
+        return new replicateLog_argsStandardScheme();
+      }
+    }
+
+    private static class replicateLog_argsStandardScheme extends StandardScheme<replicateLog_args> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, replicateLog_args struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TField schemeField;
+        iprot.readStructBegin();
+        while (true)
+        {
+          schemeField = iprot.readFieldBegin();
+          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+            break;
+          }
+          switch (schemeField.id) {
+            case 1: // REMOTE_TABLE_ID
+              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
+                struct.remoteTableId = iprot.readI32();
+                struct.setRemoteTableIdIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 2: // DATA
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.data = new WalEdits();
+                struct.data.read(iprot);
+                struct.setDataIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            default:
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+          }
+          iprot.readFieldEnd();
+        }
+        iprot.readStructEnd();
+
+        // check for required fields of primitive type, which can't be checked in the validate method
+        struct.validate();
+      }
+
+      public void write(org.apache.thrift.protocol.TProtocol oprot, replicateLog_args struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        oprot.writeFieldBegin(REMOTE_TABLE_ID_FIELD_DESC);
+        oprot.writeI32(struct.remoteTableId);
+        oprot.writeFieldEnd();
+        if (struct.data != null) {
+          oprot.writeFieldBegin(DATA_FIELD_DESC);
+          struct.data.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        oprot.writeFieldStop();
+        oprot.writeStructEnd();
+      }
+
+    }
+
+    private static class replicateLog_argsTupleSchemeFactory implements SchemeFactory {
+      public replicateLog_argsTupleScheme getScheme() {
+        return new replicateLog_argsTupleScheme();
+      }
+    }
+
+    private static class replicateLog_argsTupleScheme extends TupleScheme<replicateLog_args> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, replicateLog_args struct) throws org.apache.thrift.TException {
+        TTupleProtocol oprot = (TTupleProtocol) prot;
+        BitSet optionals = new BitSet();
+        if (struct.isSetRemoteTableId()) {
+          optionals.set(0);
+        }
+        if (struct.isSetData()) {
+          optionals.set(1);
+        }
+        oprot.writeBitSet(optionals, 2);
+        if (struct.isSetRemoteTableId()) {
+          oprot.writeI32(struct.remoteTableId);
+        }
+        if (struct.isSetData()) {
+          struct.data.write(oprot);
+        }
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, replicateLog_args struct) throws org.apache.thrift.TException {
+        TTupleProtocol iprot = (TTupleProtocol) prot;
+        BitSet incoming = iprot.readBitSet(2);
+        if (incoming.get(0)) {
+          struct.remoteTableId = iprot.readI32();
+          struct.setRemoteTableIdIsSet(true);
+        }
+        if (incoming.get(1)) {
+          struct.data = new WalEdits();
+          struct.data.read(iprot);
+          struct.setDataIsSet(true);
+        }
+      }
+    }
+
+  }
+
+  public static class replicateLog_result implements org.apache.thrift.TBase<replicateLog_result, replicateLog_result._Fields>, java.io.Serializable, Cloneable   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("replicateLog_result");
+
+    private static final org.apache.thrift.protocol.TField E_FIELD_DESC = new org.apache.thrift.protocol.TField("e", org.apache.thrift.protocol.TType.STRUCT, (short)1);
+
+    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
+    static {
+      schemes.put(StandardScheme.class, new replicateLog_resultStandardSchemeFactory());
+      schemes.put(TupleScheme.class, new replicateLog_resultTupleSchemeFactory());
+    }
+
+    public RemoteReplicationException e; // required
+
+    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+    @SuppressWarnings("all") public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+      E((short)1, "e");
+
+      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+
+      static {
+        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+          byName.put(field.getFieldName(), field);
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, or null if its not found.
+       */
+      public static _Fields findByThriftId(int fieldId) {
+        switch(fieldId) {
+          case 1: // E
+            return E;
+          default:
+            return null;
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, throwing an exception
+       * if it is not found.
+       */
+      public static _Fields findByThriftIdOrThrow(int fieldId) {
+        _Fields fields = findByThriftId(fieldId);
+        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    static {
+      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+      tmpMap.put(_Fields.E, new org.apache.thrift.meta_data.FieldMetaData("e", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
+      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(replicateLog_result.class, metaDataMap);
+    }
+
+    public replicateLog_result() {
+    }
+
+    public replicateLog_result(
+      RemoteReplicationException e)
+    {
+      this();
+      this.e = e;
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public replicateLog_result(replicateLog_result other) {
+      if (other.isSetE()) {
+        this.e = new RemoteReplicationException(other.e);
+      }
+    }
+
+    public replicateLog_result deepCopy() {
+      return new replicateLog_result(this);
+    }
+
+    @Override
+    public void clear() {
+      this.e = null;
+    }
+
+    public RemoteReplicationException getE() {
+      return this.e;
+    }
+
+    public replicateLog_result setE(RemoteReplicationException e) {
+      this.e = e;
+      return this;
+    }
+
+    public void unsetE() {
+      this.e = null;
+    }
+
+    /** Returns true if field e is set (has been assigned a value) and false otherwise */
+    public boolean isSetE() {
+      return this.e != null;
+    }
+
+    public void setEIsSet(boolean value) {
+      if (!value) {
+        this.e = null;
+      }
+    }
+
+    public void setFieldValue(_Fields field, Object value) {
+      switch (field) {
+      case E:
+        if (value == null) {
+          unsetE();
+        } else {
+          setE((RemoteReplicationException)value);
+        }
+        break;
+
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      case E:
+        return getE();
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case E:
+        return isSetE();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof replicateLog_result)
+        return this.equals((replicateLog_result)that);
+      return false;
+    }
+
+    public boolean equals(replicateLog_result that) {
+      if (that == null)
+        return false;
+
+      boolean this_present_e = true && this.isSetE();
+      boolean that_present_e = true && that.isSetE();
+      if (this_present_e || that_present_e) {
+        if (!(this_present_e && that_present_e))
+          return false;
+        if (!this.e.equals(that.e))
+          return false;
+      }
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      return 0;
+    }
+
+    public int compareTo(replicateLog_result other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+      replicateLog_result typedOther = (replicateLog_result)other;
+
+      lastComparison = Boolean.valueOf(isSetE()).compareTo(typedOther.isSetE());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetE()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.e, typedOther.e);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      return 0;
+    }
+
+    public _Fields fieldForId(int fieldId) {
+      return _Fields.findByThriftId(fieldId);
+    }
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
+      }
+
+    @Override
+    public String toString() {
+      StringBuilder sb = new StringBuilder("replicateLog_result(");
+      boolean first = true;
+
+      sb.append("e:");
+      if (this.e == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.e);
+      }
+      first = false;
+      sb.append(")");
+      return sb.toString();
+    }
+
+    public void validate() throws org.apache.thrift.TException {
+      // check for required fields
+      // check for sub-struct validity
+    }
+
+    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+      try {
+        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+      try {
+        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private static class replicateLog_resultStandardSchemeFactory implements SchemeFactory {
+      public replicateLog_resultStandardScheme getScheme() {
+        return new replicateLog_resultStandardScheme();
+      }
+    }
+
+    private static class replicateLog_resultStandardScheme extends StandardScheme<replicateLog_result> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, replicateLog_result struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TField schemeField;
+        iprot.readStructBegin();
+        while (true)
+        {
+          schemeField = iprot.readFieldBegin();
+          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+            break;
+          }
+          switch (schemeField.id) {
+            case 1: // E
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.e = new RemoteReplicationException();
+                struct.e.read(iprot);
+                struct.setEIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            default:
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+          }
+          iprot.readFieldEnd();
+        }
+        iprot.readStructEnd();
+
+        // check for required fields of primitive type, which can't be checked in the validate method
+        struct.validate();
+      }
+
+      public void write(org.apache.thrift.protocol.TProtocol oprot, replicateLog_result struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        if (struct.e != null) {
+          oprot.writeFieldBegin(E_FIELD_DESC);
+          struct.e.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        oprot.writeFieldStop();
+        oprot.writeStructEnd();
+      }
+
+    }
+
+    private static class replicateLog_resultTupleSchemeFactory implements SchemeFactory {
+      public replicateLog_resultTupleScheme getScheme() {
+        return new replicateLog_resultTupleScheme();
+      }
+    }
+
+    private static class replicateLog_resultTupleScheme extends TupleScheme<replicateLog_result> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, replicateLog_result struct) throws org.apache.thrift.TException {
+        TTupleProtocol oprot = (TTupleProtocol) prot;
+        BitSet optionals = new BitSet();
+        if (struct.isSetE()) {
+          optionals.set(0);
+        }
+        oprot.writeBitSet(optionals, 1);
+        if (struct.isSetE()) {
+          struct.e.write(oprot);
+        }
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, replicateLog_result struct) throws org.apache.thrift.TException {
+        TTupleProtocol iprot = (TTupleProtocol) prot;
+        BitSet incoming = iprot.readBitSet(1);
+        if (incoming.get(0)) {
+          struct.e = new RemoteReplicationException();
+          struct.e.read(iprot);
+          struct.setEIsSet(true);
+        }
+      }
+    }
+
+  }
+
+  public static class replicateKeyValues_args implements org.apache.thrift.TBase<replicateKeyValues_args, replicateKeyValues_args._Fields>, java.io.Serializable, Cloneable   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("replicateKeyValues_args");
+
+    private static final org.apache.thrift.protocol.TField REMOTE_TABLE_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("remoteTableId", org.apache.thrift.protocol.TType.I32, (short)1);
+    private static final org.apache.thrift.protocol.TField DATA_FIELD_DESC = new org.apache.thrift.protocol.TField("data", org.apache.thrift.protocol.TType.STRUCT, (short)2);
+
+    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
+    static {
+      schemes.put(StandardScheme.class, new replicateKeyValues_argsStandardSchemeFactory());
+      schemes.put(TupleScheme.class, new replicateKeyValues_argsTupleSchemeFactory());
+    }
+
+    public int remoteTableId; // required
+    public KeyValues data; // required
+
+    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+    @SuppressWarnings("all") public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+      REMOTE_TABLE_ID((short)1, "remoteTableId"),
+      DATA((short)2, "data");
+
+      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+
+      static {
+        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+          byName.put(field.getFieldName(), field);
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, or null if its not found.
+       */
+      public static _Fields findByThriftId(int fieldId) {
+        switch(fieldId) {
+          case 1: // REMOTE_TABLE_ID
+            return REMOTE_TABLE_ID;
+          case 2: // DATA
+            return DATA;
+          default:
+            return null;
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, throwing an exception
+       * if it is not found.
+       */
+      public static _Fields findByThriftIdOrThrow(int fieldId) {
+        _Fields fields = findByThriftId(fieldId);
+        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    private static final int __REMOTETABLEID_ISSET_ID = 0;
+    private byte __isset_bitfield = 0;
+    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    static {
+      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+      tmpMap.put(_Fields.REMOTE_TABLE_ID, new org.apache.thrift.meta_data.FieldMetaData("remoteTableId", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
+      tmpMap.put(_Fields.DATA, new org.apache.thrift.meta_data.FieldMetaData("data", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, KeyValues.class)));
+      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(replicateKeyValues_args.class, metaDataMap);
+    }
+
+    public replicateKeyValues_args() {
+    }
+
+    public replicateKeyValues_args(
+      int remoteTableId,
+      KeyValues data)
+    {
+      this();
+      this.remoteTableId = remoteTableId;
+      setRemoteTableIdIsSet(true);
+      this.data = data;
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public replicateKeyValues_args(replicateKeyValues_args other) {
+      __isset_bitfield = other.__isset_bitfield;
+      this.remoteTableId = other.remoteTableId;
+      if (other.isSetData()) {
+        this.data = new KeyValues(other.data);
+      }
+    }
+
+    public replicateKeyValues_args deepCopy() {
+      return new replicateKeyValues_args(this);
+    }
+
+    @Override
+    public void clear() {
+      setRemoteTableIdIsSet(false);
+      this.remoteTableId = 0;
+      this.data = null;
+    }
+
+    public int getRemoteTableId() {
+      return this.remoteTableId;
+    }
+
+    public replicateKeyValues_args setRemoteTableId(int remoteTableId) {
+      this.remoteTableId = remoteTableId;
+      setRemoteTableIdIsSet(true);
+      return this;
+    }
+
+    public void unsetRemoteTableId() {
+      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __REMOTETABLEID_ISSET_ID);
+    }
+
+    /** Returns true if field remoteTableId is set (has been assigned a value) and false otherwise */
+    public boolean isSetRemoteTableId() {
+      return EncodingUtils.testBit(__isset_bitfield, __REMOTETABLEID_ISSET_ID);
+    }
+
+    public void setRemoteTableIdIsSet(boolean value) {
+      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __REMOTETABLEID_ISSET_ID, value);
+    }
+
+    public KeyValues getData() {
+      return this.data;
+    }
+
+    public replicateKeyValues_args setData(KeyValues data) {
+      this.data = data;
+      return this;
+    }
+
+    public void unsetData() {
+      this.data = null;
+    }
+
+    /** Returns true if field data is set (has been assigned a value) and false otherwise */
+    public boolean isSetData() {
+      return this.data != null;
+    }
+
+    public void setDataIsSet(boolean value) {
+      if (!value) {
+        this.data = null;
+      }
+    }
+
+    public void setFieldValue(_Fields field, Object value) {
+      switch (field) {
+      case REMOTE_TABLE_ID:
+        if (value == null) {
+          unsetRemoteTableId();
+        } else {
+          setRemoteTableId((Integer)value);
+        }
+        break;
+
+      case DATA:
+        if (value == null) {
+          unsetData();
+        } else {
+          setData((KeyValues)value);
+        }
+        break;
+
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      case REMOTE_TABLE_ID:
+        return Integer.valueOf(getRemoteTableId());
+
+      case DATA:
+        return getData();
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case REMOTE_TABLE_ID:
+        return isSetRemoteTableId();
+      case DATA:
+        return isSetData();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof replicateKeyValues_args)
+        return this.equals((replicateKeyValues_args)that);
+      return false;
+    }
+
+    public boolean equals(replicateKeyValues_args that) {
+      if (that == null)
+        return false;
+
+      boolean this_present_remoteTableId = true;
+      boolean that_present_remoteTableId = true;
+      if (this_present_remoteTableId || that_present_remoteTableId) {
+        if (!(this_present_remoteTableId && that_present_remoteTableId))
+          return false;
+        if (this.remoteTableId != that.remoteTableId)
+          return false;
+      }
+
+      boolean this_present_data = true && this.isSetData();
+      boolean that_present_data = true && that.isSetData();
+      if (this_present_data || that_present_data) {
+        if (!(this_present_data && that_present_data))
+          return false;
+        if (!this.data.equals(that.data))
+          return false;
+      }
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      return 0;
+    }
+
+    public int compareTo(replicateKeyValues_args other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+      replicateKeyValues_args typedOther = (replicateKeyValues_args)other;
+
+      lastComparison = Boolean.valueOf(isSetRemoteTableId()).compareTo(typedOther.isSetRemoteTableId());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetRemoteTableId()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.remoteTableId, typedOther.remoteTableId);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetData()).compareTo(typedOther.isSetData());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetData()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.data, typedOther.data);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      return 0;
+    }
+
+    public _Fields fieldForId(int fieldId) {
+      return _Fields.findByThriftId(fieldId);
+    }
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
+    }
+
+    @Override
+    public String toString() {
+      StringBuilder sb = new StringBuilder("replicateKeyValues_args(");
+      boolean first = true;
+
+      sb.append("remoteTableId:");
+      sb.append(this.remoteTableId);
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("data:");
+      if (this.data == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.data);
+      }
+      first = false;
+      sb.append(")");
+      return sb.toString();
+    }
+
+    public void validate() throws org.apache.thrift.TException {
+      // check for required fields
+      // check for sub-struct validity
+      if (data != null) {
+        data.validate();
+      }
+    }
+
+    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+      try {
+        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+      try {
+        // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor.
+        __isset_bitfield = 0;
+        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private static class replicateKeyValues_argsStandardSchemeFactory implements SchemeFactory {
+      public replicateKeyValues_argsStandardScheme getScheme() {
+        return new replicateKeyValues_argsStandardScheme();
+      }
+    }
+
+    private static class replicateKeyValues_argsStandardScheme extends StandardScheme<replicateKeyValues_args> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, replicateKeyValues_args struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TField schemeField;
+        iprot.readStructBegin();
+        while (true)
+        {
+          schemeField = iprot.readFieldBegin();
+          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+            break;
+          }
+          switch (schemeField.id) {
+            case 1: // REMOTE_TABLE_ID
+              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
+                struct.remoteTableId = iprot.readI32();
+                struct.setRemoteTableIdIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 2: // DATA
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.data = new KeyValues();
+                struct.data.read(iprot);
+                struct.setDataIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            default:
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+          }
+          iprot.readFieldEnd();
+        }
+        iprot.readStructEnd();
+
+        // check for required fields of primitive type, which can't be checked in the validate method
+        struct.validate();
+      }
+
+      public void write(org.apache.thrift.protocol.TProtocol oprot, replicateKeyValues_args struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        oprot.writeFieldBegin(REMOTE_TABLE_ID_FIELD_DESC);
+        oprot.writeI32(struct.remoteTableId);
+        oprot.writeFieldEnd();
+        if (struct.data != null) {
+          oprot.writeFieldBegin(DATA_FIELD_DESC);
+          struct.data.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        oprot.writeFieldStop();
+        oprot.writeStructEnd();
+      }
+
+    }
+
+    private static class replicateKeyValues_argsTupleSchemeFactory implements SchemeFactory {
+      public replicateKeyValues_argsTupleScheme getScheme() {
+        return new replicateKeyValues_argsTupleScheme();
+      }
+    }
+
+    private static class replicateKeyValues_argsTupleScheme extends TupleScheme<replicateKeyValues_args> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, replicateKeyValues_args struct) throws org.apache.thrift.TException {
+        TTupleProtocol oprot = (TTupleProtocol) prot;
+        BitSet optionals = new BitSet();
+        if (struct.isSetRemoteTableId()) {
+          optionals.set(0);
+        }
+        if (struct.isSetData()) {
+          optionals.set(1);
+        }
+        oprot.writeBitSet(optionals, 2);
+        if (struct.isSetRemoteTableId()) {
+          oprot.writeI32(struct.remoteTableId);
+        }
+        if (struct.isSetData()) {
+          struct.data.write(oprot);
+        }
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, replicateKeyValues_args struct) throws org.apache.thrift.TException {
+        TTupleProtocol iprot = (TTupleProtocol) prot;
+        BitSet incoming = iprot.readBitSet(2);
+        if (incoming.get(0)) {
+          struct.remoteTableId = iprot.readI32();
+          struct.setRemoteTableIdIsSet(true);
+        }
+        if (incoming.get(1)) {
+          struct.data = new KeyValues();
+          struct.data.read(iprot);
+          struct.setDataIsSet(true);
+        }
+      }
+    }
+
+  }
+
+  public static class replicateKeyValues_result implements org.apache.thrift.TBase<replicateKeyValues_result, replicateKeyValues_result._Fields>, java.io.Serializable, Cloneable   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("replicateKeyValues_result");
+
+    private static final org.apache.thrift.protocol.TField E_FIELD_DESC = new org.apache.thrift.protocol.TField("e", org.apache.thrift.protocol.TType.STRUCT, (short)1);
+
+    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
+    static {
+      schemes.put(StandardScheme.class, new replicateKeyValues_resultStandardSchemeFactory());
+      schemes.put(TupleScheme.class, new replicateKeyValues_resultTupleSchemeFactory());
+    }
+
+    public RemoteReplicationException e; // required
+
+    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+    @SuppressWarnings("all") public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+      E((short)1, "e");
+
+      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+
+      static {
+        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+          byName.put(field.getFieldName(), field);
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, or null if its not found.
+       */
+      public static _Fields findByThriftId(int fieldId) {
+        switch(fieldId) {
+          case 1: // E
+            return E;
+          default:
+            return null;
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, throwing an exception
+       * if it is not found.
+       */
+      public static _Fields findByThriftIdOrThrow(int fieldId) {
+        _Fields fields = findByThriftId(fieldId);
+        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    static {
+      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+      tmpMap.put(_Fields.E, new org.apache.thrift.meta_data.FieldMetaData("e", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
+      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(replicateKeyValues_result.class, metaDataMap);
+    }
+
+    public replicateKeyValues_result() {
+    }
+
+    public replicateKeyValues_result(
+      RemoteReplicationException e)
+    {
+      this();
+      this.e = e;
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public replicateKeyValues_result(replicateKeyValues_result other) {
+      if (other.isSetE()) {
+        this.e = new RemoteReplicationException(other.e);
+      }
+    }
+
+    public replicateKeyValues_result deepCopy() {
+      return new replicateKeyValues_result(this);
+    }
+
+    @Override
+    public void clear() {
+      this.e = null;
+    }
+
+    public RemoteReplicationException getE() {
+      return this.e;
+    }
+
+    public replicateKeyValues_result setE(RemoteReplicationException e) {
+      this.e = e;
+      return this;
+    }
+
+    public void unsetE() {
+      this.e = null;
+    }
+
+    /** Returns true if field e is set (has been assigned a value) and false otherwise */
+    public boolean isSetE() {
+      return this.e != null;
+    }
+
+    public void setEIsSet(boolean value) {
+      if (!value) {
+        this.e = null;
+      }
+    }
+
+    public void setFieldValue(_Fields field, Object value) {
+      switch (field) {
+      case E:
+        if (value == null) {
+          unsetE();
+        } else {
+          setE((RemoteReplicationException)value);
+        }
+        break;
+
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      case E:
+        return getE();
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case E:
+        return isSetE();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof replicateKeyValues_result)
+        return this.equals((replicateKeyValues_result)that);
+      return false;
+    }
+
+    public boolean equals(replicateKeyValues_result that) {
+      if (that == null)
+        return false;
+
+      boolean this_present_e = true && this.isSetE();
+      boolean that_present_e = true && that.isSetE();
+      if (this_present_e || that_present_e) {
+        if (!(this_present_e && that_present_e))
+          return false;
+        if (!this.e.equals(that.e))
+          return false;
+      }
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      return 0;
+    }
+
+    public int compareTo(replicateKeyValues_result other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+      replicateKeyValues_result typedOther = (replicateKeyValues_result)other;
+
+      lastComparison = Boolean.valueOf(isSetE()).compareTo(typedOther.isSetE());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetE()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.e, typedOther.e);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      return 0;
+    }
+
+    public _Fields fieldForId(int fieldId) {
+      return _Fields.findByThriftId(fieldId);
+    }
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
+      }
+
+    @Override
+    public String toString() {
+      StringBuilder sb = new StringBuilder("replicateKeyValues_result(");
+      boolean first = true;
+
+      sb.append("e:");
+      if (this.e == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.e);
+      }
+      first = false;
+      sb.append(")");
+      return sb.toString();
+    }
+
+    public void validate() throws org.apache.thrift.TException {
+      // check for required fields
+      // check for sub-struct validity
+    }
+
+    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+      try {
+        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+      try {
+        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private static class replicateKeyValues_resultStandardSchemeFactory implements SchemeFactory {
+      public replicateKeyValues_resultStandardScheme getScheme() {
+        return new replicateKeyValues_resultStandardScheme();
+      }
+    }
+
+    private static class replicateKeyValues_resultStandardScheme extends StandardScheme<replicateKeyValues_result> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, replicateKeyValues_result struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TField schemeField;
+        iprot.readStructBegin();
+        while (true)
+        {
+          schemeField = iprot.readFieldBegin();
+          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+            break;
+          }
+          switch (schemeField.id) {
+            case 1: // E
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.e = new RemoteReplicationException();
+                struct.e.read(iprot);
+                struct.setEIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            default:
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+          }
+          iprot.readFieldEnd();
+        }
+        iprot.readStructEnd();
+
+        // check for required fields of primitive type, which can't be checked in the validate method
+        struct.validate();
+      }
+
+      public void write(org.apache.thrift.protocol.TProtocol oprot, replicateKeyValues_result struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        if (struct.e != null) {
+          oprot.writeFieldBegin(E_FIELD_DESC);
+          struct.e.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        oprot.writeFieldStop();
+        oprot.writeStructEnd();
+      }
+
+    }
+
+    private static class replicateKeyValues_resultTupleSchemeFactory implements SchemeFactory {
+      public replicateKeyValues_resultTupleScheme getScheme() {
+        return new replicateKeyValues_resultTupleScheme();
+      }
+    }
+
+    private static class replicateKeyValues_resultTupleScheme extends TupleScheme<replicateKeyValues_result> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, replicateKeyValues_result struct) throws org.apache.thrift.TException {
+        TTupleProtocol oprot = (TTupleProtocol) prot;
+        BitSet optionals = new BitSet();
+        if (struct.isSetE()) {
+          optionals.set(0);
+        }
+        oprot.writeBitSet(optionals, 1);
+        if (struct.isSetE()) {
+          struct.e.write(oprot);
+        }
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, replicateKeyValues_result struct) throws org.apache.thrift.TException {
+        TTupleProtocol iprot = (TTupleProtocol) prot;
+        BitSet incoming = iprot.readBitSet(1);
+        if (incoming.get(0)) {
+          struct.e = new RemoteReplicationException();
+          struct.e.read(iprot);
+          struct.setEIsSet(true);
+        }
+      }
+    }
+
+  }
+
+}


[30/53] [abbrv] Revert "ACCUMULO-1897 Move shell into new package and module"

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/FormatterCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/FormatterCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/FormatterCommand.java
new file mode 100644
index 0000000..631c6e6
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/FormatterCommand.java
@@ -0,0 +1,69 @@
+/*
+ * 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.accumulo.core.util.shell.commands;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.conf.Property;
+import org.apache.accumulo.core.util.format.Formatter;
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+
+public class FormatterCommand extends ShellPluginConfigurationCommand {
+  
+  private Option interpeterOption;
+
+  public FormatterCommand() {
+    super("formatter", Property.TABLE_FORMATTER_CLASS, "f");
+  }
+
+  @Override
+  public String description() {
+    return "specifies a formatter to use for displaying table entries";
+  }
+
+  public static Class<? extends Formatter> getCurrentFormatter(final String tableName, final Shell shellState) {
+    return ShellPluginConfigurationCommand.getPluginClass(tableName, shellState, Formatter.class, Property.TABLE_FORMATTER_CLASS);
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options options = super.getOptions();
+    
+    interpeterOption = new Option("i", "interpeter", false, "configure class as interpreter also");
+    
+    options.addOption(interpeterOption);
+    
+    return options;
+  }
+  
+  protected void setPlugin(final CommandLine cl, final Shell shellState, final String tableName, final String className) throws AccumuloException, AccumuloSecurityException {
+    super.setPlugin(cl, shellState, tableName, className);
+    if (cl.hasOption(interpeterOption.getOpt())) {
+      shellState.getConnector().tableOperations().setProperty(tableName, Property.TABLE_INTERPRETER_CLASS.toString(), className);
+    }
+  }
+  
+  protected void removePlugin(final CommandLine cl, final Shell shellState, final String tableName) throws AccumuloException, AccumuloSecurityException {
+    super.removePlugin(cl, shellState, tableName);
+    if (cl.hasOption(interpeterOption.getOpt())) {
+      shellState.getConnector().tableOperations().removeProperty(tableName, Property.TABLE_INTERPRETER_CLASS.toString());
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/GetAuthsCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/GetAuthsCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/GetAuthsCommand.java
new file mode 100644
index 0000000..e40a83f
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/GetAuthsCommand.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.accumulo.core.util.shell.commands;
+
+import java.io.IOException;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.security.Authorizations;
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.core.util.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+import org.apache.commons.lang.StringUtils;
+
+public class GetAuthsCommand extends Command {
+  private Option userOpt;
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException, IOException {
+    final String user = cl.getOptionValue(userOpt.getOpt(), shellState.getConnector().whoami());
+    // Sort authorizations
+    Authorizations auths = shellState.getConnector().securityOperations().getUserAuthorizations(user);
+    SortedSet<String> set = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
+    for (byte[] auth : auths) {
+      set.add(new String(auth));
+    }
+    shellState.getReader().println(StringUtils.join(set, ','));
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "displays the maximum scan authorizations for a user";
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+    userOpt = new Option(Shell.userOption, "user", true, "user to operate on");
+    userOpt.setArgName("user");
+    o.addOption(userOpt);
+    return o;
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/GetGroupsCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/GetGroupsCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/GetGroupsCommand.java
new file mode 100644
index 0000000..bef2e5c
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/GetGroupsCommand.java
@@ -0,0 +1,60 @@
+/*
+ * 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.accumulo.core.util.shell.commands;
+
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import org.apache.accumulo.core.util.LocalityGroupUtil;
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.core.util.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Options;
+import org.apache.hadoop.io.Text;
+
+public class GetGroupsCommand extends Command {
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    final String tableName = OptUtil.getTableOpt(cl, shellState);
+    
+    final Map<String,Set<Text>> groups = shellState.getConnector().tableOperations().getLocalityGroups(tableName);
+    
+    for (Entry<String,Set<Text>> entry : groups.entrySet()) {
+      shellState.getReader().println(entry.getKey() + "=" + LocalityGroupUtil.encodeColumnFamilies(entry.getValue()));
+    }
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "gets the locality groups for a given table";
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options opts = new Options();
+    opts.addOption(OptUtil.tableOpt("table to fetch locality groups from"));
+    return opts;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/GetSplitsCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/GetSplitsCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/GetSplitsCommand.java
new file mode 100644
index 0000000..92c7c5d
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/GetSplitsCommand.java
@@ -0,0 +1,155 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.accumulo.core.util.shell.commands;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.Iterator;
+import java.util.Map.Entry;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.Scanner;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.core.data.Key;
+import org.apache.accumulo.core.data.KeyExtent;
+import org.apache.accumulo.core.data.Range;
+import org.apache.accumulo.core.data.Value;
+import org.apache.accumulo.core.metadata.MetadataTable;
+import org.apache.accumulo.core.metadata.RootTable;
+import org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection;
+import org.apache.accumulo.core.security.Authorizations;
+import org.apache.accumulo.core.util.TextUtil;
+import org.apache.accumulo.core.util.format.BinaryFormatter;
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.core.util.shell.Shell.Command;
+import org.apache.accumulo.core.util.shell.Shell.PrintFile;
+import org.apache.accumulo.core.util.shell.Shell.PrintLine;
+import org.apache.accumulo.core.util.shell.Shell.PrintShell;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+import org.apache.commons.codec.binary.Base64;
+import org.apache.hadoop.io.Text;
+
+public class GetSplitsCommand extends Command {
+  
+  private Option outputFileOpt, maxSplitsOpt, base64Opt, verboseOpt;
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws IOException, AccumuloException, AccumuloSecurityException,
+      TableNotFoundException {
+    final String tableName = OptUtil.getTableOpt(cl, shellState);
+    
+    final String outputFile = cl.getOptionValue(outputFileOpt.getOpt());
+    final String m = cl.getOptionValue(maxSplitsOpt.getOpt());
+    final int maxSplits = m == null ? 0 : Integer.parseInt(m);
+    final boolean encode = cl.hasOption(base64Opt.getOpt());
+    final boolean verbose = cl.hasOption(verboseOpt.getOpt());
+    
+    final PrintLine p = outputFile == null ? new PrintShell(shellState.getReader()) : new PrintFile(outputFile);
+    
+    try {
+      if (!verbose) {
+        for (Text row : maxSplits > 0 ? shellState.getConnector().tableOperations().listSplits(tableName, maxSplits) : shellState.getConnector()
+            .tableOperations().listSplits(tableName)) {
+          p.print(encode(encode, row));
+        }
+      } else {
+        String systemTableToCheck = MetadataTable.NAME.equals(tableName) ? RootTable.NAME : MetadataTable.NAME;
+        final Scanner scanner = shellState.getConnector().createScanner(systemTableToCheck, Authorizations.EMPTY);
+        TabletsSection.TabletColumnFamily.PREV_ROW_COLUMN.fetch(scanner);
+        final Text start = new Text(shellState.getConnector().tableOperations().tableIdMap().get(tableName));
+        final Text end = new Text(start);
+        end.append(new byte[] {'<'}, 0, 1);
+        scanner.setRange(new Range(start, end));
+        for (Iterator<Entry<Key,Value>> iterator = scanner.iterator(); iterator.hasNext();) {
+          final Entry<Key,Value> next = iterator.next();
+          if (TabletsSection.TabletColumnFamily.PREV_ROW_COLUMN.hasColumns(next.getKey())) {
+            KeyExtent extent = new KeyExtent(next.getKey().getRow(), next.getValue());
+            final String pr = encode(encode, extent.getPrevEndRow());
+            final String er = encode(encode, extent.getEndRow());
+            final String line = String.format("%-26s (%s, %s%s", obscuredTabletName(extent), pr == null ? "-inf" : pr, er == null ? "+inf" : er,
+                er == null ? ") Default Tablet " : "]");
+            p.print(line);
+          }
+        }
+      }
+      
+    } finally {
+      p.close();
+    }
+    
+    return 0;
+  }
+  
+  private static String encode(final boolean encode, final Text text) {
+    if (text == null) {
+      return null;
+    }
+    BinaryFormatter.getlength(text.getLength());
+    return encode ? new String(Base64.encodeBase64(TextUtil.getBytes(text)), StandardCharsets.UTF_8) : BinaryFormatter.appendText(new StringBuilder(), text).toString();
+  }
+  
+  private static String obscuredTabletName(final KeyExtent extent) {
+    MessageDigest digester;
+    try {
+      digester = MessageDigest.getInstance("MD5");
+    } catch (NoSuchAlgorithmException e) {
+      throw new RuntimeException(e);
+    }
+    if (extent.getEndRow() != null && extent.getEndRow().getLength() > 0) {
+      digester.update(extent.getEndRow().getBytes(), 0, extent.getEndRow().getLength());
+    }
+    return new String(Base64.encodeBase64(digester.digest()), StandardCharsets.UTF_8);
+  }
+  
+  @Override
+  public String description() {
+    return "retrieves the current split points for tablets in the current table";
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options opts = new Options();
+    
+    outputFileOpt = new Option("o", "output", true, "local file to write the splits to");
+    outputFileOpt.setArgName("file");
+    
+    maxSplitsOpt = new Option("m", "max", true, "maximum number of splits to return (evenly spaced)");
+    maxSplitsOpt.setArgName("num");
+    
+    base64Opt = new Option("b64", "base64encoded", false, "encode the split points");
+    
+    verboseOpt = new Option("v", "verbose", false, "print out the tablet information with start/end rows");
+    
+    opts.addOption(outputFileOpt);
+    opts.addOption(maxSplitsOpt);
+    opts.addOption(base64Opt);
+    opts.addOption(verboseOpt);
+    opts.addOption(OptUtil.tableOpt("table to get splits for"));
+    
+    return opts;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/GrantCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/GrantCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/GrantCommand.java
new file mode 100644
index 0000000..de719fd
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/GrantCommand.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.accumulo.core.util.shell.commands;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.accumulo.core.security.NamespacePermission;
+import org.apache.accumulo.core.security.SystemPermission;
+import org.apache.accumulo.core.security.TablePermission;
+import org.apache.accumulo.core.util.BadArgumentException;
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.core.util.shell.Shell.Command;
+import org.apache.accumulo.core.util.shell.Token;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.OptionGroup;
+import org.apache.commons.cli.Options;
+
+public class GrantCommand extends TableOperation {
+  {
+    disableUnflaggedTableOptions();
+  }
+
+  private Option systemOpt, userOpt;
+  private String user;
+  private String[] permission;
+
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    user = cl.hasOption(userOpt.getOpt()) ? cl.getOptionValue(userOpt.getOpt()) : shellState.getConnector().whoami();
+
+    permission = cl.getArgs()[0].split("\\.", 2);
+    if (cl.hasOption(systemOpt.getOpt()) && permission[0].equalsIgnoreCase("System")) {
+      try {
+        shellState.getConnector().securityOperations().grantSystemPermission(user, SystemPermission.valueOf(permission[1]));
+        Shell.log.debug("Granted " + user + " the " + permission[1] + " permission");
+      } catch (IllegalArgumentException e) {
+        throw new BadArgumentException("No such system permission", fullCommand, fullCommand.indexOf(cl.getArgs()[0]));
+      }
+    } else if (permission[0].equalsIgnoreCase("Table")) {
+      super.execute(fullCommand, cl, shellState);
+    } else if (permission[0].equalsIgnoreCase("Namespace")) {
+      if (cl.hasOption(optNamespace.getOpt())) {
+        try {
+          shellState.getConnector().securityOperations()
+              .grantNamespacePermission(user, cl.getOptionValue(optNamespace.getOpt()), NamespacePermission.valueOf(permission[1]));
+        } catch (IllegalArgumentException e) {
+          throw new BadArgumentException("No such namespace permission", fullCommand, fullCommand.indexOf(cl.getArgs()[0]));
+        }
+      } else {
+        throw new BadArgumentException("No namespace specified to apply permission to", fullCommand, fullCommand.indexOf(cl.getArgs()[0]));
+      }
+    } else {
+      throw new BadArgumentException("Unrecognized permission", fullCommand, fullCommand.indexOf(cl.getArgs()[0]));
+    }
+    return 0;
+  }
+
+  @Override
+  protected void doTableOp(final Shell shellState, final String tableName) throws Exception {
+    try {
+      shellState.getConnector().securityOperations().grantTablePermission(user, tableName, TablePermission.valueOf(permission[1]));
+      Shell.log.debug("Granted " + user + " the " + permission[1] + " permission on table " + tableName);
+    } catch (IllegalArgumentException e) {
+      throw new IllegalArgumentException("No such table permission", e);
+    }
+  }
+
+  @Override
+  public String description() {
+    return "grants system, table, or namespace permissions for a user";
+  }
+
+  @Override
+  public String usage() {
+    return getName() + " <permission>";
+  }
+
+  @Override
+  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> completionSet) {
+    final Token cmd = new Token(getName());
+    cmd.addSubcommand(new Token(TablePermission.printableValues()));
+    cmd.addSubcommand(new Token(SystemPermission.printableValues()));
+    cmd.addSubcommand(new Token(NamespacePermission.printableValues()));
+    root.addSubcommand(cmd);
+  }
+
+  @Override
+  public Options getOptions() {
+    super.getOptions();
+    final Options o = new Options();
+
+    final OptionGroup group = new OptionGroup();
+
+    systemOpt = new Option("s", "system", false, "grant a system permission");
+
+    optNamespace = new Option(Shell.namespaceOption, "namespace", true, "name of a namespace to operate on");
+    optNamespace.setArgName("namespace");
+
+    group.addOption(systemOpt);
+    group.addOption(optTableName);
+    group.addOption(optTablePattern);
+    group.addOption(optNamespace);
+
+    o.addOptionGroup(group);
+    userOpt = new Option(Shell.userOption, "user", true, "user to operate on");
+    userOpt.setArgName("username");
+    userOpt.setRequired(true);
+    o.addOption(userOpt);
+
+    return o;
+  }
+
+  @Override
+  public int numArgs() {
+    return 1;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/GrepCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/GrepCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/GrepCommand.java
new file mode 100644
index 0000000..c2ff232
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/GrepCommand.java
@@ -0,0 +1,111 @@
+/*
+ * 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.accumulo.core.util.shell.commands;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.accumulo.core.client.BatchScanner;
+import org.apache.accumulo.core.client.IteratorSetting;
+import org.apache.accumulo.core.iterators.user.GrepIterator;
+import org.apache.accumulo.core.security.Authorizations;
+import org.apache.accumulo.core.util.format.Formatter;
+import org.apache.accumulo.core.util.interpret.ScanInterpreter;
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.core.util.shell.Shell.PrintFile;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.MissingArgumentException;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+
+public class GrepCommand extends ScanCommand {
+  
+  private Option numThreadsOpt;
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    final PrintFile printFile = getOutputFile(cl);
+    
+    final String tableName = OptUtil.getTableOpt(cl, shellState);
+    
+    if (cl.getArgList().isEmpty()) {
+      throw new MissingArgumentException("No terms specified");
+    }
+    final Class<? extends Formatter> formatter = getFormatter(cl, tableName, shellState);
+    final ScanInterpreter interpeter = getInterpreter(cl, tableName, shellState);
+    
+    // handle first argument, if present, the authorizations list to
+    // scan with
+    int numThreads = 20;
+    if (cl.hasOption(numThreadsOpt.getOpt())) {
+      numThreads = Integer.parseInt(cl.getOptionValue(numThreadsOpt.getOpt()));
+    }
+    final Authorizations auths = getAuths(cl, shellState);
+    final BatchScanner scanner = shellState.getConnector().createBatchScanner(tableName, auths, numThreads);
+    scanner.setRanges(Collections.singletonList(getRange(cl, interpeter)));
+    
+    scanner.setTimeout(getTimeout(cl), TimeUnit.MILLISECONDS);
+    
+    for (int i = 0; i < cl.getArgs().length; i++) {
+      setUpIterator(Integer.MAX_VALUE - cl.getArgs().length + i, "grep" + i, cl.getArgs()[i], scanner, cl);
+    }
+    try {
+      // handle columns
+      fetchColumns(cl, scanner, interpeter);
+      
+      // output the records
+      printRecords(cl, shellState, scanner, formatter, printFile);
+    } finally {
+      scanner.close();
+    }
+    
+    return 0;
+  }
+  
+  protected void setUpIterator(final int prio, final String name, final String term, final BatchScanner scanner, CommandLine cl) throws IOException {
+    if (prio < 0) {
+      throw new IllegalArgumentException("Priority < 0 " + prio);
+    }
+    final IteratorSetting grep = new IteratorSetting(prio, name, GrepIterator.class);
+    GrepIterator.setTerm(grep, term);
+    scanner.addScanIterator(grep);
+  }
+  
+  @Override
+  public String description() {
+    return "searches each row, column family, column qualifier and value in a table for a substring (not a regular expression), in parallel, on the server side";
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options opts = super.getOptions();
+    numThreadsOpt = new Option("nt", "num-threads", true, "number of threads to use");
+    opts.addOption(numThreadsOpt);
+    return opts;
+  }
+  
+  @Override
+  public String usage() {
+    return getName() + " <term>{ <term>}";
+  }
+  
+  @Override
+  public int numArgs() {
+    return Shell.NO_FIXED_ARG_LENGTH_CHECK;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/HelpCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/HelpCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/HelpCommand.java
new file mode 100644
index 0000000..9881e00
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/HelpCommand.java
@@ -0,0 +1,129 @@
+/*
+ * 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.accumulo.core.util.shell.commands;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.core.util.shell.Shell.Command;
+import org.apache.accumulo.core.util.shell.ShellCommandException;
+import org.apache.accumulo.core.util.shell.Token;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+
+public class HelpCommand extends Command {
+  private Option disablePaginationOpt;
+  private Option noWrapOpt;
+  
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws ShellCommandException, IOException {
+    int numColumns = shellState.getReader().getTerminal().getWidth();
+    if (cl.hasOption(noWrapOpt.getOpt())) {
+      numColumns = Integer.MAX_VALUE;
+    }
+    // print help summary
+    if (cl.getArgs().length == 0) {
+      int i = 0;
+      for (String cmd : shellState.commandFactory.keySet()) {
+        i = Math.max(i, cmd.length());
+      }
+      if (numColumns < 40) {
+        throw new IllegalArgumentException("numColumns must be at least 40 (was " + numColumns + ")");
+      }
+      final ArrayList<String> output = new ArrayList<String>();
+      for (Entry<String,Command[]> cmdGroup : shellState.commandGrouping.entrySet()) {
+        output.add(cmdGroup.getKey());
+        for (Command c : cmdGroup.getValue()) {
+          String n = c.getName();
+          String s = c.description();
+          if (s == null) {
+            s = "";
+          }
+          int beginIndex = 0;
+          int endIndex = s.length();
+          while (beginIndex < endIndex && s.charAt(beginIndex) == ' ')
+            beginIndex++;
+          String dash = "-";
+          while (endIndex > beginIndex && endIndex - beginIndex + i + 5 > numColumns) {
+            endIndex = s.lastIndexOf(" ", numColumns + beginIndex - i - 5);
+            if (endIndex == -1 || endIndex < beginIndex) {
+              endIndex = numColumns + beginIndex - i - 5 - 1;
+              output.add(String.format("%-" + i + "s  %s  %s-", n, dash, s.substring(beginIndex, endIndex)));
+              dash = " ";
+              beginIndex = endIndex;
+            } else {
+              output.add(String.format("%-" + i + "s  %s  %s", n, dash, s.substring(beginIndex, endIndex)));
+              dash = " ";
+              beginIndex = endIndex + 1;
+            }
+            n = "";
+            endIndex = s.length();
+            while (beginIndex < endIndex && s.charAt(beginIndex) == ' ') {
+              beginIndex++;
+            }
+          }
+          output.add(String.format("%-" + i + "s  %s  %s", n, dash, s.substring(beginIndex, endIndex)));
+        }
+        output.add("");
+      }
+      shellState.printLines(output.iterator(), !cl.hasOption(disablePaginationOpt.getOpt()));
+    }
+    
+    // print help for every command on command line
+    for (String cmd : cl.getArgs()) {
+      final Command c = shellState.commandFactory.get(cmd);
+      if (c == null) {
+        shellState.getReader().println(String.format("Unknown command \"%s\".  Enter \"help\" for a list possible commands.", cmd));
+      } else {
+        c.printHelp(shellState, numColumns);
+      }
+    }
+    return 0;
+  }
+  
+  public String description() {
+    return "provides information about the available commands";
+  }
+  
+  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> special) {
+    registerCompletionForCommands(root, special);
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+    disablePaginationOpt = new Option("np", "no-pagination", false, "disable pagination of output");
+    o.addOption(disablePaginationOpt);
+    noWrapOpt = new Option("nw", "no-wrap", false, "disable wrapping of output");
+    o.addOption(noWrapOpt);
+    return o;
+  }
+  
+  @Override
+  public String usage() {
+    return getName() + " [ <command>{ <command>} ]";
+  }
+  
+  @Override
+  public int numArgs() {
+    return Shell.NO_FIXED_ARG_LENGTH_CHECK;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/HiddenCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/HiddenCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/HiddenCommand.java
new file mode 100644
index 0000000..c1615ea
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/HiddenCommand.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.accumulo.core.util.shell.commands;
+
+import java.nio.charset.StandardCharsets;
+import java.security.SecureRandom;
+import java.util.Random;
+
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.core.util.shell.Shell.Command;
+import org.apache.accumulo.core.util.shell.ShellCommandException;
+import org.apache.accumulo.core.util.shell.ShellCommandException.ErrorCode;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.codec.binary.Base64;
+
+public class HiddenCommand extends Command {
+  private static Random rand = new SecureRandom();
+  
+  @Override
+  public String description() {
+    return "The first rule of Accumulo is: \"You don't talk about Accumulo.\"";
+  }
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    if (rand.nextInt(10) == 0) {
+      shellState.getReader().beep();
+      shellState.getReader().println();
+      shellState.getReader().println(
+          new String(Base64.decodeBase64(("ICAgICAgIC4tLS4KICAgICAgLyAvXCBcCiAgICAgKCAvLS1cICkKICAgICAuPl8gIF88LgogICAgLyB8ICd8ICcgXAog"
+              + "ICAvICB8Xy58Xy4gIFwKICAvIC98ICAgICAgfFwgXAogfCB8IHwgfFwvfCB8IHwgfAogfF98IHwgfCAgfCB8IHxffAogICAgIC8gIF9fICBcCiAgICAvICAv"
+              + "ICBcICBcCiAgIC8gIC8gICAgXCAgXF8KIHwvICAvICAgICAgXCB8IHwKIHxfXy8gICAgICAgIFx8X3wK").getBytes(StandardCharsets.UTF_8)), StandardCharsets.UTF_8));
+    } else {
+      throw new ShellCommandException(ErrorCode.UNRECOGNIZED_COMMAND, getName());
+    }
+    return 0;
+  }
+  
+  @Override
+  public int numArgs() {
+    return Shell.NO_FIXED_ARG_LENGTH_CHECK;
+  }
+  
+  @Override
+  public String getName() {
+    return "accvmvlo";
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/HistoryCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/HistoryCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/HistoryCommand.java
new file mode 100644
index 0000000..9531d90
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/HistoryCommand.java
@@ -0,0 +1,82 @@
+/*
+ * 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.accumulo.core.util.shell.commands;
+
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.ListIterator;
+
+import jline.console.history.History.Entry;
+
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.core.util.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+import org.apache.commons.collections.iterators.AbstractIteratorDecorator;
+
+public class HistoryCommand extends Command {
+  private Option clearHist;
+  private Option disablePaginationOpt;
+  
+  @SuppressWarnings("unchecked")
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws IOException {
+    if (cl.hasOption(clearHist.getOpt())) {
+      shellState.getReader().getHistory().clear();
+    } else {
+      ListIterator<Entry> it = shellState.getReader().getHistory().entries();
+      shellState.printLines(new HistoryLineIterator(it), !cl.hasOption(disablePaginationOpt.getOpt()));
+    }
+    
+    return 0;
+  }
+  
+  /**
+   * Decorator that converts an Iterator<History.Entry> to an Iterator<String>.
+   */
+  private static class HistoryLineIterator extends AbstractIteratorDecorator {
+    public HistoryLineIterator(Iterator<Entry> iterator) {
+      super(iterator);
+    }
+    
+    @Override
+    public String next() {
+      return super.next().toString();
+    }
+  }
+  
+  @Override
+  public String description() {
+    return ("generates a list of commands previously executed");
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+    clearHist = new Option("c", "clear", false, "clear history file");
+    o.addOption(clearHist);
+    disablePaginationOpt = new Option("np", "no-pagination", false, "disable pagination of output");
+    o.addOption(disablePaginationOpt);
+    return o;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ImportDirectoryCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ImportDirectoryCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ImportDirectoryCommand.java
new file mode 100644
index 0000000..13db3a4
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ImportDirectoryCommand.java
@@ -0,0 +1,58 @@
+/*
+ * 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.accumulo.core.util.shell.commands;
+
+import java.io.IOException;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.core.util.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+
+public class ImportDirectoryCommand extends Command {
+  
+  @Override
+  public String description() {
+    return "bulk imports an entire directory of data files to the current table.  The boolean argument determines if accumulo sets the time.";
+  }
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws IOException, AccumuloException, AccumuloSecurityException,
+      TableNotFoundException {
+    shellState.checkTableState();
+    
+    String dir = cl.getArgs()[0];
+    String failureDir = cl.getArgs()[1];
+    final boolean setTime = Boolean.parseBoolean(cl.getArgs()[2]);
+
+    shellState.getConnector().tableOperations().importDirectory(shellState.getTableName(), dir, failureDir, setTime);
+    return 0;
+  }
+  
+  @Override
+  public int numArgs() {
+    return 3;
+  }
+  
+  @Override
+  public String usage() {
+    return getName() + " <directory> <failureDirectory> true|false";
+  }
+  
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ImportTableCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ImportTableCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ImportTableCommand.java
new file mode 100644
index 0000000..571c45b
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ImportTableCommand.java
@@ -0,0 +1,51 @@
+/*
+ * 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.accumulo.core.util.shell.commands;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.TableExistsException;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.core.util.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+
+public class ImportTableCommand extends Command {
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException, TableNotFoundException,
+      TableExistsException {
+    
+    shellState.getConnector().tableOperations().importTable(cl.getArgs()[0], cl.getArgs()[1]);
+    return 0;
+  }
+  
+  @Override
+  public String usage() {
+    return getName() + " <table name> <import dir>";
+  }
+  
+  @Override
+  public String description() {
+    return "imports a table";
+  }
+  
+  @Override
+  public int numArgs() {
+    return 2;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/InfoCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/InfoCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/InfoCommand.java
new file mode 100644
index 0000000..57de6b1
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/InfoCommand.java
@@ -0,0 +1,19 @@
+/*
+ * 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.accumulo.core.util.shell.commands;
+
+public class InfoCommand extends AboutCommand {}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/InsertCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/InsertCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/InsertCommand.java
new file mode 100644
index 0000000..a97db05
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/InsertCommand.java
@@ -0,0 +1,148 @@
+/*
+ * 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.accumulo.core.util.shell.commands;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.BatchWriter;
+import org.apache.accumulo.core.client.BatchWriterConfig;
+import org.apache.accumulo.core.client.MutationsRejectedException;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.core.client.security.SecurityErrorCode;
+import org.apache.accumulo.core.conf.AccumuloConfiguration;
+import org.apache.accumulo.core.data.ConstraintViolationSummary;
+import org.apache.accumulo.core.data.KeyExtent;
+import org.apache.accumulo.core.data.Mutation;
+import org.apache.accumulo.core.data.Value;
+import org.apache.accumulo.core.security.ColumnVisibility;
+import org.apache.accumulo.core.tabletserver.thrift.ConstraintViolationException;
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.core.util.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+import org.apache.hadoop.io.Text;
+
+public class InsertCommand extends Command {
+  private Option insertOptAuths, timestampOpt;
+  private Option timeoutOption;
+  
+  protected long getTimeout(final CommandLine cl) {
+    if (cl.hasOption(timeoutOption.getLongOpt())) {
+      return AccumuloConfiguration.getTimeInMillis(cl.getOptionValue(timeoutOption.getLongOpt()));
+    }
+    
+    return Long.MAX_VALUE;
+  }
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException,
+      TableNotFoundException, IOException, ConstraintViolationException {
+    shellState.checkTableState();
+    
+    final Mutation m = new Mutation(new Text(cl.getArgs()[0].getBytes(Shell.CHARSET)));
+    final Text colf = new Text(cl.getArgs()[1].getBytes(Shell.CHARSET));
+    final Text colq = new Text(cl.getArgs()[2].getBytes(Shell.CHARSET));
+    final Value val = new Value(cl.getArgs()[3].getBytes(Shell.CHARSET));
+    
+    if (cl.hasOption(insertOptAuths.getOpt())) {
+      final ColumnVisibility le = new ColumnVisibility(cl.getOptionValue(insertOptAuths.getOpt()));
+      Shell.log.debug("Authorization label will be set to: " + le.toString());
+      
+      if (cl.hasOption(timestampOpt.getOpt()))
+        m.put(colf, colq, le, Long.parseLong(cl.getOptionValue(timestampOpt.getOpt())), val);
+      else
+        m.put(colf, colq, le, val);
+    } else if (cl.hasOption(timestampOpt.getOpt()))
+      m.put(colf, colq, Long.parseLong(cl.getOptionValue(timestampOpt.getOpt())), val);
+    else
+      m.put(colf, colq, val);
+    
+    final BatchWriter bw = shellState.getConnector().createBatchWriter(shellState.getTableName(),
+        new BatchWriterConfig().setMaxMemory(Math.max(m.estimatedMemoryUsed(), 1024)).setMaxWriteThreads(1).setTimeout(getTimeout(cl), TimeUnit.MILLISECONDS));
+    bw.addMutation(m);
+    try {
+      bw.close();
+    } catch (MutationsRejectedException e) {
+      final ArrayList<String> lines = new ArrayList<String>();
+      if (e.getAuthorizationFailuresMap().isEmpty() == false) {
+        lines.add("	Authorization Failures:");
+      }
+      for (Entry<KeyExtent,Set<SecurityErrorCode>> entry : e.getAuthorizationFailuresMap().entrySet()) {
+        lines.add("		" + entry);
+      }
+      if (e.getConstraintViolationSummaries().isEmpty() == false) {
+        lines.add("	Constraint Failures:");
+      }
+      for (ConstraintViolationSummary cvs : e.getConstraintViolationSummaries()) {
+        lines.add("		" + cvs.toString());
+      }
+      
+      if (lines.size() == 0 || e.getUnknownExceptions() > 0) {
+        // must always print something
+        lines.add(" " + e.getClass().getName() + " : " + e.getMessage());
+        if (e.getCause() != null)
+          lines.add("   Caused by : " + e.getCause().getClass().getName() + " : " + e.getCause().getMessage());
+      }
+      
+      shellState.printLines(lines.iterator(), false);
+      
+      return 1;
+    }
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "inserts a record";
+  }
+  
+  @Override
+  public String usage() {
+    return getName() + " <row> <colfamily> <colqualifier> <value>";
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+    insertOptAuths = new Option("l", "visibility-label", true, "formatted visibility");
+    insertOptAuths.setArgName("expression");
+    o.addOption(insertOptAuths);
+    
+    timestampOpt = new Option("ts", "timestamp", true, "timestamp to use for insert");
+    timestampOpt.setArgName("timestamp");
+    o.addOption(timestampOpt);
+    
+    timeoutOption = new Option(null, "timeout", true,
+        "time before insert should fail if no data is written. If no unit is given assumes seconds.  Units d,h,m,s,and ms are supported.  e.g. 30s or 100ms");
+    timeoutOption.setArgName("timeout");
+    o.addOption(timeoutOption);
+    
+    return o;
+  }
+  
+  @Override
+  public int numArgs() {
+    return 4;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/InterpreterCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/InterpreterCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/InterpreterCommand.java
new file mode 100644
index 0000000..090bd7f
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/InterpreterCommand.java
@@ -0,0 +1,40 @@
+/*
+ * 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.accumulo.core.util.shell.commands;
+
+import org.apache.accumulo.core.conf.Property;
+import org.apache.accumulo.core.util.interpret.ScanInterpreter;
+import org.apache.accumulo.core.util.shell.Shell;
+
+/**
+ * 
+ */
+public class InterpreterCommand extends ShellPluginConfigurationCommand {
+  
+  public InterpreterCommand() {
+    super("interpreter", Property.TABLE_INTERPRETER_CLASS, "i");
+  }
+  
+  @Override
+  public String description() {
+    return "specifies a scan interpreter to interpret scan range and column arguments";
+  }
+  
+  public static Class<? extends ScanInterpreter> getCurrentInterpreter(final String tableName, final Shell shellState) {
+    return ShellPluginConfigurationCommand.getPluginClass(tableName, shellState, ScanInterpreter.class, Property.TABLE_INTERPRETER_CLASS);
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ListCompactionsCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ListCompactionsCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ListCompactionsCommand.java
new file mode 100644
index 0000000..baa59a0
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ListCompactionsCommand.java
@@ -0,0 +1,78 @@
+/*
+ * 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.accumulo.core.util.shell.commands;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.accumulo.core.client.admin.InstanceOperations;
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.core.util.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+
+public class ListCompactionsCommand extends Command {
+  
+  private Option tserverOption, disablePaginationOpt;
+  
+  @Override
+  public String description() {
+    return "lists what compactions are currently running in accumulo. See the accumulo.core.client.admin.ActiveCompaciton javadoc for more information about columns.";
+  }
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    
+    List<String> tservers;
+    
+    final InstanceOperations instanceOps = shellState.getConnector().instanceOperations();
+    
+    final boolean paginate = !cl.hasOption(disablePaginationOpt.getOpt());
+    
+    if (cl.hasOption(tserverOption.getOpt())) {
+      tservers = new ArrayList<String>();
+      tservers.add(cl.getOptionValue(tserverOption.getOpt()));
+    } else {
+      tservers = instanceOps.getTabletServers();
+    }
+    
+    shellState.printLines(new ActiveCompactionIterator(tservers, instanceOps), paginate);
+    
+    return 0;
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options opts = new Options();
+    
+    tserverOption = new Option("ts", "tabletServer", true, "tablet server to list compactions for");
+    tserverOption.setArgName("tablet server");
+    opts.addOption(tserverOption);
+    
+    disablePaginationOpt = new Option("np", "no-pagination", false, "disable pagination of output");
+    opts.addOption(disablePaginationOpt);
+    
+    return opts;
+  }
+  
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ListIterCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ListIterCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ListIterCommand.java
new file mode 100644
index 0000000..9aac389
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ListIterCommand.java
@@ -0,0 +1,140 @@
+/*
+ * 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.accumulo.core.util.shell.commands;
+
+import java.util.EnumMap;
+import java.util.EnumSet;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import org.apache.accumulo.core.client.IteratorSetting;
+import org.apache.accumulo.core.iterators.IteratorUtil.IteratorScope;
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.core.util.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.OptionGroup;
+import org.apache.commons.cli.Options;
+
+public class ListIterCommand extends Command {
+  private Option nameOpt, allScopesOpt;
+  private Map<IteratorScope,Option> scopeOpts;
+
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+
+    boolean tables = cl.hasOption(OptUtil.tableOpt().getOpt()) || !shellState.getTableName().isEmpty();
+    boolean namespaces = cl.hasOption(OptUtil.namespaceOpt().getOpt());
+
+    final Map<String,EnumSet<IteratorScope>> iterators;
+    if (namespaces) {
+      iterators = shellState.getConnector().namespaceOperations().listIterators(OptUtil.getNamespaceOpt(cl, shellState));
+    } else if (tables) {
+      iterators = shellState.getConnector().tableOperations().listIterators(OptUtil.getTableOpt(cl, shellState));
+    } else {
+      throw new IllegalArgumentException("No table or namespace specified");
+    }
+
+    if (cl.hasOption(nameOpt.getOpt())) {
+      final String name = cl.getOptionValue(nameOpt.getOpt());
+      if (!iterators.containsKey(name)) {
+        Shell.log.warn("no iterators found that match your criteria");
+        return 0;
+      }
+      final EnumSet<IteratorScope> scopes = iterators.get(name);
+      iterators.clear();
+      iterators.put(name, scopes);
+    }
+
+    final boolean allScopes = cl.hasOption(allScopesOpt.getOpt());
+    Set<IteratorScope> desiredScopes = new HashSet<IteratorScope>();
+    for (IteratorScope scope : IteratorScope.values()) {
+      if (allScopes || cl.hasOption(scopeOpts.get(scope).getOpt()))
+        desiredScopes.add(scope);
+    }
+    if (desiredScopes.isEmpty()) {
+      throw new IllegalArgumentException("You must select at least one scope to configure");
+    }
+    final StringBuilder sb = new StringBuilder("-\n");
+    for (Entry<String,EnumSet<IteratorScope>> entry : iterators.entrySet()) {
+      final String name = entry.getKey();
+      final EnumSet<IteratorScope> scopes = entry.getValue();
+      for (IteratorScope scope : scopes) {
+        if (desiredScopes.contains(scope)) {
+          IteratorSetting setting;
+          if (namespaces) {
+            setting = shellState.getConnector().namespaceOperations().getIteratorSetting(OptUtil.getNamespaceOpt(cl, shellState), name, scope);
+          } else if (tables) {
+            setting = shellState.getConnector().tableOperations().getIteratorSetting(OptUtil.getTableOpt(cl, shellState), name, scope);
+          } else {
+            throw new IllegalArgumentException("No table or namespace specified");
+          }
+          sb.append("-    Iterator ").append(setting.getName()).append(", ").append(scope).append(" scope options:\n");
+          sb.append("-        ").append("iteratorPriority").append(" = ").append(setting.getPriority()).append("\n");
+          sb.append("-        ").append("iteratorClassName").append(" = ").append(setting.getIteratorClass()).append("\n");
+          for (Entry<String,String> optEntry : setting.getOptions().entrySet()) {
+            sb.append("-        ").append(optEntry.getKey()).append(" = ").append(optEntry.getValue()).append("\n");
+          }
+        }
+      }
+    }
+    sb.append("-");
+    shellState.getReader().println(sb.toString());
+
+    return 0;
+  }
+
+  @Override
+  public String description() {
+    return "lists table-specific or namespace-specific iterators configured in this shell session";
+  }
+
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+
+    nameOpt = new Option("n", "name", true, "iterator to list");
+    nameOpt.setArgName("itername");
+
+    allScopesOpt = new Option("all", "all-scopes", false, "list from all scopes");
+    o.addOption(allScopesOpt);
+    
+    scopeOpts = new EnumMap<IteratorScope,Option>(IteratorScope.class);
+    scopeOpts.put(IteratorScope.minc, new Option(IteratorScope.minc.name(), "minor-compaction", false, "list iterator for minor compaction scope"));
+    scopeOpts.put(IteratorScope.majc, new Option(IteratorScope.majc.name(), "major-compaction", false, "list iterator for major compaction scope"));
+    scopeOpts.put(IteratorScope.scan, new Option(IteratorScope.scan.name(), "scan-time", false, "list iterator for scan scope"));
+
+    OptionGroup grp = new OptionGroup();
+    grp.addOption(OptUtil.tableOpt("table to list the configured iterators on"));
+    grp.addOption(OptUtil.namespaceOpt("namespace to list the configured iterators on"));
+    o.addOptionGroup(grp);
+    o.addOption(nameOpt);
+
+    for (Option opt : scopeOpts.values()) {
+      o.addOption(opt);
+    }
+
+    return o;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ListScansCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ListScansCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ListScansCommand.java
new file mode 100644
index 0000000..e4a2692
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ListScansCommand.java
@@ -0,0 +1,78 @@
+/*
+ * 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.accumulo.core.util.shell.commands;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.accumulo.core.client.admin.InstanceOperations;
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.core.util.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+
+public class ListScansCommand extends Command {
+  
+  private Option tserverOption, disablePaginationOpt;
+  
+  @Override
+  public String description() {
+    return "lists what scans are currently running in accumulo. See the accumulo.core.client.admin.ActiveScan javadoc for more information about columns.";
+  }
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    
+    List<String> tservers;
+    
+    final InstanceOperations instanceOps = shellState.getConnector().instanceOperations();
+    
+    final boolean paginate = !cl.hasOption(disablePaginationOpt.getOpt());
+    
+    if (cl.hasOption(tserverOption.getOpt())) {
+      tservers = new ArrayList<String>();
+      tservers.add(cl.getOptionValue(tserverOption.getOpt()));
+    } else {
+      tservers = instanceOps.getTabletServers();
+    }
+    
+    shellState.printLines(new ActiveScanIterator(tservers, instanceOps), paginate);
+    
+    return 0;
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options opts = new Options();
+    
+    tserverOption = new Option("ts", "tabletServer", true, "tablet server to list scans for");
+    tserverOption.setArgName("tablet server");
+    opts.addOption(tserverOption);
+    
+    disablePaginationOpt = new Option("np", "no-pagination", false, "disable pagination of output");
+    opts.addOption(disablePaginationOpt);
+    
+    return opts;
+  }
+  
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ListShellIterCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ListShellIterCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ListShellIterCommand.java
new file mode 100644
index 0000000..7f6ad84
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ListShellIterCommand.java
@@ -0,0 +1,105 @@
+/*
+ * 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.accumulo.core.util.shell.commands;
+
+import java.util.List;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import org.apache.accumulo.core.client.IteratorSetting;
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.core.util.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+
+/**
+ * 
+ */
+public class ListShellIterCommand extends Command {
+  
+  private Option nameOpt, profileOpt;
+
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    if (shellState.iteratorProfiles.size() == 0)
+      return 0;
+    
+    final StringBuilder sb = new StringBuilder();
+
+    String profile = null;
+    if (cl.hasOption(profileOpt.getOpt()))
+      profile = cl.getOptionValue(profileOpt.getOpt());
+
+    String name = null;
+    if (cl.hasOption(nameOpt.getOpt()))
+      name = cl.getOptionValue(nameOpt.getOpt());
+
+    Set<Entry<String,List<IteratorSetting>>> es = shellState.iteratorProfiles.entrySet();
+    for (Entry<String,List<IteratorSetting>> entry : es) {
+      if (profile != null && !profile.equals(entry.getKey()))
+        continue;
+
+      sb.append("-\n");
+      sb.append("- Profile : " + entry.getKey() + "\n");
+      for (IteratorSetting setting : entry.getValue()) {
+        if (name != null && !name.equals(setting.getName()))
+          continue;
+
+        sb.append("-    Iterator ").append(setting.getName()).append(", ").append(" options:\n");
+        sb.append("-        ").append("iteratorPriority").append(" = ").append(setting.getPriority()).append("\n");
+        sb.append("-        ").append("iteratorClassName").append(" = ").append(setting.getIteratorClass()).append("\n");
+        for (Entry<String,String> optEntry : setting.getOptions().entrySet()) {
+          sb.append("-        ").append(optEntry.getKey()).append(" = ").append(optEntry.getValue()).append("\n");
+        }
+      }
+    }
+    
+    if (sb.length() > 0) {
+      sb.append("-\n");
+    }
+
+    shellState.getReader().print(sb.toString());
+
+    return 0;
+  }
+  
+  public String description() {
+    return "lists iterators profiles configured in shell";
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+    
+    profileOpt = new Option("pn", "profile", true, "iterator profile name");
+    profileOpt.setArgName("profile");
+
+    nameOpt = new Option("n", "name", true, "iterator to list");
+    nameOpt.setArgName("itername");
+    
+    o.addOption(profileOpt);
+    o.addOption(nameOpt);
+
+    return o;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/MaxRowCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/MaxRowCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/MaxRowCommand.java
new file mode 100644
index 0000000..ddb6cc1
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/MaxRowCommand.java
@@ -0,0 +1,55 @@
+/*
+ * 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.accumulo.core.util.shell.commands;
+
+import org.apache.accumulo.core.data.Range;
+import org.apache.accumulo.core.security.Authorizations;
+import org.apache.accumulo.core.util.interpret.ScanInterpreter;
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.commons.cli.CommandLine;
+import org.apache.hadoop.io.Text;
+
+public class MaxRowCommand extends ScanCommand {
+  
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    final String tableName = OptUtil.getTableOpt(cl, shellState);
+    
+    final ScanInterpreter interpeter = getInterpreter(cl, tableName, shellState);
+    
+    final Range range = getRange(cl, interpeter);
+    final Authorizations auths = getAuths(cl, shellState);
+    final Text startRow = range.getStartKey() == null ? null : range.getStartKey().getRow();
+    final Text endRow = range.getEndKey() == null ? null : range.getEndKey().getRow();
+    
+    try {
+      final Text max = shellState.getConnector().tableOperations()
+          .getMaxRow(tableName, auths, startRow, range.isStartKeyInclusive(), endRow, range.isEndKeyInclusive());
+      if (max != null) {
+        shellState.getReader().println(max.toString());
+      }
+    } catch (Exception e) {
+      e.printStackTrace();
+    }
+    
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "finds the max row in a table within a given range";
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/MergeCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/MergeCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/MergeCommand.java
new file mode 100644
index 0000000..9774e36
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/MergeCommand.java
@@ -0,0 +1,111 @@
+/*
+ * 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.accumulo.core.util.shell.commands;
+
+import java.io.IOException;
+
+import org.apache.accumulo.core.conf.AccumuloConfiguration;
+import org.apache.accumulo.core.util.Merge;
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.core.util.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+import org.apache.hadoop.io.Text;
+
+public class MergeCommand extends Command {
+  private Option verboseOpt, forceOpt, sizeOpt, allOpt;
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    boolean verbose = shellState.isVerbose();
+    boolean force = false;
+    boolean all = false;
+    long size = -1;
+    final String tableName = OptUtil.getTableOpt(cl, shellState);
+    final Text startRow = OptUtil.getStartRow(cl);
+    final Text endRow = OptUtil.getEndRow(cl);
+    if (cl.hasOption(verboseOpt.getOpt())) {
+      verbose = true;
+    }
+    if (cl.hasOption(forceOpt.getOpt())) {
+      force = true;
+    }
+    if (cl.hasOption(allOpt.getOpt())) {
+      all = true;
+    }
+    if (cl.hasOption(sizeOpt.getOpt())) {
+      size = AccumuloConfiguration.getMemoryInBytes(cl.getOptionValue(sizeOpt.getOpt()));
+    }
+    if (startRow == null && endRow == null && size < 0 && !all) {
+      shellState.getReader().flush();
+      String line = shellState.getReader().readLine("Merge the entire table { " + tableName + " } into one tablet (yes|no)? ");
+      if (line == null)
+        return 0;
+      if (!line.equalsIgnoreCase("y") && !line.equalsIgnoreCase("yes"))
+        return 0;
+    }
+    if (size < 0) {
+      shellState.getConnector().tableOperations().merge(tableName, startRow, endRow);
+    } else {
+      final boolean finalVerbose = verbose;
+      final Merge merge = new Merge() {
+        protected void message(String fmt, Object... args) {
+          if (finalVerbose) {
+            try {
+              shellState.getReader().println(String.format(fmt, args));
+            } catch (IOException ex) {
+              throw new RuntimeException(ex);
+            }
+          }
+        }
+      };
+      merge.mergomatic(shellState.getConnector(), tableName, startRow, endRow, size, force);
+    }
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "merges tablets in a table";
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+    verboseOpt = new Option("v", "verbose", false, "verbose output during merge");
+    sizeOpt = new Option("s", "size", true, "merge tablets to the given size over the entire table");
+    forceOpt = new Option("f", "force", false, "merge small tablets to large tablets, even if it goes over the given size");
+    allOpt = new Option("", "all", false, "allow an entire table to be merged into one tablet without prompting the user for confirmation");
+    Option startRowOpt = OptUtil.startRowOpt();
+    startRowOpt.setDescription("begin row (NOT inclusive)");
+    o.addOption(startRowOpt);
+    o.addOption(OptUtil.endRowOpt());
+    o.addOption(OptUtil.tableOpt("table to be merged"));
+    o.addOption(verboseOpt);
+    o.addOption(sizeOpt);
+    o.addOption(forceOpt);
+    o.addOption(allOpt);
+    return o;
+  }
+  
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/NamespacePermissionsCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/NamespacePermissionsCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/NamespacePermissionsCommand.java
new file mode 100644
index 0000000..2dcba55
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/NamespacePermissionsCommand.java
@@ -0,0 +1,44 @@
+/*
+ * 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.accumulo.core.util.shell.commands;
+
+import java.io.IOException;
+
+import org.apache.accumulo.core.security.NamespacePermission;
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.core.util.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+
+public class NamespacePermissionsCommand extends Command {
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws IOException {
+    for (String p : NamespacePermission.printableValues()) {
+      shellState.getReader().println(p);
+    }
+    return 0;
+  }
+
+  @Override
+  public String description() {
+    return "displays a list of valid namespace permissions";
+  }
+
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/NamespacesCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/NamespacesCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/NamespacesCommand.java
new file mode 100644
index 0000000..16ee645
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/NamespacesCommand.java
@@ -0,0 +1,83 @@
+/*
+ * 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.accumulo.core.util.shell.commands;
+
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.TreeMap;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.impl.Namespaces;
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.core.util.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+
+import com.google.common.base.Function;
+import com.google.common.collect.Iterators;
+
+public class NamespacesCommand extends Command {
+  private Option disablePaginationOpt, namespaceIdOption;
+
+  private static final String DEFAULT_NAMESPACE_DISPLAY_NAME = "\"\"";
+
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException, IOException {
+    Map<String,String> namespaces = new TreeMap<String,String>(shellState.getConnector().namespaceOperations().namespaceIdMap());
+
+    Iterator<String> it = Iterators.transform(namespaces.entrySet().iterator(), new Function<Entry<String,String>,String>() {
+      @Override
+      public String apply(Map.Entry<String,String> entry) {
+        String name = entry.getKey();
+        if (Namespaces.DEFAULT_NAMESPACE.equals(name))
+          name = DEFAULT_NAMESPACE_DISPLAY_NAME;
+        String id = entry.getValue();
+        if (cl.hasOption(namespaceIdOption.getOpt()))
+          return String.format(TablesCommand.NAME_AND_ID_FORMAT, name, id);
+        else
+          return name;
+      };
+    });
+
+    shellState.printLines(it, !cl.hasOption(disablePaginationOpt.getOpt()));
+    return 0;
+  }
+
+  @Override
+  public String description() {
+    return "displays a list of all existing namespaces";
+  }
+
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+    namespaceIdOption = new Option("l", "list-ids", false, "display internal namespace ids along with the name");
+    o.addOption(namespaceIdOption);
+    disablePaginationOpt = new Option("np", "no-pagination", false, "disable pagination of output");
+    o.addOption(disablePaginationOpt);
+    return o;
+  }
+
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/NoTableCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/NoTableCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/NoTableCommand.java
new file mode 100644
index 0000000..afdab53
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/NoTableCommand.java
@@ -0,0 +1,40 @@
+/*
+ * 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.accumulo.core.util.shell.commands;
+
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.core.util.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+
+public class NoTableCommand extends Command {
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    shellState.setTableName("");
+    
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "returns to a tableless shell state";
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+}


[38/53] [abbrv] ACCUMULO-1879 Move shell into new package and module

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/AddAuthsCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/AddAuthsCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/AddAuthsCommand.java
new file mode 100644
index 0000000..27fea1e
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/AddAuthsCommand.java
@@ -0,0 +1,82 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.security.Authorizations;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Token;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.OptionGroup;
+import org.apache.commons.cli.Options;
+
+public class AddAuthsCommand extends Command {
+  private Option userOpt;
+  private Option scanOptAuths;
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException {
+    final String user = cl.getOptionValue(userOpt.getOpt(), shellState.getConnector().whoami());
+    final String scanOpts = cl.getOptionValue(scanOptAuths.getOpt());
+    Authorizations auths = shellState.getConnector().securityOperations().getUserAuthorizations(user);
+    StringBuilder userAuths = new StringBuilder();
+    if (!auths.isEmpty()) {
+      userAuths.append(auths.toString());
+      userAuths.append(",");
+    }
+    userAuths.append(scanOpts);
+    shellState.getConnector().securityOperations().changeUserAuthorizations(user, ScanCommand.parseAuthorizations(userAuths.toString()));
+    Shell.log.debug("Changed record-level authorizations for user " + user);
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "adds authorizations to the maximum scan authorizations for a user";
+  }
+  
+  @Override
+  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> completionSet) {
+    registerCompletionForUsers(root, completionSet);
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+    final OptionGroup setOrClear = new OptionGroup();
+    scanOptAuths = new Option("s", "scan-authorizations", true, "scan authorizations to set");
+    scanOptAuths.setArgName("comma-separated-authorizations");
+    setOrClear.addOption(scanOptAuths);
+    setOrClear.setRequired(true);
+    o.addOptionGroup(setOrClear);
+    userOpt = new Option(Shell.userOption, "user", true, "user to operate on");
+    userOpt.setArgName("user");
+    o.addOption(userOpt);
+    return o;
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/AddSplitsCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/AddSplitsCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/AddSplitsCommand.java
new file mode 100644
index 0000000..b695d4d
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/AddSplitsCommand.java
@@ -0,0 +1,88 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.util.TreeSet;
+
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.ShellUtil;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.MissingArgumentException;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+import org.apache.hadoop.io.Text;
+
+public class AddSplitsCommand extends Command {
+  private Option optSplitsFile, base64Opt;
+  
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    final String tableName = OptUtil.getTableOpt(cl, shellState);
+    final boolean decode = cl.hasOption(base64Opt.getOpt());
+    
+    final TreeSet<Text> splits = new TreeSet<Text>();
+    
+    if (cl.hasOption(optSplitsFile.getOpt())) {
+      splits.addAll(ShellUtil.scanFile(cl.getOptionValue(optSplitsFile.getOpt()), decode));
+    } else {
+      if (cl.getArgList().isEmpty()) {
+        throw new MissingArgumentException("No split points specified");
+      }
+      for (String s : cl.getArgs()) {
+        splits.add(new Text(s.getBytes(Shell.CHARSET)));
+      }
+    }
+    
+    if (!shellState.getConnector().tableOperations().exists(tableName)) {
+      throw new TableNotFoundException(null, tableName, null);
+    }
+    shellState.getConnector().tableOperations().addSplits(tableName, splits);
+    
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "adds split points to an existing table";
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+    
+    optSplitsFile = new Option("sf", "splits-file", true, "file with a newline-separated list of rows to split the table with");
+    optSplitsFile.setArgName("filename");
+    
+    base64Opt = new Option("b64", "base64encoded", false, "decode encoded split points (splits file only)");
+    
+    o.addOption(OptUtil.tableOpt("name of the table to add split points to"));
+    o.addOption(optSplitsFile);
+    o.addOption(base64Opt);
+    return o;
+  }
+  
+  @Override
+  public String usage() {
+    return getName() + " [<split>{ <split>} ]";
+  }
+  
+  @Override
+  public int numArgs() {
+    return Shell.NO_FIXED_ARG_LENGTH_CHECK;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/AuthenticateCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/AuthenticateCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/AuthenticateCommand.java
new file mode 100644
index 0000000..807de24
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/AuthenticateCommand.java
@@ -0,0 +1,66 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.security.tokens.PasswordToken;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Token;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+
+public class AuthenticateCommand extends Command {
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException, IOException {
+    final String user = cl.getArgs()[0];
+    final String p = shellState.readMaskedLine("Enter current password for '" + user + "': ", '*');
+    if (p == null) {
+      shellState.getReader().println();
+      return 0;
+    } // user canceled
+    final byte[] password = p.getBytes(StandardCharsets.UTF_8);
+    final boolean valid = shellState.getConnector().securityOperations().authenticateUser(user, new PasswordToken(password));
+    shellState.getReader().println((valid ? "V" : "Not v") + "alid");
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "verifies a user's credentials";
+  }
+  
+  @Override
+  public String usage() {
+    return getName() + " <username>";
+  }
+  
+  @Override
+  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> completionSet) {
+    registerCompletionForUsers(root, completionSet);
+  }
+  
+  @Override
+  public int numArgs() {
+    return 1;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/ByeCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/ByeCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/ByeCommand.java
new file mode 100644
index 0000000..2f3baa9
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/ByeCommand.java
@@ -0,0 +1,19 @@
+/*
+ * 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.accumulo.shell.commands;
+
+public class ByeCommand extends ExitCommand {}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/ClasspathCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/ClasspathCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/ClasspathCommand.java
new file mode 100644
index 0000000..c056581
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/ClasspathCommand.java
@@ -0,0 +1,55 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.io.IOException;
+
+import jline.console.ConsoleReader;
+
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.accumulo.start.classloader.vfs.AccumuloVFSClassLoader;
+import org.apache.accumulo.start.classloader.vfs.AccumuloVFSClassLoader.Printer;
+import org.apache.commons.cli.CommandLine;
+
+public class ClasspathCommand extends Command {
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) {
+    final ConsoleReader reader = shellState.getReader();
+    AccumuloVFSClassLoader.printClassPath(new Printer() {
+      @Override
+      public void print(String s) {
+        try {
+          reader.println(s);
+        } catch (IOException ex) {
+          throw new RuntimeException(ex);
+        }
+      }
+    });
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "lists the current files on the classpath";
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/ClearCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/ClearCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/ClearCommand.java
new file mode 100644
index 0000000..9340d4e
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/ClearCommand.java
@@ -0,0 +1,52 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.io.IOException;
+
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+
+public class ClearCommand extends Command {
+  @Override
+  public String description() {
+    return "clears the screen";
+  }
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws IOException {
+    // custom clear screen, so I don't have to redraw the prompt twice
+    if (!shellState.getReader().getTerminal().isAnsiSupported()) {
+      throw new IOException("Terminal does not support ANSI commands");
+    }
+    // send the ANSI code to clear the screen
+    shellState.getReader().print(((char) 27) + "[2J");
+    shellState.getReader().flush();
+    
+    // then send the ANSI code to go to position 1,1
+    shellState.getReader().print(((char) 27) + "[1;1H");
+    shellState.getReader().flush();
+    
+    return 0;
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/CloneTableCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/CloneTableCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/CloneTableCommand.java
new file mode 100644
index 0000000..37de39d
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/CloneTableCommand.java
@@ -0,0 +1,102 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.TableExistsException;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Token;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+
+public class CloneTableCommand extends Command {
+  
+  private Option setPropsOption;
+  private Option excludePropsOption;
+  private Option noFlushOption;
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException, TableNotFoundException,
+      TableExistsException {
+    
+    final HashMap<String,String> props = new HashMap<String,String>();
+    final HashSet<String> exclude = new HashSet<String>();
+    boolean flush = true;
+    
+    if (cl.hasOption(setPropsOption.getOpt())) {
+      String[] keyVals = cl.getOptionValue(setPropsOption.getOpt()).split(",");
+      for (String keyVal : keyVals) {
+        String[] sa = keyVal.split("=");
+        props.put(sa[0], sa[1]);
+      }
+    }
+    
+    if (cl.hasOption(excludePropsOption.getOpt())) {
+      String[] keys = cl.getOptionValue(excludePropsOption.getOpt()).split(",");
+      for (String key : keys) {
+        exclude.add(key);
+      }
+    }
+    
+    if (cl.hasOption(noFlushOption.getOpt())) {
+      flush = false;
+    }
+    
+    shellState.getConnector().tableOperations().clone(cl.getArgs()[0], cl.getArgs()[1], flush, props, exclude);
+    return 0;
+  }
+  
+  @Override
+  public String usage() {
+    return getName() + " <current table name> <new table name>";
+  }
+  
+  @Override
+  public String description() {
+    return "clones a table";
+  }
+  
+  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> completionSet) {
+    registerCompletionForTables(root, completionSet);
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+    setPropsOption = new Option("s", "set", true, "set initial properties before the table comes online. Expects <prop>=<value>{,<prop>=<value>}");
+    o.addOption(setPropsOption);
+    excludePropsOption = new Option("e", "exclude", true, "exclude properties that should not be copied from source table. Expects <prop>{,<prop>}");
+    o.addOption(excludePropsOption);
+    noFlushOption = new Option("nf", "noFlush", false, "do not flush table data in memory before cloning.");
+    o.addOption(noFlushOption);
+    return o;
+  }
+  
+  @Override
+  public int numArgs() {
+    return 2;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/ClsCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/ClsCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/ClsCommand.java
new file mode 100644
index 0000000..e1ba4fd
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/ClsCommand.java
@@ -0,0 +1,19 @@
+/*
+ * 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.accumulo.shell.commands;
+
+public class ClsCommand extends ClearCommand {}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/CompactCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/CompactCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/CompactCommand.java
new file mode 100644
index 0000000..80dd9ba
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/CompactCommand.java
@@ -0,0 +1,129 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.IteratorSetting;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.shell.Shell;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+import org.apache.hadoop.io.Text;
+
+public class CompactCommand extends TableOperation {
+  private Option noFlushOption, waitOpt, profileOpt, cancelOpt;
+  private boolean flush;
+  private Text startRow;
+  private Text endRow;
+  private List<IteratorSetting> iterators;
+  
+  boolean override = false;
+  private boolean wait;
+  
+  private boolean cancel = false;
+
+  @Override
+  public String description() {
+    return "sets all tablets for a table to major compact as soon as possible (based on current time)";
+  }
+  
+  protected void doTableOp(final Shell shellState, final String tableName) throws AccumuloException, AccumuloSecurityException {
+    // compact the tables
+    
+    if (cancel) {
+      try {
+        shellState.getConnector().tableOperations().cancelCompaction(tableName);
+        Shell.log.info("Compaction canceled for table " + tableName);
+      } catch (TableNotFoundException e) {
+        throw new AccumuloException(e);
+      }
+    } else {
+      try {
+        if (wait) {
+          Shell.log.info("Compacting table ...");
+        }
+        
+        shellState.getConnector().tableOperations().compact(tableName, startRow, endRow, iterators, flush, wait);
+        
+        Shell.log.info("Compaction of table " + tableName + " " + (wait ? "completed" : "started") + " for given range");
+      } catch (Exception ex) {
+        throw new AccumuloException(ex);
+      }
+    }
+  }
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    
+    if (cl.hasOption(cancelOpt.getLongOpt())) {
+      cancel = true;
+      
+      if (cl.getOptions().length > 2) {
+        throw new IllegalArgumentException("Can not specify other options with cancel");
+      }
+    } else {
+      cancel = false;
+    }
+
+    flush = !cl.hasOption(noFlushOption.getOpt());
+    startRow = OptUtil.getStartRow(cl);
+    endRow = OptUtil.getEndRow(cl);
+    wait = cl.hasOption(waitOpt.getOpt());
+    
+    if (cl.hasOption(profileOpt.getOpt())) {
+      List<IteratorSetting> iterators = shellState.iteratorProfiles.get(cl.getOptionValue(profileOpt.getOpt()));
+      if (iterators == null) {
+        Shell.log.error("Profile " + cl.getOptionValue(profileOpt.getOpt()) + " does not exist");
+        return -1;
+      }
+      
+      this.iterators = new ArrayList<IteratorSetting>(iterators);
+    } else {
+      this.iterators = Collections.emptyList();
+    }
+
+
+    return super.execute(fullCommand, cl, shellState);
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options opts = super.getOptions();
+    
+    opts.addOption(OptUtil.startRowOpt());
+    opts.addOption(OptUtil.endRowOpt());
+    noFlushOption = new Option("nf", "noFlush", false, "do not flush table data in memory before compacting.");
+    opts.addOption(noFlushOption);
+    waitOpt = new Option("w", "wait", false, "wait for compact to finish");
+    opts.addOption(waitOpt);
+    
+    profileOpt = new Option("pn", "profile", true, "iterator profile name");
+    profileOpt.setArgName("profile");
+    opts.addOption(profileOpt);
+
+    cancelOpt = new Option(null, "cancel", false, "cancel user initiated compactions");
+    opts.addOption(cancelOpt);
+
+    return opts;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/ConfigCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/ConfigCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/ConfigCommand.java
new file mode 100644
index 0000000..9b39512
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/ConfigCommand.java
@@ -0,0 +1,315 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.TreeMap;
+
+import jline.console.ConsoleReader;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.NamespaceNotFoundException;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.core.client.impl.Namespaces;
+import org.apache.accumulo.core.client.impl.Tables;
+import org.apache.accumulo.core.conf.AccumuloConfiguration;
+import org.apache.accumulo.core.conf.Property;
+import org.apache.accumulo.core.security.ColumnVisibility;
+import org.apache.accumulo.core.util.BadArgumentException;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Token;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.accumulo.shell.Shell.PrintFile;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.OptionGroup;
+import org.apache.commons.cli.Options;
+
+public class ConfigCommand extends Command {
+  private Option tableOpt, deleteOpt, setOpt, filterOpt, disablePaginationOpt, outputFileOpt, namespaceOpt;
+
+  private int COL1 = 10, COL2 = 7;
+  private ConsoleReader reader;
+
+  @Override
+  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> completionSet) {
+    final Token cmd = new Token(getName());
+    final Token sub = new Token("-" + setOpt.getOpt());
+    for (Property p : Property.values()) {
+      if (!(p.getKey().endsWith(".")) && !p.isExperimental()) {
+        sub.addSubcommand(new Token(p.toString()));
+      }
+    }
+    cmd.addSubcommand(sub);
+    root.addSubcommand(cmd);
+  }
+
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException,
+      TableNotFoundException, IOException, ClassNotFoundException, NamespaceNotFoundException {
+    reader = shellState.getReader();
+
+    final String tableName = cl.getOptionValue(tableOpt.getOpt());
+    if (tableName != null && !shellState.getConnector().tableOperations().exists(tableName)) {
+      throw new TableNotFoundException(null, tableName, null);
+    }
+    final String namespace = cl.getOptionValue(namespaceOpt.getOpt());
+    if (namespace != null && !shellState.getConnector().namespaceOperations().exists(namespace)) {
+      throw new NamespaceNotFoundException(null, namespace, null);
+    }
+    if (cl.hasOption(deleteOpt.getOpt())) {
+      // delete property from table
+      String property = cl.getOptionValue(deleteOpt.getOpt());
+      if (property.contains("=")) {
+        throw new BadArgumentException("Invalid '=' operator in delete operation.", fullCommand, fullCommand.indexOf('='));
+      }
+      if (tableName != null) {
+        if (!Property.isValidTablePropertyKey(property)) {
+          Shell.log.warn("Invalid per-table property : " + property + ", still removing from zookeeper if it's there.");
+        }
+        shellState.getConnector().tableOperations().removeProperty(tableName, property);
+        Shell.log.debug("Successfully deleted table configuration option.");
+      } else if (namespace != null) {
+        if (!Property.isValidTablePropertyKey(property)) {
+          Shell.log.warn("Invalid per-table property : " + property + ", still removing from zookeeper if it's there.");
+        }
+        shellState.getConnector().namespaceOperations().removeProperty(namespace, property);
+        Shell.log.debug("Successfully deleted namespace configuration option.");
+      } else {
+        if (!Property.isValidZooPropertyKey(property)) {
+          Shell.log.warn("Invalid per-table property : " + property + ", still removing from zookeeper if it's there.");
+        }
+        shellState.getConnector().instanceOperations().removeProperty(property);
+        Shell.log.debug("Successfully deleted system configuration option");
+      }
+    } else if (cl.hasOption(setOpt.getOpt())) {
+      // set property on table
+      String property = cl.getOptionValue(setOpt.getOpt()), value = null;
+      if (!property.contains("=")) {
+        throw new BadArgumentException("Missing '=' operator in set operation.", fullCommand, fullCommand.indexOf(property));
+      }
+      final String pair[] = property.split("=", 2);
+      property = pair[0];
+      value = pair[1];
+
+      if (tableName != null) {
+        if (!Property.isValidTablePropertyKey(property)) {
+          throw new BadArgumentException("Invalid per-table property.", fullCommand, fullCommand.indexOf(property));
+        }
+        if (property.equals(Property.TABLE_DEFAULT_SCANTIME_VISIBILITY.getKey())) {
+          new ColumnVisibility(value); // validate that it is a valid expression
+        }
+        shellState.getConnector().tableOperations().setProperty(tableName, property, value);
+        Shell.log.debug("Successfully set table configuration option.");
+      } else if (namespace != null) {
+        if (!Property.isValidTablePropertyKey(property)) {
+          throw new BadArgumentException("Invalid per-table property.", fullCommand, fullCommand.indexOf(property));
+        }
+        if (property.equals(Property.TABLE_DEFAULT_SCANTIME_VISIBILITY.getKey())) {
+          new ColumnVisibility(value); // validate that it is a valid expression
+        }
+        shellState.getConnector().namespaceOperations().setProperty(namespace, property, value);
+        Shell.log.debug("Successfully set table configuration option.");
+      } else {
+        if (!Property.isValidZooPropertyKey(property)) {
+          throw new BadArgumentException("Property cannot be modified in zookeeper", fullCommand, fullCommand.indexOf(property));
+        }
+        shellState.getConnector().instanceOperations().setProperty(property, value);
+        Shell.log.debug("Successfully set system configuration option");
+      }
+    } else {
+      // display properties
+      final TreeMap<String,String> systemConfig = new TreeMap<String,String>();
+      systemConfig.putAll(shellState.getConnector().instanceOperations().getSystemConfiguration());
+
+      final String outputFile = cl.getOptionValue(outputFileOpt.getOpt());
+      final PrintFile printFile = outputFile == null ? null : new PrintFile(outputFile);
+
+      final TreeMap<String,String> siteConfig = new TreeMap<String,String>();
+      siteConfig.putAll(shellState.getConnector().instanceOperations().getSiteConfiguration());
+
+      final TreeMap<String,String> defaults = new TreeMap<String,String>();
+      for (Entry<String,String> defaultEntry : AccumuloConfiguration.getDefaultConfiguration()) {
+        defaults.put(defaultEntry.getKey(), defaultEntry.getValue());
+      }
+
+      final TreeMap<String,String> namespaceConfig = new TreeMap<String,String>();
+      if (tableName != null) {
+        String n = Namespaces.getNamespaceName(shellState.getInstance(),
+            Tables.getNamespaceId(shellState.getInstance(), Tables.getTableId(shellState.getInstance(), tableName)));
+        for (Entry<String,String> e : shellState.getConnector().namespaceOperations().getProperties(n)) {
+          namespaceConfig.put(e.getKey(), e.getValue());
+        }
+      }
+
+      Iterable<Entry<String,String>> acuconf = shellState.getConnector().instanceOperations().getSystemConfiguration().entrySet();
+      if (tableName != null) {
+        acuconf = shellState.getConnector().tableOperations().getProperties(tableName);
+      } else if (namespace != null) {
+        acuconf = shellState.getConnector().namespaceOperations().getProperties(namespace);
+      }
+      final TreeMap<String,String> sortedConf = new TreeMap<String,String>();
+      for (Entry<String,String> propEntry : acuconf) {
+        sortedConf.put(propEntry.getKey(), propEntry.getValue());
+      }
+
+      for (Entry<String,String> propEntry : acuconf) {
+        final String key = propEntry.getKey();
+        // only show properties with similar names to that
+        // specified, or all of them if none specified
+        if (cl.hasOption(filterOpt.getOpt()) && !key.contains(cl.getOptionValue(filterOpt.getOpt()))) {
+          continue;
+        }
+        if ((tableName != null || namespace != null) && !Property.isValidTablePropertyKey(key)) {
+          continue;
+        }
+        COL2 = Math.max(COL2, propEntry.getKey().length() + 3);
+      }
+
+      final ArrayList<String> output = new ArrayList<String>();
+      printConfHeader(output);
+
+      for (Entry<String,String> propEntry : sortedConf.entrySet()) {
+        final String key = propEntry.getKey();
+
+        // only show properties with similar names to that
+        // specified, or all of them if none specified
+        if (cl.hasOption(filterOpt.getOpt()) && !key.contains(cl.getOptionValue(filterOpt.getOpt()))) {
+          continue;
+        }
+        if ((tableName != null || namespace != null) && !Property.isValidTablePropertyKey(key)) {
+          continue;
+        }
+        String siteVal = siteConfig.get(key);
+        String sysVal = systemConfig.get(key);
+        String curVal = propEntry.getValue();
+        String dfault = defaults.get(key);
+        String nspVal = namespaceConfig.get(key);
+        boolean printed = false;
+
+        if (dfault != null && key.toLowerCase().contains("password")) {
+          siteVal = sysVal = dfault = curVal = curVal.replaceAll(".", "*");
+        }
+        if (sysVal != null) {
+          if (defaults.containsKey(key) && !Property.getPropertyByKey(key).isExperimental()) {
+            printConfLine(output, "default", key, dfault);
+            printed = true;
+          }
+          if (!defaults.containsKey(key) || !defaults.get(key).equals(siteVal)) {
+            printConfLine(output, "site", printed ? "   @override" : key, siteVal == null ? "" : siteVal);
+            printed = true;
+          }
+          if (!siteConfig.containsKey(key) || !siteVal.equals(sysVal)) {
+            printConfLine(output, "system", printed ? "   @override" : key, sysVal == null ? "" : sysVal);
+            printed = true;
+          }
+
+        }
+        if (nspVal != null) {
+          if (!systemConfig.containsKey(key) || !sysVal.equals(nspVal)) {
+            printConfLine(output, "namespace", printed ? "   @override" : key, nspVal == null ? "" : nspVal);
+            printed = true;
+          }
+        }
+
+        // show per-table value only if it is different (overridden)
+        if (tableName != null && !curVal.equals(nspVal)) {
+          printConfLine(output, "table", printed ? "   @override" : key, curVal);
+        } else if (namespace != null && !curVal.equals(sysVal)) {
+          printConfLine(output, "namespace", printed ? "   @override" : key, curVal);
+        }
+      }
+      printConfFooter(output);
+      shellState.printLines(output.iterator(), !cl.hasOption(disablePaginationOpt.getOpt()), printFile);
+      if (printFile != null) {
+        printFile.close();
+      }
+    }
+    return 0;
+  }
+
+  private void printConfHeader(List<String> output) {
+    printConfFooter(output);
+    output.add(String.format("%-" + COL1 + "s | %-" + COL2 + "s | %s", "SCOPE", "NAME", "VALUE"));
+    printConfFooter(output);
+  }
+
+  private void printConfLine(List<String> output, String s1, String s2, String s3) {
+    if (s2.length() < COL2) {
+      s2 += " " + Shell.repeat(".", COL2 - s2.length() - 1);
+    }
+    output.add(String.format("%-" + COL1 + "s | %-" + COL2 + "s | %s", s1, s2,
+        s3.replace("\n", "\n" + Shell.repeat(" ", COL1 + 1) + "|" + Shell.repeat(" ", COL2 + 2) + "|" + " ")));
+  }
+
+  private void printConfFooter(List<String> output) {
+    int col3 = Math.max(1, Math.min(Integer.MAX_VALUE, reader.getTerminal().getWidth() - COL1 - COL2 - 6));
+    output.add(String.format("%" + COL1 + "s-+-%" + COL2 + "s-+-%-" + col3 + "s", Shell.repeat("-", COL1), Shell.repeat("-", COL2), Shell.repeat("-", col3)));
+  }
+
+  @Override
+  public String description() {
+    return "prints system properties and table specific properties";
+  }
+
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+    final OptionGroup og = new OptionGroup();
+    final OptionGroup tgroup = new OptionGroup();
+
+    tableOpt = new Option(Shell.tableOption, "table", true, "table to display/set/delete properties for");
+    deleteOpt = new Option("d", "delete", true, "delete a per-table property");
+    setOpt = new Option("s", "set", true, "set a per-table property");
+    filterOpt = new Option("f", "filter", true, "show only properties that contain this string");
+    disablePaginationOpt = new Option("np", "no-pagination", false, "disables pagination of output");
+    outputFileOpt = new Option("o", "output", true, "local file to write the scan output to");
+    namespaceOpt = new Option(Shell.namespaceOption, "namespace", true, "namespace to display/set/delete properties for");
+
+    tableOpt.setArgName("table");
+    deleteOpt.setArgName("property");
+    setOpt.setArgName("property=value");
+    filterOpt.setArgName("string");
+    outputFileOpt.setArgName("file");
+    namespaceOpt.setArgName("namespace");
+
+    og.addOption(deleteOpt);
+    og.addOption(setOpt);
+    og.addOption(filterOpt);
+
+    tgroup.addOption(tableOpt);
+    tgroup.addOption(namespaceOpt);
+
+    o.addOptionGroup(tgroup);
+    o.addOptionGroup(og);
+    o.addOption(disablePaginationOpt);
+    o.addOption(outputFileOpt);
+
+    return o;
+  }
+
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/ConstraintCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/ConstraintCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/ConstraintCommand.java
new file mode 100644
index 0000000..0b6adbf
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/ConstraintCommand.java
@@ -0,0 +1,134 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.util.Map.Entry;
+
+import org.apache.accumulo.core.constraints.Constraint;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.ShellCommandException;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.accumulo.shell.ShellCommandException.ErrorCode;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.OptionGroup;
+import org.apache.commons.cli.Options;
+
+public class ConstraintCommand extends Command {
+  protected Option namespaceOpt;
+
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    final String tableName;
+    final String namespace;
+
+    if (cl.hasOption(namespaceOpt.getOpt())) {
+      namespace = cl.getOptionValue(namespaceOpt.getOpt());
+    } else {
+      namespace = null;
+    }
+
+    if (cl.hasOption(OptUtil.tableOpt().getOpt()) || !shellState.getTableName().isEmpty()) {
+      tableName = OptUtil.getTableOpt(cl, shellState);
+    } else {
+      tableName = null;
+    }
+
+    int i;
+    switch (OptUtil.getAldOpt(cl)) {
+      case ADD:
+        for (String constraint : cl.getArgs()) {
+          if (namespace != null) {
+            if (!shellState.getConnector().namespaceOperations().testClassLoad(namespace, constraint, Constraint.class.getName())) {
+              throw new ShellCommandException(ErrorCode.INITIALIZATION_FAILURE, "Servers are unable to load " + constraint + " as type "
+                  + Constraint.class.getName());
+            }
+            i = shellState.getConnector().namespaceOperations().addConstraint(namespace, constraint);
+            shellState.getReader().println("Added constraint " + constraint + " to namespace " + namespace + " with number " + i);
+          } else if (tableName != null && !tableName.isEmpty()) {
+            if (!shellState.getConnector().tableOperations().testClassLoad(tableName, constraint, Constraint.class.getName())) {
+              throw new ShellCommandException(ErrorCode.INITIALIZATION_FAILURE, "Servers are unable to load " + constraint + " as type "
+                  + Constraint.class.getName());
+            }
+            i = shellState.getConnector().tableOperations().addConstraint(tableName, constraint);
+            shellState.getReader().println("Added constraint " + constraint + " to table " + tableName + " with number " + i);
+          } else {
+            throw new IllegalArgumentException("Please specify either a table or a namespace");
+          }
+        }
+        break;
+      case DELETE:
+        for (String constraint : cl.getArgs()) {
+          i = Integer.parseInt(constraint);
+          if (namespace != null) {
+            shellState.getConnector().namespaceOperations().removeConstraint(namespace, i);
+            shellState.getReader().println("Removed constraint " + i + " from namespace " + namespace);
+          } else if (tableName != null) {
+            shellState.getConnector().tableOperations().removeConstraint(tableName, i);
+            shellState.getReader().println("Removed constraint " + i + " from table " + tableName);
+          } else {
+            throw new IllegalArgumentException("Please specify either a table or a namespace");
+          }
+        }
+        break;
+      case LIST:
+        if (namespace != null) {
+          for (Entry<String,Integer> property : shellState.getConnector().namespaceOperations().listConstraints(namespace).entrySet()) {
+            shellState.getReader().println(property.toString());
+          }
+        } else if (tableName != null) {
+          for (Entry<String,Integer> property : shellState.getConnector().tableOperations().listConstraints(tableName).entrySet()) {
+            shellState.getReader().println(property.toString());
+          }
+        } else {
+          throw new IllegalArgumentException("Please specify either a table or a namespace");
+        }
+    }
+
+    return 0;
+  }
+
+  @Override
+  public String description() {
+    return "adds, deletes, or lists constraints for a table";
+  }
+
+  @Override
+  public int numArgs() {
+    return Shell.NO_FIXED_ARG_LENGTH_CHECK;
+  }
+
+  @Override
+  public String usage() {
+    return getName() + " <constraint>{ <constraint>}";
+  }
+
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+    o.addOptionGroup(OptUtil.addListDeleteGroup("constraint"));
+
+    OptionGroup grp = new OptionGroup();
+    grp.addOption(OptUtil.tableOpt("table to add, delete, or list constraints for"));
+    namespaceOpt = new Option(Shell.namespaceOption, "namespace", true, "name of a namespace to operate on");
+    namespaceOpt.setArgName("namespace");
+    grp.addOption(namespaceOpt);
+
+    o.addOptionGroup(grp);
+    return o;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/CreateNamespaceCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/CreateNamespaceCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/CreateNamespaceCommand.java
new file mode 100644
index 0000000..e278105
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/CreateNamespaceCommand.java
@@ -0,0 +1,99 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.io.IOException;
+import java.util.Map.Entry;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.NamespaceExistsException;
+import org.apache.accumulo.core.client.NamespaceNotFoundException;
+import org.apache.accumulo.core.client.TableExistsException;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.core.conf.Property;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.OptionGroup;
+import org.apache.commons.cli.Options;
+
+public class CreateNamespaceCommand extends Command {
+  private Option createNamespaceOptCopyConfig;
+
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException,
+      TableExistsException, TableNotFoundException, IOException, ClassNotFoundException, NamespaceExistsException, NamespaceNotFoundException {
+
+    if (createNamespaceOptCopyConfig == null) {
+      getOptions();
+    }
+
+    String namespace = cl.getArgs()[0];
+
+    shellState.getConnector().namespaceOperations().create(namespace);
+
+    // Copy options if flag was set
+    Iterable<Entry<String,String>> configuration = null;
+    if (cl.hasOption(createNamespaceOptCopyConfig.getOpt())) {
+      String copy = cl.getOptionValue(createNamespaceOptCopyConfig.getOpt());
+      if (shellState.getConnector().namespaceOperations().exists(namespace)) {
+        configuration = shellState.getConnector().namespaceOperations().getProperties(copy);
+      }
+    } 
+    if (configuration != null) {
+      for (Entry<String,String> entry : configuration) {
+        if (Property.isValidTablePropertyKey(entry.getKey())) {
+          shellState.getConnector().namespaceOperations().setProperty(namespace, entry.getKey(), entry.getValue());
+        }
+      }
+    }
+
+    return 0;
+  }
+
+  @Override
+  public String description() {
+    return "creates a new namespace";
+  }
+
+  @Override
+  public String usage() {
+    return getName() + " <namespaceName>";
+  }
+
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+
+    createNamespaceOptCopyConfig = new Option("cc", "copy-config", true, "namespace to copy configuration from");
+    createNamespaceOptCopyConfig.setArgName("namespace");
+
+    OptionGroup ogp = new OptionGroup();
+    ogp.addOption(createNamespaceOptCopyConfig);
+
+    o.addOptionGroup(ogp);
+
+    return o;
+  }
+
+  @Override
+  public int numArgs() {
+    return 1;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/CreateTableCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/CreateTableCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/CreateTableCommand.java
new file mode 100644
index 0000000..81b39d2
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/CreateTableCommand.java
@@ -0,0 +1,203 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.io.IOException;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.TableExistsException;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.core.client.admin.TimeType;
+import org.apache.accumulo.core.client.impl.Tables;
+import org.apache.accumulo.core.conf.Property;
+import org.apache.accumulo.core.iterators.IteratorUtil;
+import org.apache.accumulo.core.security.VisibilityConstraint;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.ShellUtil;
+import org.apache.accumulo.shell.Token;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.OptionGroup;
+import org.apache.commons.cli.Options;
+import org.apache.hadoop.io.Text;
+
+public class CreateTableCommand extends Command {
+  private Option createTableOptCopySplits;
+  private Option createTableOptCopyConfig;
+  private Option createTableOptSplit;
+  private Option createTableOptTimeLogical;
+  private Option createTableOptTimeMillis;
+  private Option createTableNoDefaultIters;
+  private Option createTableOptEVC;
+  private Option base64Opt;
+  private Option createTableOptFormatter;
+
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException,
+      TableExistsException, TableNotFoundException, IOException, ClassNotFoundException {
+
+    final String testTableName = cl.getArgs()[0];
+
+    if (!testTableName.matches(Tables.VALID_NAME_REGEX)) {
+      shellState.getReader().println("Only letters, numbers and underscores are allowed for use in table names.");
+      throw new IllegalArgumentException();
+    }
+
+    final String tableName = cl.getArgs()[0];
+    if (shellState.getConnector().tableOperations().exists(tableName)) {
+      throw new TableExistsException(null, tableName, null);
+    }
+    final SortedSet<Text> partitions = new TreeSet<Text>();
+    final boolean decode = cl.hasOption(base64Opt.getOpt());
+
+    if (cl.hasOption(createTableOptSplit.getOpt())) {
+      partitions.addAll(ShellUtil.scanFile(cl.getOptionValue(createTableOptSplit.getOpt()), decode));
+    } else if (cl.hasOption(createTableOptCopySplits.getOpt())) {
+      final String oldTable = cl.getOptionValue(createTableOptCopySplits.getOpt());
+      if (!shellState.getConnector().tableOperations().exists(oldTable)) {
+        throw new TableNotFoundException(null, oldTable, null);
+      }
+      partitions.addAll(shellState.getConnector().tableOperations().listSplits(oldTable));
+    }
+
+    if (cl.hasOption(createTableOptCopyConfig.getOpt())) {
+      final String oldTable = cl.getOptionValue(createTableOptCopyConfig.getOpt());
+      if (!shellState.getConnector().tableOperations().exists(oldTable)) {
+        throw new TableNotFoundException(null, oldTable, null);
+      }
+    }
+
+    TimeType timeType = TimeType.MILLIS;
+    if (cl.hasOption(createTableOptTimeLogical.getOpt())) {
+      timeType = TimeType.LOGICAL;
+    }
+
+    // create table
+    shellState.getConnector().tableOperations().create(tableName, true, timeType);
+    if (partitions.size() > 0) {
+      shellState.getConnector().tableOperations().addSplits(tableName, partitions);
+    }
+
+    shellState.setTableName(tableName); // switch shell to new table context
+
+    if (cl.hasOption(createTableNoDefaultIters.getOpt())) {
+      for (String key : IteratorUtil.generateInitialTableProperties(true).keySet()) {
+        shellState.getConnector().tableOperations().removeProperty(tableName, key);
+      }
+    }
+
+    // Copy options if flag was set
+    if (cl.hasOption(createTableOptCopyConfig.getOpt())) {
+      if (shellState.getConnector().tableOperations().exists(tableName)) {
+        final Iterable<Entry<String,String>> configuration = shellState.getConnector().tableOperations()
+            .getProperties(cl.getOptionValue(createTableOptCopyConfig.getOpt()));
+        for (Entry<String,String> entry : configuration) {
+          if (Property.isValidTablePropertyKey(entry.getKey())) {
+            shellState.getConnector().tableOperations().setProperty(tableName, entry.getKey(), entry.getValue());
+          }
+        }
+      }
+    }
+
+    if (cl.hasOption(createTableOptEVC.getOpt())) {
+      try {
+        shellState.getConnector().tableOperations().addConstraint(tableName, VisibilityConstraint.class.getName());
+      } catch (AccumuloException e) {
+        Shell.log.warn(e.getMessage() + " while setting visibility constraint, but table was created");
+      }
+    }
+
+    // Load custom formatter if set
+    if (cl.hasOption(createTableOptFormatter.getOpt())) {
+      final String formatterClass = cl.getOptionValue(createTableOptFormatter.getOpt());
+
+      shellState.getConnector().tableOperations().setProperty(tableName, Property.TABLE_FORMATTER_CLASS.toString(), formatterClass);
+    }
+
+    return 0;
+  }
+
+  @Override
+  public String description() {
+    return "creates a new table, with optional aggregators and optionally pre-split";
+  }
+
+  @Override
+  public String usage() {
+    return getName() + " <tableName>";
+  }
+
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+
+    createTableOptCopyConfig = new Option("cc", "copy-config", true, "table to copy configuration from");
+    createTableOptCopySplits = new Option("cs", "copy-splits", true, "table to copy current splits from");
+    createTableOptSplit = new Option("sf", "splits-file", true, "file with a newline-separated list of rows to split the table with");
+    createTableOptTimeLogical = new Option("tl", "time-logical", false, "use logical time");
+    createTableOptTimeMillis = new Option("tm", "time-millis", false, "use time in milliseconds");
+    createTableNoDefaultIters = new Option("ndi", "no-default-iterators", false, "prevent creation of the normal default iterator set");
+    createTableOptEVC = new Option("evc", "enable-visibility-constraint", false,
+        "prevent users from writing data they cannot read.  When enabling this, consider disabling bulk import and alter table.");
+    createTableOptFormatter = new Option("f", "formatter", true, "default formatter to set");
+
+    createTableOptCopyConfig.setArgName("table");
+    createTableOptCopySplits.setArgName("table");
+    createTableOptSplit.setArgName("filename");
+    createTableOptFormatter.setArgName("className");
+
+    // Splits and CopySplits are put in an optionsgroup to make them
+    // mutually exclusive
+    final OptionGroup splitOrCopySplit = new OptionGroup();
+    splitOrCopySplit.addOption(createTableOptSplit);
+    splitOrCopySplit.addOption(createTableOptCopySplits);
+
+    final OptionGroup timeGroup = new OptionGroup();
+    timeGroup.addOption(createTableOptTimeLogical);
+    timeGroup.addOption(createTableOptTimeMillis);
+
+    base64Opt = new Option("b64", "base64encoded", false, "decode encoded split points");
+    o.addOption(base64Opt);
+
+    o.addOptionGroup(splitOrCopySplit);
+    o.addOptionGroup(timeGroup);
+    o.addOption(createTableOptSplit);
+    o.addOption(createTableOptCopyConfig);
+    o.addOption(createTableNoDefaultIters);
+    o.addOption(createTableOptEVC);
+    o.addOption(createTableOptFormatter);
+
+    return o;
+  }
+
+  @Override
+  public int numArgs() {
+    return 1;
+  }
+
+  @Override
+  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> special) {
+    registerCompletionForNamespaces(root, special);
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/CreateUserCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/CreateUserCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/CreateUserCommand.java
new file mode 100644
index 0000000..2a7359f
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/CreateUserCommand.java
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.accumulo.shell.commands;
+
+import java.io.IOException;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.TableExistsException;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.core.client.security.tokens.PasswordToken;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Options;
+
+public class CreateUserCommand extends Command {
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, TableNotFoundException,
+      AccumuloSecurityException, TableExistsException, IOException {
+    final String user = cl.getArgs()[0];
+    
+    final String password = shellState.readMaskedLine("Enter new password for '" + user + "': ", '*');
+    if (password == null) {
+      shellState.getReader().println();
+      return 0;
+    } // user canceled
+    String passwordConfirm = shellState.readMaskedLine("Please confirm new password for '" + user + "': ", '*');
+    if (passwordConfirm == null) {
+      shellState.getReader().println();
+      return 0;
+    } // user canceled
+    
+    if (!password.equals(passwordConfirm)) {
+      throw new IllegalArgumentException("Passwords do not match");
+    }
+    shellState.getConnector().securityOperations().createLocalUser(user, new PasswordToken(password));
+    Shell.log.debug("Created user " + user);
+    return 0;
+  }
+  
+  @Override
+  public String usage() {
+    return getName() + " <username>";
+  }
+  
+  @Override
+  public String description() {
+    return "creates a new user";
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+    return o;
+  }
+  
+  @Override
+  public int numArgs() {
+    return 1;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/DUCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/DUCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/DUCommand.java
new file mode 100644
index 0000000..eb6aeb5
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/DUCommand.java
@@ -0,0 +1,124 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import org.apache.accumulo.core.client.Instance;
+import org.apache.accumulo.core.client.NamespaceNotFoundException;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.core.client.admin.DiskUsage;
+import org.apache.accumulo.core.client.impl.Namespaces;
+import org.apache.accumulo.core.util.NumUtil;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+
+public class DUCommand extends Command {
+
+  private Option optTablePattern, optHumanReadble, optNamespace;
+
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws IOException, TableNotFoundException,
+      NamespaceNotFoundException {
+
+    final SortedSet<String> tables = new TreeSet<String>(Arrays.asList(cl.getArgs()));
+
+    if (cl.hasOption(Shell.tableOption)) {
+      String tableName = cl.getOptionValue(Shell.tableOption);
+      if (!shellState.getConnector().tableOperations().exists(tableName)) {
+        throw new TableNotFoundException(tableName, tableName, "specified table that doesn't exist");
+      }
+      tables.add(tableName);
+    }
+
+    if (cl.hasOption(optNamespace.getOpt())) {
+      Instance instance = shellState.getInstance();
+      String namespaceId = Namespaces.getNamespaceId(instance, cl.getOptionValue(optNamespace.getOpt()));
+      tables.addAll(Namespaces.getTableNames(instance, namespaceId));
+    }
+
+    boolean prettyPrint = cl.hasOption(optHumanReadble.getOpt()) ? true : false;
+
+    // Add any patterns
+    if (cl.hasOption(optTablePattern.getOpt())) {
+      for (String table : shellState.getConnector().tableOperations().list()) {
+        if (table.matches(cl.getOptionValue(optTablePattern.getOpt()))) {
+          tables.add(table);
+        }
+      }
+    }
+
+    // If we didn't get any tables, and we have a table selected, add the current table
+    if (tables.isEmpty() && !shellState.getTableName().isEmpty()) {
+      tables.add(shellState.getTableName());
+    }
+
+    try {
+      String valueFormat = prettyPrint ? "%9s" : "%,24d";
+      for (DiskUsage usage : shellState.getConnector().tableOperations().getDiskUsage(tables)) {
+        Object value = prettyPrint ? NumUtil.bigNumberForSize(usage.getUsage()) : usage.getUsage();
+        shellState.getReader().println(String.format(valueFormat + " %s", value, usage.getTables()));
+      }
+    } catch (Exception ex) {
+      throw new RuntimeException(ex);
+    }
+    return 0;
+  }
+
+  @Override
+  public String description() {
+    return "prints how much space, in bytes, is used by files referenced by a table.  When multiple tables are specified it prints how much space, in bytes, is used by files shared between tables, if any.";
+  }
+
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+
+    optTablePattern = new Option("p", "pattern", true, "regex pattern of table names");
+    optTablePattern.setArgName("pattern");
+
+    optHumanReadble = new Option("h", "human-readable", false, "format large sizes to human readable units");
+    optHumanReadble.setArgName("human readable output");
+
+    optNamespace = new Option(Shell.namespaceOption, "namespace", true, "name of a namespace");
+    optNamespace.setArgName("namespace");
+
+    o.addOption(OptUtil.tableOpt("table to examine"));
+
+    o.addOption(optTablePattern);
+    o.addOption(optHumanReadble);
+    o.addOption(optNamespace);
+
+    return o;
+  }
+
+  @Override
+  public String usage() {
+    return getName() + " <table>{ <table>}";
+  }
+
+  @Override
+  public int numArgs() {
+    return Shell.NO_FIXED_ARG_LENGTH_CHECK;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/DebugCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/DebugCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/DebugCommand.java
new file mode 100644
index 0000000..ab40adc
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/DebugCommand.java
@@ -0,0 +1,71 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.accumulo.core.util.BadArgumentException;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Token;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+
+public class DebugCommand extends Command {
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws IOException {
+    if (cl.getArgs().length == 1) {
+      if (cl.getArgs()[0].equalsIgnoreCase("on")) {
+        Shell.setDebugging(true);
+      } else if (cl.getArgs()[0].equalsIgnoreCase("off")) {
+        Shell.setDebugging(false);
+      } else {
+        throw new BadArgumentException("Argument must be 'on' or 'off'", fullCommand, fullCommand.indexOf(cl.getArgs()[0]));
+      }
+    } else if (cl.getArgs().length == 0) {
+      shellState.getReader().println(Shell.isDebuggingEnabled() ? "on" : "off");
+    } else {
+      shellState.printException(new IllegalArgumentException("Expected 0 or 1 argument. There were " + cl.getArgs().length + "."));
+      printHelp(shellState);
+      return 1;
+    }
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "turns debug logging on or off";
+  }
+  
+  @Override
+  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> special) {
+    final Token debug_command = new Token(getName());
+    debug_command.addSubcommand(Arrays.asList(new String[] {"on", "off"}));
+    root.addSubcommand(debug_command);
+  }
+  
+  @Override
+  public String usage() {
+    return getName() + " [ on | off ]";
+  }
+  
+  @Override
+  public int numArgs() {
+    return Shell.NO_FIXED_ARG_LENGTH_CHECK;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteCommand.java
new file mode 100644
index 0000000..2601f58
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteCommand.java
@@ -0,0 +1,112 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.io.IOException;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.BatchWriter;
+import org.apache.accumulo.core.client.BatchWriterConfig;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.core.conf.AccumuloConfiguration;
+import org.apache.accumulo.core.data.Mutation;
+import org.apache.accumulo.core.security.ColumnVisibility;
+import org.apache.accumulo.core.tabletserver.thrift.ConstraintViolationException;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+import org.apache.hadoop.io.Text;
+
+public class DeleteCommand extends Command {
+  private Option deleteOptAuths, timestampOpt;
+  private Option timeoutOption;
+  
+  protected long getTimeout(final CommandLine cl) {
+    if (cl.hasOption(timeoutOption.getLongOpt())) {
+      return AccumuloConfiguration.getTimeInMillis(cl.getOptionValue(timeoutOption.getLongOpt()));
+    }
+    
+    return Long.MAX_VALUE;
+  }
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException,
+      TableNotFoundException, IOException, ConstraintViolationException {
+    shellState.checkTableState();
+    
+    final Mutation m = new Mutation(new Text(cl.getArgs()[0].getBytes(Shell.CHARSET)));
+    final Text colf = new Text(cl.getArgs()[1].getBytes(Shell.CHARSET));
+    final Text colq = new Text(cl.getArgs()[2].getBytes(Shell.CHARSET));
+    
+    if (cl.hasOption(deleteOptAuths.getOpt())) {
+      final ColumnVisibility le = new ColumnVisibility(cl.getOptionValue(deleteOptAuths.getOpt()));
+      if (cl.hasOption(timestampOpt.getOpt())) {
+        m.putDelete(colf, colq, le, Long.parseLong(cl.getOptionValue(timestampOpt.getOpt())));
+      } else {
+        m.putDelete(colf, colq, le);
+      }
+    } else if (cl.hasOption(timestampOpt.getOpt())) {
+      m.putDelete(colf, colq, Long.parseLong(cl.getOptionValue(timestampOpt.getOpt())));
+    } else {
+      m.putDelete(colf, colq);
+    }
+    final BatchWriter bw = shellState.getConnector().createBatchWriter(shellState.getTableName(),
+        new BatchWriterConfig().setMaxMemory(Math.max(m.estimatedMemoryUsed(), 1024)).setMaxWriteThreads(1).setTimeout(getTimeout(cl), TimeUnit.MILLISECONDS));
+    bw.addMutation(m);
+    bw.close();
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "deletes a record from a table";
+  }
+  
+  @Override
+  public String usage() {
+    return getName() + " <row> <colfamily> <colqualifier>";
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+    
+    deleteOptAuths = new Option("l", "visibility-label", true, "formatted visibility");
+    deleteOptAuths.setArgName("expression");
+    o.addOption(deleteOptAuths);
+    
+    timestampOpt = new Option("ts", "timestamp", true, "timestamp to use for deletion");
+    timestampOpt.setArgName("timestamp");
+    o.addOption(timestampOpt);
+    
+    timeoutOption = new Option(null, "timeout", true,
+        "time before insert should fail if no data is written. If no unit is given assumes seconds.  Units d,h,m,s,and ms are supported.  e.g. 30s or 100ms");
+    timeoutOption.setArgName("timeout");
+    o.addOption(timeoutOption);
+    
+    return o;
+  }
+  
+  @Override
+  public int numArgs() {
+    return 3;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteIterCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteIterCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteIterCommand.java
new file mode 100644
index 0000000..ec60aee
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteIterCommand.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.accumulo.shell.commands;
+
+import java.util.EnumSet;
+
+import org.apache.accumulo.core.iterators.IteratorUtil.IteratorScope;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.OptionGroup;
+import org.apache.commons.cli.Options;
+
+public class DeleteIterCommand extends Command {
+  private Option allScopeOpt, mincScopeOpt, majcScopeOpt, scanScopeOpt, nameOpt;
+
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+
+    boolean tables = cl.hasOption(OptUtil.tableOpt().getOpt()) || !shellState.getTableName().isEmpty();
+    boolean namespaces = cl.hasOption(OptUtil.namespaceOpt().getOpt());
+
+    final String name = cl.getOptionValue(nameOpt.getOpt());
+
+    if (namespaces) {
+      if (!shellState.getConnector().namespaceOperations().listIterators(OptUtil.getNamespaceOpt(cl, shellState)).containsKey(name)) {
+        Shell.log.warn("no iterators found that match your criteria");
+        return 0;
+      }
+    } else if (tables) {
+      if (!shellState.getConnector().tableOperations().listIterators(OptUtil.getTableOpt(cl, shellState)).containsKey(name)) {
+        Shell.log.warn("no iterators found that match your criteria");
+        return 0;
+      }
+    } else {
+      throw new IllegalArgumentException("No table or namespace specified");
+    }
+
+    final EnumSet<IteratorScope> scopes = EnumSet.noneOf(IteratorScope.class);
+    if (cl.hasOption(allScopeOpt.getOpt()) || cl.hasOption(mincScopeOpt.getOpt())) {
+      scopes.add(IteratorScope.minc);
+    }
+    if (cl.hasOption(allScopeOpt.getOpt()) || cl.hasOption(majcScopeOpt.getOpt())) {
+      scopes.add(IteratorScope.majc);
+    }
+    if (cl.hasOption(allScopeOpt.getOpt()) || cl.hasOption(scanScopeOpt.getOpt())) {
+      scopes.add(IteratorScope.scan);
+    }
+    if (scopes.isEmpty()) {
+      throw new IllegalArgumentException("You must select at least one scope to configure");
+    }
+
+    if (namespaces) {
+      shellState.getConnector().namespaceOperations().removeIterator(OptUtil.getNamespaceOpt(cl, shellState), name, scopes);
+    } else if (tables) {
+      shellState.getConnector().tableOperations().removeIterator(OptUtil.getTableOpt(cl, shellState), name, scopes);
+    } else {
+      throw new IllegalArgumentException("No table or namespace specified");
+    }
+    return 0;
+  }
+
+  @Override
+  public String description() {
+    return "deletes a table-specific or namespace-specific iterator";
+  }
+
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+
+    nameOpt = new Option("n", "name", true, "iterator to delete");
+    nameOpt.setArgName("itername");
+    nameOpt.setRequired(true);
+
+    allScopeOpt = new Option("all", "all-scopes", false, "remove from all scopes");
+    mincScopeOpt = new Option(IteratorScope.minc.name(), "minor-compaction", false, "remove from minor compaction scope");
+    majcScopeOpt = new Option(IteratorScope.majc.name(), "major-compaction", false, "remove from major compaction scope");
+    scanScopeOpt = new Option(IteratorScope.scan.name(), "scan-time", false, "remove from scan scope");
+
+    OptionGroup grp = new OptionGroup();
+    grp.addOption(OptUtil.tableOpt("table to delete the iterator from"));
+    grp.addOption(OptUtil.namespaceOpt("namespace to delete the iterator from"));
+    o.addOptionGroup(grp);
+    o.addOption(nameOpt);
+
+    o.addOption(allScopeOpt);
+    o.addOption(mincScopeOpt);
+    o.addOption(majcScopeOpt);
+    o.addOption(scanScopeOpt);
+
+    return o;
+  }
+
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteManyCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteManyCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteManyCommand.java
new file mode 100644
index 0000000..c29a92c
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteManyCommand.java
@@ -0,0 +1,82 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.util.concurrent.TimeUnit;
+
+import org.apache.accumulo.core.client.BatchWriter;
+import org.apache.accumulo.core.client.BatchWriterConfig;
+import org.apache.accumulo.core.client.IteratorSetting;
+import org.apache.accumulo.core.client.Scanner;
+import org.apache.accumulo.core.iterators.SortedKeyIterator;
+import org.apache.accumulo.core.security.Authorizations;
+import org.apache.accumulo.core.util.interpret.ScanInterpreter;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.format.DeleterFormatter;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+
+public class DeleteManyCommand extends ScanCommand {
+  private Option forceOpt;
+  
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    final String tableName = OptUtil.getTableOpt(cl, shellState);
+    
+    final ScanInterpreter interpeter = getInterpreter(cl, tableName, shellState);
+
+    // handle first argument, if present, the authorizations list to
+    // scan with
+    final Authorizations auths = getAuths(cl, shellState);
+    final Scanner scanner = shellState.getConnector().createScanner(tableName, auths);
+    
+    scanner.addScanIterator(new IteratorSetting(Integer.MAX_VALUE, "NOVALUE", SortedKeyIterator.class));
+    
+    // handle session-specific scan iterators
+    addScanIterators(shellState, cl, scanner, tableName);
+    
+    // handle remaining optional arguments
+    scanner.setRange(getRange(cl, interpeter));
+    
+    scanner.setTimeout(getTimeout(cl), TimeUnit.MILLISECONDS);
+
+    // handle columns
+    fetchColumns(cl, scanner, interpeter);
+    
+    // output / delete the records
+    final BatchWriter writer = shellState.getConnector()
+        .createBatchWriter(tableName, new BatchWriterConfig().setTimeout(getTimeout(cl), TimeUnit.MILLISECONDS));
+    shellState.printLines(new DeleterFormatter(writer, scanner, cl.hasOption(timestampOpt.getOpt()), shellState, cl.hasOption(forceOpt.getOpt())), false);
+    
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "scans a table and deletes the resulting records";
+  }
+  
+  @Override
+  public Options getOptions() {
+    forceOpt = new Option("f", "force", false, "force deletion without prompting");
+    final Options opts = super.getOptions();
+    opts.addOption(forceOpt);
+    opts.addOption(OptUtil.tableOpt("table to delete entries from"));
+    return opts;
+  }
+  
+}


[11/53] [abbrv] ACCUMULO-1897 Move shell into new package and module

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/FormatterCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/FormatterCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/FormatterCommand.java
deleted file mode 100644
index 631c6e6..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/FormatterCommand.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.accumulo.core.util.shell.commands;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.conf.Property;
-import org.apache.accumulo.core.util.format.Formatter;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-
-public class FormatterCommand extends ShellPluginConfigurationCommand {
-  
-  private Option interpeterOption;
-
-  public FormatterCommand() {
-    super("formatter", Property.TABLE_FORMATTER_CLASS, "f");
-  }
-
-  @Override
-  public String description() {
-    return "specifies a formatter to use for displaying table entries";
-  }
-
-  public static Class<? extends Formatter> getCurrentFormatter(final String tableName, final Shell shellState) {
-    return ShellPluginConfigurationCommand.getPluginClass(tableName, shellState, Formatter.class, Property.TABLE_FORMATTER_CLASS);
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options options = super.getOptions();
-    
-    interpeterOption = new Option("i", "interpeter", false, "configure class as interpreter also");
-    
-    options.addOption(interpeterOption);
-    
-    return options;
-  }
-  
-  protected void setPlugin(final CommandLine cl, final Shell shellState, final String tableName, final String className) throws AccumuloException, AccumuloSecurityException {
-    super.setPlugin(cl, shellState, tableName, className);
-    if (cl.hasOption(interpeterOption.getOpt())) {
-      shellState.getConnector().tableOperations().setProperty(tableName, Property.TABLE_INTERPRETER_CLASS.toString(), className);
-    }
-  }
-  
-  protected void removePlugin(final CommandLine cl, final Shell shellState, final String tableName) throws AccumuloException, AccumuloSecurityException {
-    super.removePlugin(cl, shellState, tableName);
-    if (cl.hasOption(interpeterOption.getOpt())) {
-      shellState.getConnector().tableOperations().removeProperty(tableName, Property.TABLE_INTERPRETER_CLASS.toString());
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/GetAuthsCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/GetAuthsCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/GetAuthsCommand.java
deleted file mode 100644
index e40a83f..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/GetAuthsCommand.java
+++ /dev/null
@@ -1,67 +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.accumulo.core.util.shell.commands;
-
-import java.io.IOException;
-import java.util.SortedSet;
-import java.util.TreeSet;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.security.Authorizations;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-import org.apache.commons.lang.StringUtils;
-
-public class GetAuthsCommand extends Command {
-  private Option userOpt;
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException, IOException {
-    final String user = cl.getOptionValue(userOpt.getOpt(), shellState.getConnector().whoami());
-    // Sort authorizations
-    Authorizations auths = shellState.getConnector().securityOperations().getUserAuthorizations(user);
-    SortedSet<String> set = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
-    for (byte[] auth : auths) {
-      set.add(new String(auth));
-    }
-    shellState.getReader().println(StringUtils.join(set, ','));
-    return 0;
-  }
-  
-  @Override
-  public String description() {
-    return "displays the maximum scan authorizations for a user";
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-    userOpt = new Option(Shell.userOption, "user", true, "user to operate on");
-    userOpt.setArgName("user");
-    o.addOption(userOpt);
-    return o;
-  }
-  
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/GetGroupsCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/GetGroupsCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/GetGroupsCommand.java
deleted file mode 100644
index bef2e5c..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/GetGroupsCommand.java
+++ /dev/null
@@ -1,60 +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.accumulo.core.util.shell.commands;
-
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-
-import org.apache.accumulo.core.util.LocalityGroupUtil;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Options;
-import org.apache.hadoop.io.Text;
-
-public class GetGroupsCommand extends Command {
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    final String tableName = OptUtil.getTableOpt(cl, shellState);
-    
-    final Map<String,Set<Text>> groups = shellState.getConnector().tableOperations().getLocalityGroups(tableName);
-    
-    for (Entry<String,Set<Text>> entry : groups.entrySet()) {
-      shellState.getReader().println(entry.getKey() + "=" + LocalityGroupUtil.encodeColumnFamilies(entry.getValue()));
-    }
-    return 0;
-  }
-  
-  @Override
-  public String description() {
-    return "gets the locality groups for a given table";
-  }
-  
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options opts = new Options();
-    opts.addOption(OptUtil.tableOpt("table to fetch locality groups from"));
-    return opts;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/GetSplitsCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/GetSplitsCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/GetSplitsCommand.java
deleted file mode 100644
index 92c7c5d..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/GetSplitsCommand.java
+++ /dev/null
@@ -1,155 +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.accumulo.core.util.shell.commands;
-
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.util.Iterator;
-import java.util.Map.Entry;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.Scanner;
-import org.apache.accumulo.core.client.TableNotFoundException;
-import org.apache.accumulo.core.data.Key;
-import org.apache.accumulo.core.data.KeyExtent;
-import org.apache.accumulo.core.data.Range;
-import org.apache.accumulo.core.data.Value;
-import org.apache.accumulo.core.metadata.MetadataTable;
-import org.apache.accumulo.core.metadata.RootTable;
-import org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection;
-import org.apache.accumulo.core.security.Authorizations;
-import org.apache.accumulo.core.util.TextUtil;
-import org.apache.accumulo.core.util.format.BinaryFormatter;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.accumulo.core.util.shell.Shell.PrintFile;
-import org.apache.accumulo.core.util.shell.Shell.PrintLine;
-import org.apache.accumulo.core.util.shell.Shell.PrintShell;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-import org.apache.commons.codec.binary.Base64;
-import org.apache.hadoop.io.Text;
-
-public class GetSplitsCommand extends Command {
-  
-  private Option outputFileOpt, maxSplitsOpt, base64Opt, verboseOpt;
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws IOException, AccumuloException, AccumuloSecurityException,
-      TableNotFoundException {
-    final String tableName = OptUtil.getTableOpt(cl, shellState);
-    
-    final String outputFile = cl.getOptionValue(outputFileOpt.getOpt());
-    final String m = cl.getOptionValue(maxSplitsOpt.getOpt());
-    final int maxSplits = m == null ? 0 : Integer.parseInt(m);
-    final boolean encode = cl.hasOption(base64Opt.getOpt());
-    final boolean verbose = cl.hasOption(verboseOpt.getOpt());
-    
-    final PrintLine p = outputFile == null ? new PrintShell(shellState.getReader()) : new PrintFile(outputFile);
-    
-    try {
-      if (!verbose) {
-        for (Text row : maxSplits > 0 ? shellState.getConnector().tableOperations().listSplits(tableName, maxSplits) : shellState.getConnector()
-            .tableOperations().listSplits(tableName)) {
-          p.print(encode(encode, row));
-        }
-      } else {
-        String systemTableToCheck = MetadataTable.NAME.equals(tableName) ? RootTable.NAME : MetadataTable.NAME;
-        final Scanner scanner = shellState.getConnector().createScanner(systemTableToCheck, Authorizations.EMPTY);
-        TabletsSection.TabletColumnFamily.PREV_ROW_COLUMN.fetch(scanner);
-        final Text start = new Text(shellState.getConnector().tableOperations().tableIdMap().get(tableName));
-        final Text end = new Text(start);
-        end.append(new byte[] {'<'}, 0, 1);
-        scanner.setRange(new Range(start, end));
-        for (Iterator<Entry<Key,Value>> iterator = scanner.iterator(); iterator.hasNext();) {
-          final Entry<Key,Value> next = iterator.next();
-          if (TabletsSection.TabletColumnFamily.PREV_ROW_COLUMN.hasColumns(next.getKey())) {
-            KeyExtent extent = new KeyExtent(next.getKey().getRow(), next.getValue());
-            final String pr = encode(encode, extent.getPrevEndRow());
-            final String er = encode(encode, extent.getEndRow());
-            final String line = String.format("%-26s (%s, %s%s", obscuredTabletName(extent), pr == null ? "-inf" : pr, er == null ? "+inf" : er,
-                er == null ? ") Default Tablet " : "]");
-            p.print(line);
-          }
-        }
-      }
-      
-    } finally {
-      p.close();
-    }
-    
-    return 0;
-  }
-  
-  private static String encode(final boolean encode, final Text text) {
-    if (text == null) {
-      return null;
-    }
-    BinaryFormatter.getlength(text.getLength());
-    return encode ? new String(Base64.encodeBase64(TextUtil.getBytes(text)), StandardCharsets.UTF_8) : BinaryFormatter.appendText(new StringBuilder(), text).toString();
-  }
-  
-  private static String obscuredTabletName(final KeyExtent extent) {
-    MessageDigest digester;
-    try {
-      digester = MessageDigest.getInstance("MD5");
-    } catch (NoSuchAlgorithmException e) {
-      throw new RuntimeException(e);
-    }
-    if (extent.getEndRow() != null && extent.getEndRow().getLength() > 0) {
-      digester.update(extent.getEndRow().getBytes(), 0, extent.getEndRow().getLength());
-    }
-    return new String(Base64.encodeBase64(digester.digest()), StandardCharsets.UTF_8);
-  }
-  
-  @Override
-  public String description() {
-    return "retrieves the current split points for tablets in the current table";
-  }
-  
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options opts = new Options();
-    
-    outputFileOpt = new Option("o", "output", true, "local file to write the splits to");
-    outputFileOpt.setArgName("file");
-    
-    maxSplitsOpt = new Option("m", "max", true, "maximum number of splits to return (evenly spaced)");
-    maxSplitsOpt.setArgName("num");
-    
-    base64Opt = new Option("b64", "base64encoded", false, "encode the split points");
-    
-    verboseOpt = new Option("v", "verbose", false, "print out the tablet information with start/end rows");
-    
-    opts.addOption(outputFileOpt);
-    opts.addOption(maxSplitsOpt);
-    opts.addOption(base64Opt);
-    opts.addOption(verboseOpt);
-    opts.addOption(OptUtil.tableOpt("table to get splits for"));
-    
-    return opts;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/GrantCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/GrantCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/GrantCommand.java
deleted file mode 100644
index de719fd..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/GrantCommand.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.accumulo.core.util.shell.commands;
-
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.accumulo.core.security.NamespacePermission;
-import org.apache.accumulo.core.security.SystemPermission;
-import org.apache.accumulo.core.security.TablePermission;
-import org.apache.accumulo.core.util.BadArgumentException;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.accumulo.core.util.shell.Token;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.OptionGroup;
-import org.apache.commons.cli.Options;
-
-public class GrantCommand extends TableOperation {
-  {
-    disableUnflaggedTableOptions();
-  }
-
-  private Option systemOpt, userOpt;
-  private String user;
-  private String[] permission;
-
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    user = cl.hasOption(userOpt.getOpt()) ? cl.getOptionValue(userOpt.getOpt()) : shellState.getConnector().whoami();
-
-    permission = cl.getArgs()[0].split("\\.", 2);
-    if (cl.hasOption(systemOpt.getOpt()) && permission[0].equalsIgnoreCase("System")) {
-      try {
-        shellState.getConnector().securityOperations().grantSystemPermission(user, SystemPermission.valueOf(permission[1]));
-        Shell.log.debug("Granted " + user + " the " + permission[1] + " permission");
-      } catch (IllegalArgumentException e) {
-        throw new BadArgumentException("No such system permission", fullCommand, fullCommand.indexOf(cl.getArgs()[0]));
-      }
-    } else if (permission[0].equalsIgnoreCase("Table")) {
-      super.execute(fullCommand, cl, shellState);
-    } else if (permission[0].equalsIgnoreCase("Namespace")) {
-      if (cl.hasOption(optNamespace.getOpt())) {
-        try {
-          shellState.getConnector().securityOperations()
-              .grantNamespacePermission(user, cl.getOptionValue(optNamespace.getOpt()), NamespacePermission.valueOf(permission[1]));
-        } catch (IllegalArgumentException e) {
-          throw new BadArgumentException("No such namespace permission", fullCommand, fullCommand.indexOf(cl.getArgs()[0]));
-        }
-      } else {
-        throw new BadArgumentException("No namespace specified to apply permission to", fullCommand, fullCommand.indexOf(cl.getArgs()[0]));
-      }
-    } else {
-      throw new BadArgumentException("Unrecognized permission", fullCommand, fullCommand.indexOf(cl.getArgs()[0]));
-    }
-    return 0;
-  }
-
-  @Override
-  protected void doTableOp(final Shell shellState, final String tableName) throws Exception {
-    try {
-      shellState.getConnector().securityOperations().grantTablePermission(user, tableName, TablePermission.valueOf(permission[1]));
-      Shell.log.debug("Granted " + user + " the " + permission[1] + " permission on table " + tableName);
-    } catch (IllegalArgumentException e) {
-      throw new IllegalArgumentException("No such table permission", e);
-    }
-  }
-
-  @Override
-  public String description() {
-    return "grants system, table, or namespace permissions for a user";
-  }
-
-  @Override
-  public String usage() {
-    return getName() + " <permission>";
-  }
-
-  @Override
-  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> completionSet) {
-    final Token cmd = new Token(getName());
-    cmd.addSubcommand(new Token(TablePermission.printableValues()));
-    cmd.addSubcommand(new Token(SystemPermission.printableValues()));
-    cmd.addSubcommand(new Token(NamespacePermission.printableValues()));
-    root.addSubcommand(cmd);
-  }
-
-  @Override
-  public Options getOptions() {
-    super.getOptions();
-    final Options o = new Options();
-
-    final OptionGroup group = new OptionGroup();
-
-    systemOpt = new Option("s", "system", false, "grant a system permission");
-
-    optNamespace = new Option(Shell.namespaceOption, "namespace", true, "name of a namespace to operate on");
-    optNamespace.setArgName("namespace");
-
-    group.addOption(systemOpt);
-    group.addOption(optTableName);
-    group.addOption(optTablePattern);
-    group.addOption(optNamespace);
-
-    o.addOptionGroup(group);
-    userOpt = new Option(Shell.userOption, "user", true, "user to operate on");
-    userOpt.setArgName("username");
-    userOpt.setRequired(true);
-    o.addOption(userOpt);
-
-    return o;
-  }
-
-  @Override
-  public int numArgs() {
-    return 1;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/GrepCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/GrepCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/GrepCommand.java
deleted file mode 100644
index c2ff232..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/GrepCommand.java
+++ /dev/null
@@ -1,111 +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.accumulo.core.util.shell.commands;
-
-import java.io.IOException;
-import java.util.Collections;
-import java.util.concurrent.TimeUnit;
-
-import org.apache.accumulo.core.client.BatchScanner;
-import org.apache.accumulo.core.client.IteratorSetting;
-import org.apache.accumulo.core.iterators.user.GrepIterator;
-import org.apache.accumulo.core.security.Authorizations;
-import org.apache.accumulo.core.util.format.Formatter;
-import org.apache.accumulo.core.util.interpret.ScanInterpreter;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.PrintFile;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.MissingArgumentException;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-
-public class GrepCommand extends ScanCommand {
-  
-  private Option numThreadsOpt;
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    final PrintFile printFile = getOutputFile(cl);
-    
-    final String tableName = OptUtil.getTableOpt(cl, shellState);
-    
-    if (cl.getArgList().isEmpty()) {
-      throw new MissingArgumentException("No terms specified");
-    }
-    final Class<? extends Formatter> formatter = getFormatter(cl, tableName, shellState);
-    final ScanInterpreter interpeter = getInterpreter(cl, tableName, shellState);
-    
-    // handle first argument, if present, the authorizations list to
-    // scan with
-    int numThreads = 20;
-    if (cl.hasOption(numThreadsOpt.getOpt())) {
-      numThreads = Integer.parseInt(cl.getOptionValue(numThreadsOpt.getOpt()));
-    }
-    final Authorizations auths = getAuths(cl, shellState);
-    final BatchScanner scanner = shellState.getConnector().createBatchScanner(tableName, auths, numThreads);
-    scanner.setRanges(Collections.singletonList(getRange(cl, interpeter)));
-    
-    scanner.setTimeout(getTimeout(cl), TimeUnit.MILLISECONDS);
-    
-    for (int i = 0; i < cl.getArgs().length; i++) {
-      setUpIterator(Integer.MAX_VALUE - cl.getArgs().length + i, "grep" + i, cl.getArgs()[i], scanner, cl);
-    }
-    try {
-      // handle columns
-      fetchColumns(cl, scanner, interpeter);
-      
-      // output the records
-      printRecords(cl, shellState, scanner, formatter, printFile);
-    } finally {
-      scanner.close();
-    }
-    
-    return 0;
-  }
-  
-  protected void setUpIterator(final int prio, final String name, final String term, final BatchScanner scanner, CommandLine cl) throws IOException {
-    if (prio < 0) {
-      throw new IllegalArgumentException("Priority < 0 " + prio);
-    }
-    final IteratorSetting grep = new IteratorSetting(prio, name, GrepIterator.class);
-    GrepIterator.setTerm(grep, term);
-    scanner.addScanIterator(grep);
-  }
-  
-  @Override
-  public String description() {
-    return "searches each row, column family, column qualifier and value in a table for a substring (not a regular expression), in parallel, on the server side";
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options opts = super.getOptions();
-    numThreadsOpt = new Option("nt", "num-threads", true, "number of threads to use");
-    opts.addOption(numThreadsOpt);
-    return opts;
-  }
-  
-  @Override
-  public String usage() {
-    return getName() + " <term>{ <term>}";
-  }
-  
-  @Override
-  public int numArgs() {
-    return Shell.NO_FIXED_ARG_LENGTH_CHECK;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/HelpCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/HelpCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/HelpCommand.java
deleted file mode 100644
index 9881e00..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/HelpCommand.java
+++ /dev/null
@@ -1,129 +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.accumulo.core.util.shell.commands;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.accumulo.core.util.shell.ShellCommandException;
-import org.apache.accumulo.core.util.shell.Token;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-
-public class HelpCommand extends Command {
-  private Option disablePaginationOpt;
-  private Option noWrapOpt;
-  
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws ShellCommandException, IOException {
-    int numColumns = shellState.getReader().getTerminal().getWidth();
-    if (cl.hasOption(noWrapOpt.getOpt())) {
-      numColumns = Integer.MAX_VALUE;
-    }
-    // print help summary
-    if (cl.getArgs().length == 0) {
-      int i = 0;
-      for (String cmd : shellState.commandFactory.keySet()) {
-        i = Math.max(i, cmd.length());
-      }
-      if (numColumns < 40) {
-        throw new IllegalArgumentException("numColumns must be at least 40 (was " + numColumns + ")");
-      }
-      final ArrayList<String> output = new ArrayList<String>();
-      for (Entry<String,Command[]> cmdGroup : shellState.commandGrouping.entrySet()) {
-        output.add(cmdGroup.getKey());
-        for (Command c : cmdGroup.getValue()) {
-          String n = c.getName();
-          String s = c.description();
-          if (s == null) {
-            s = "";
-          }
-          int beginIndex = 0;
-          int endIndex = s.length();
-          while (beginIndex < endIndex && s.charAt(beginIndex) == ' ')
-            beginIndex++;
-          String dash = "-";
-          while (endIndex > beginIndex && endIndex - beginIndex + i + 5 > numColumns) {
-            endIndex = s.lastIndexOf(" ", numColumns + beginIndex - i - 5);
-            if (endIndex == -1 || endIndex < beginIndex) {
-              endIndex = numColumns + beginIndex - i - 5 - 1;
-              output.add(String.format("%-" + i + "s  %s  %s-", n, dash, s.substring(beginIndex, endIndex)));
-              dash = " ";
-              beginIndex = endIndex;
-            } else {
-              output.add(String.format("%-" + i + "s  %s  %s", n, dash, s.substring(beginIndex, endIndex)));
-              dash = " ";
-              beginIndex = endIndex + 1;
-            }
-            n = "";
-            endIndex = s.length();
-            while (beginIndex < endIndex && s.charAt(beginIndex) == ' ') {
-              beginIndex++;
-            }
-          }
-          output.add(String.format("%-" + i + "s  %s  %s", n, dash, s.substring(beginIndex, endIndex)));
-        }
-        output.add("");
-      }
-      shellState.printLines(output.iterator(), !cl.hasOption(disablePaginationOpt.getOpt()));
-    }
-    
-    // print help for every command on command line
-    for (String cmd : cl.getArgs()) {
-      final Command c = shellState.commandFactory.get(cmd);
-      if (c == null) {
-        shellState.getReader().println(String.format("Unknown command \"%s\".  Enter \"help\" for a list possible commands.", cmd));
-      } else {
-        c.printHelp(shellState, numColumns);
-      }
-    }
-    return 0;
-  }
-  
-  public String description() {
-    return "provides information about the available commands";
-  }
-  
-  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> special) {
-    registerCompletionForCommands(root, special);
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-    disablePaginationOpt = new Option("np", "no-pagination", false, "disable pagination of output");
-    o.addOption(disablePaginationOpt);
-    noWrapOpt = new Option("nw", "no-wrap", false, "disable wrapping of output");
-    o.addOption(noWrapOpt);
-    return o;
-  }
-  
-  @Override
-  public String usage() {
-    return getName() + " [ <command>{ <command>} ]";
-  }
-  
-  @Override
-  public int numArgs() {
-    return Shell.NO_FIXED_ARG_LENGTH_CHECK;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/HiddenCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/HiddenCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/HiddenCommand.java
deleted file mode 100644
index c1615ea..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/HiddenCommand.java
+++ /dev/null
@@ -1,62 +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.accumulo.core.util.shell.commands;
-
-import java.nio.charset.StandardCharsets;
-import java.security.SecureRandom;
-import java.util.Random;
-
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.accumulo.core.util.shell.ShellCommandException;
-import org.apache.accumulo.core.util.shell.ShellCommandException.ErrorCode;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.codec.binary.Base64;
-
-public class HiddenCommand extends Command {
-  private static Random rand = new SecureRandom();
-  
-  @Override
-  public String description() {
-    return "The first rule of Accumulo is: \"You don't talk about Accumulo.\"";
-  }
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    if (rand.nextInt(10) == 0) {
-      shellState.getReader().beep();
-      shellState.getReader().println();
-      shellState.getReader().println(
-          new String(Base64.decodeBase64(("ICAgICAgIC4tLS4KICAgICAgLyAvXCBcCiAgICAgKCAvLS1cICkKICAgICAuPl8gIF88LgogICAgLyB8ICd8ICcgXAog"
-              + "ICAvICB8Xy58Xy4gIFwKICAvIC98ICAgICAgfFwgXAogfCB8IHwgfFwvfCB8IHwgfAogfF98IHwgfCAgfCB8IHxffAogICAgIC8gIF9fICBcCiAgICAvICAv"
-              + "ICBcICBcCiAgIC8gIC8gICAgXCAgXF8KIHwvICAvICAgICAgXCB8IHwKIHxfXy8gICAgICAgIFx8X3wK").getBytes(StandardCharsets.UTF_8)), StandardCharsets.UTF_8));
-    } else {
-      throw new ShellCommandException(ErrorCode.UNRECOGNIZED_COMMAND, getName());
-    }
-    return 0;
-  }
-  
-  @Override
-  public int numArgs() {
-    return Shell.NO_FIXED_ARG_LENGTH_CHECK;
-  }
-  
-  @Override
-  public String getName() {
-    return "accvmvlo";
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/HistoryCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/HistoryCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/HistoryCommand.java
deleted file mode 100644
index 9531d90..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/HistoryCommand.java
+++ /dev/null
@@ -1,82 +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.accumulo.core.util.shell.commands;
-
-import java.io.IOException;
-import java.util.Iterator;
-import java.util.ListIterator;
-
-import jline.console.history.History.Entry;
-
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-import org.apache.commons.collections.iterators.AbstractIteratorDecorator;
-
-public class HistoryCommand extends Command {
-  private Option clearHist;
-  private Option disablePaginationOpt;
-  
-  @SuppressWarnings("unchecked")
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws IOException {
-    if (cl.hasOption(clearHist.getOpt())) {
-      shellState.getReader().getHistory().clear();
-    } else {
-      ListIterator<Entry> it = shellState.getReader().getHistory().entries();
-      shellState.printLines(new HistoryLineIterator(it), !cl.hasOption(disablePaginationOpt.getOpt()));
-    }
-    
-    return 0;
-  }
-  
-  /**
-   * Decorator that converts an Iterator<History.Entry> to an Iterator<String>.
-   */
-  private static class HistoryLineIterator extends AbstractIteratorDecorator {
-    public HistoryLineIterator(Iterator<Entry> iterator) {
-      super(iterator);
-    }
-    
-    @Override
-    public String next() {
-      return super.next().toString();
-    }
-  }
-  
-  @Override
-  public String description() {
-    return ("generates a list of commands previously executed");
-  }
-  
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-    clearHist = new Option("c", "clear", false, "clear history file");
-    o.addOption(clearHist);
-    disablePaginationOpt = new Option("np", "no-pagination", false, "disable pagination of output");
-    o.addOption(disablePaginationOpt);
-    return o;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ImportDirectoryCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ImportDirectoryCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ImportDirectoryCommand.java
deleted file mode 100644
index 13db3a4..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ImportDirectoryCommand.java
+++ /dev/null
@@ -1,58 +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.accumulo.core.util.shell.commands;
-
-import java.io.IOException;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.TableNotFoundException;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-
-public class ImportDirectoryCommand extends Command {
-  
-  @Override
-  public String description() {
-    return "bulk imports an entire directory of data files to the current table.  The boolean argument determines if accumulo sets the time.";
-  }
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws IOException, AccumuloException, AccumuloSecurityException,
-      TableNotFoundException {
-    shellState.checkTableState();
-    
-    String dir = cl.getArgs()[0];
-    String failureDir = cl.getArgs()[1];
-    final boolean setTime = Boolean.parseBoolean(cl.getArgs()[2]);
-
-    shellState.getConnector().tableOperations().importDirectory(shellState.getTableName(), dir, failureDir, setTime);
-    return 0;
-  }
-  
-  @Override
-  public int numArgs() {
-    return 3;
-  }
-  
-  @Override
-  public String usage() {
-    return getName() + " <directory> <failureDirectory> true|false";
-  }
-  
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ImportTableCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ImportTableCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ImportTableCommand.java
deleted file mode 100644
index 571c45b..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ImportTableCommand.java
+++ /dev/null
@@ -1,51 +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.accumulo.core.util.shell.commands;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.TableExistsException;
-import org.apache.accumulo.core.client.TableNotFoundException;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-
-public class ImportTableCommand extends Command {
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException, TableNotFoundException,
-      TableExistsException {
-    
-    shellState.getConnector().tableOperations().importTable(cl.getArgs()[0], cl.getArgs()[1]);
-    return 0;
-  }
-  
-  @Override
-  public String usage() {
-    return getName() + " <table name> <import dir>";
-  }
-  
-  @Override
-  public String description() {
-    return "imports a table";
-  }
-  
-  @Override
-  public int numArgs() {
-    return 2;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/InfoCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/InfoCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/InfoCommand.java
deleted file mode 100644
index 57de6b1..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/InfoCommand.java
+++ /dev/null
@@ -1,19 +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.accumulo.core.util.shell.commands;
-
-public class InfoCommand extends AboutCommand {}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/InsertCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/InsertCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/InsertCommand.java
deleted file mode 100644
index a97db05..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/InsertCommand.java
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.accumulo.core.util.shell.commands;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.concurrent.TimeUnit;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.BatchWriter;
-import org.apache.accumulo.core.client.BatchWriterConfig;
-import org.apache.accumulo.core.client.MutationsRejectedException;
-import org.apache.accumulo.core.client.TableNotFoundException;
-import org.apache.accumulo.core.client.security.SecurityErrorCode;
-import org.apache.accumulo.core.conf.AccumuloConfiguration;
-import org.apache.accumulo.core.data.ConstraintViolationSummary;
-import org.apache.accumulo.core.data.KeyExtent;
-import org.apache.accumulo.core.data.Mutation;
-import org.apache.accumulo.core.data.Value;
-import org.apache.accumulo.core.security.ColumnVisibility;
-import org.apache.accumulo.core.tabletserver.thrift.ConstraintViolationException;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-import org.apache.hadoop.io.Text;
-
-public class InsertCommand extends Command {
-  private Option insertOptAuths, timestampOpt;
-  private Option timeoutOption;
-  
-  protected long getTimeout(final CommandLine cl) {
-    if (cl.hasOption(timeoutOption.getLongOpt())) {
-      return AccumuloConfiguration.getTimeInMillis(cl.getOptionValue(timeoutOption.getLongOpt()));
-    }
-    
-    return Long.MAX_VALUE;
-  }
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException,
-      TableNotFoundException, IOException, ConstraintViolationException {
-    shellState.checkTableState();
-    
-    final Mutation m = new Mutation(new Text(cl.getArgs()[0].getBytes(Shell.CHARSET)));
-    final Text colf = new Text(cl.getArgs()[1].getBytes(Shell.CHARSET));
-    final Text colq = new Text(cl.getArgs()[2].getBytes(Shell.CHARSET));
-    final Value val = new Value(cl.getArgs()[3].getBytes(Shell.CHARSET));
-    
-    if (cl.hasOption(insertOptAuths.getOpt())) {
-      final ColumnVisibility le = new ColumnVisibility(cl.getOptionValue(insertOptAuths.getOpt()));
-      Shell.log.debug("Authorization label will be set to: " + le.toString());
-      
-      if (cl.hasOption(timestampOpt.getOpt()))
-        m.put(colf, colq, le, Long.parseLong(cl.getOptionValue(timestampOpt.getOpt())), val);
-      else
-        m.put(colf, colq, le, val);
-    } else if (cl.hasOption(timestampOpt.getOpt()))
-      m.put(colf, colq, Long.parseLong(cl.getOptionValue(timestampOpt.getOpt())), val);
-    else
-      m.put(colf, colq, val);
-    
-    final BatchWriter bw = shellState.getConnector().createBatchWriter(shellState.getTableName(),
-        new BatchWriterConfig().setMaxMemory(Math.max(m.estimatedMemoryUsed(), 1024)).setMaxWriteThreads(1).setTimeout(getTimeout(cl), TimeUnit.MILLISECONDS));
-    bw.addMutation(m);
-    try {
-      bw.close();
-    } catch (MutationsRejectedException e) {
-      final ArrayList<String> lines = new ArrayList<String>();
-      if (e.getAuthorizationFailuresMap().isEmpty() == false) {
-        lines.add("	Authorization Failures:");
-      }
-      for (Entry<KeyExtent,Set<SecurityErrorCode>> entry : e.getAuthorizationFailuresMap().entrySet()) {
-        lines.add("		" + entry);
-      }
-      if (e.getConstraintViolationSummaries().isEmpty() == false) {
-        lines.add("	Constraint Failures:");
-      }
-      for (ConstraintViolationSummary cvs : e.getConstraintViolationSummaries()) {
-        lines.add("		" + cvs.toString());
-      }
-      
-      if (lines.size() == 0 || e.getUnknownExceptions() > 0) {
-        // must always print something
-        lines.add(" " + e.getClass().getName() + " : " + e.getMessage());
-        if (e.getCause() != null)
-          lines.add("   Caused by : " + e.getCause().getClass().getName() + " : " + e.getCause().getMessage());
-      }
-      
-      shellState.printLines(lines.iterator(), false);
-      
-      return 1;
-    }
-    return 0;
-  }
-  
-  @Override
-  public String description() {
-    return "inserts a record";
-  }
-  
-  @Override
-  public String usage() {
-    return getName() + " <row> <colfamily> <colqualifier> <value>";
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-    insertOptAuths = new Option("l", "visibility-label", true, "formatted visibility");
-    insertOptAuths.setArgName("expression");
-    o.addOption(insertOptAuths);
-    
-    timestampOpt = new Option("ts", "timestamp", true, "timestamp to use for insert");
-    timestampOpt.setArgName("timestamp");
-    o.addOption(timestampOpt);
-    
-    timeoutOption = new Option(null, "timeout", true,
-        "time before insert should fail if no data is written. If no unit is given assumes seconds.  Units d,h,m,s,and ms are supported.  e.g. 30s or 100ms");
-    timeoutOption.setArgName("timeout");
-    o.addOption(timeoutOption);
-    
-    return o;
-  }
-  
-  @Override
-  public int numArgs() {
-    return 4;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/InterpreterCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/InterpreterCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/InterpreterCommand.java
deleted file mode 100644
index 090bd7f..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/InterpreterCommand.java
+++ /dev/null
@@ -1,40 +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.accumulo.core.util.shell.commands;
-
-import org.apache.accumulo.core.conf.Property;
-import org.apache.accumulo.core.util.interpret.ScanInterpreter;
-import org.apache.accumulo.core.util.shell.Shell;
-
-/**
- * 
- */
-public class InterpreterCommand extends ShellPluginConfigurationCommand {
-  
-  public InterpreterCommand() {
-    super("interpreter", Property.TABLE_INTERPRETER_CLASS, "i");
-  }
-  
-  @Override
-  public String description() {
-    return "specifies a scan interpreter to interpret scan range and column arguments";
-  }
-  
-  public static Class<? extends ScanInterpreter> getCurrentInterpreter(final String tableName, final Shell shellState) {
-    return ShellPluginConfigurationCommand.getPluginClass(tableName, shellState, ScanInterpreter.class, Property.TABLE_INTERPRETER_CLASS);
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ListCompactionsCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ListCompactionsCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ListCompactionsCommand.java
deleted file mode 100644
index baa59a0..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ListCompactionsCommand.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.accumulo.core.util.shell.commands;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.accumulo.core.client.admin.InstanceOperations;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-
-public class ListCompactionsCommand extends Command {
-  
-  private Option tserverOption, disablePaginationOpt;
-  
-  @Override
-  public String description() {
-    return "lists what compactions are currently running in accumulo. See the accumulo.core.client.admin.ActiveCompaciton javadoc for more information about columns.";
-  }
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    
-    List<String> tservers;
-    
-    final InstanceOperations instanceOps = shellState.getConnector().instanceOperations();
-    
-    final boolean paginate = !cl.hasOption(disablePaginationOpt.getOpt());
-    
-    if (cl.hasOption(tserverOption.getOpt())) {
-      tservers = new ArrayList<String>();
-      tservers.add(cl.getOptionValue(tserverOption.getOpt()));
-    } else {
-      tservers = instanceOps.getTabletServers();
-    }
-    
-    shellState.printLines(new ActiveCompactionIterator(tservers, instanceOps), paginate);
-    
-    return 0;
-  }
-  
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options opts = new Options();
-    
-    tserverOption = new Option("ts", "tabletServer", true, "tablet server to list compactions for");
-    tserverOption.setArgName("tablet server");
-    opts.addOption(tserverOption);
-    
-    disablePaginationOpt = new Option("np", "no-pagination", false, "disable pagination of output");
-    opts.addOption(disablePaginationOpt);
-    
-    return opts;
-  }
-  
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ListIterCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ListIterCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ListIterCommand.java
deleted file mode 100644
index 9aac389..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ListIterCommand.java
+++ /dev/null
@@ -1,140 +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.accumulo.core.util.shell.commands;
-
-import java.util.EnumMap;
-import java.util.EnumSet;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-
-import org.apache.accumulo.core.client.IteratorSetting;
-import org.apache.accumulo.core.iterators.IteratorUtil.IteratorScope;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.OptionGroup;
-import org.apache.commons.cli.Options;
-
-public class ListIterCommand extends Command {
-  private Option nameOpt, allScopesOpt;
-  private Map<IteratorScope,Option> scopeOpts;
-
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-
-    boolean tables = cl.hasOption(OptUtil.tableOpt().getOpt()) || !shellState.getTableName().isEmpty();
-    boolean namespaces = cl.hasOption(OptUtil.namespaceOpt().getOpt());
-
-    final Map<String,EnumSet<IteratorScope>> iterators;
-    if (namespaces) {
-      iterators = shellState.getConnector().namespaceOperations().listIterators(OptUtil.getNamespaceOpt(cl, shellState));
-    } else if (tables) {
-      iterators = shellState.getConnector().tableOperations().listIterators(OptUtil.getTableOpt(cl, shellState));
-    } else {
-      throw new IllegalArgumentException("No table or namespace specified");
-    }
-
-    if (cl.hasOption(nameOpt.getOpt())) {
-      final String name = cl.getOptionValue(nameOpt.getOpt());
-      if (!iterators.containsKey(name)) {
-        Shell.log.warn("no iterators found that match your criteria");
-        return 0;
-      }
-      final EnumSet<IteratorScope> scopes = iterators.get(name);
-      iterators.clear();
-      iterators.put(name, scopes);
-    }
-
-    final boolean allScopes = cl.hasOption(allScopesOpt.getOpt());
-    Set<IteratorScope> desiredScopes = new HashSet<IteratorScope>();
-    for (IteratorScope scope : IteratorScope.values()) {
-      if (allScopes || cl.hasOption(scopeOpts.get(scope).getOpt()))
-        desiredScopes.add(scope);
-    }
-    if (desiredScopes.isEmpty()) {
-      throw new IllegalArgumentException("You must select at least one scope to configure");
-    }
-    final StringBuilder sb = new StringBuilder("-\n");
-    for (Entry<String,EnumSet<IteratorScope>> entry : iterators.entrySet()) {
-      final String name = entry.getKey();
-      final EnumSet<IteratorScope> scopes = entry.getValue();
-      for (IteratorScope scope : scopes) {
-        if (desiredScopes.contains(scope)) {
-          IteratorSetting setting;
-          if (namespaces) {
-            setting = shellState.getConnector().namespaceOperations().getIteratorSetting(OptUtil.getNamespaceOpt(cl, shellState), name, scope);
-          } else if (tables) {
-            setting = shellState.getConnector().tableOperations().getIteratorSetting(OptUtil.getTableOpt(cl, shellState), name, scope);
-          } else {
-            throw new IllegalArgumentException("No table or namespace specified");
-          }
-          sb.append("-    Iterator ").append(setting.getName()).append(", ").append(scope).append(" scope options:\n");
-          sb.append("-        ").append("iteratorPriority").append(" = ").append(setting.getPriority()).append("\n");
-          sb.append("-        ").append("iteratorClassName").append(" = ").append(setting.getIteratorClass()).append("\n");
-          for (Entry<String,String> optEntry : setting.getOptions().entrySet()) {
-            sb.append("-        ").append(optEntry.getKey()).append(" = ").append(optEntry.getValue()).append("\n");
-          }
-        }
-      }
-    }
-    sb.append("-");
-    shellState.getReader().println(sb.toString());
-
-    return 0;
-  }
-
-  @Override
-  public String description() {
-    return "lists table-specific or namespace-specific iterators configured in this shell session";
-  }
-
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-
-    nameOpt = new Option("n", "name", true, "iterator to list");
-    nameOpt.setArgName("itername");
-
-    allScopesOpt = new Option("all", "all-scopes", false, "list from all scopes");
-    o.addOption(allScopesOpt);
-    
-    scopeOpts = new EnumMap<IteratorScope,Option>(IteratorScope.class);
-    scopeOpts.put(IteratorScope.minc, new Option(IteratorScope.minc.name(), "minor-compaction", false, "list iterator for minor compaction scope"));
-    scopeOpts.put(IteratorScope.majc, new Option(IteratorScope.majc.name(), "major-compaction", false, "list iterator for major compaction scope"));
-    scopeOpts.put(IteratorScope.scan, new Option(IteratorScope.scan.name(), "scan-time", false, "list iterator for scan scope"));
-
-    OptionGroup grp = new OptionGroup();
-    grp.addOption(OptUtil.tableOpt("table to list the configured iterators on"));
-    grp.addOption(OptUtil.namespaceOpt("namespace to list the configured iterators on"));
-    o.addOptionGroup(grp);
-    o.addOption(nameOpt);
-
-    for (Option opt : scopeOpts.values()) {
-      o.addOption(opt);
-    }
-
-    return o;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ListScansCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ListScansCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ListScansCommand.java
deleted file mode 100644
index e4a2692..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ListScansCommand.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.accumulo.core.util.shell.commands;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.accumulo.core.client.admin.InstanceOperations;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-
-public class ListScansCommand extends Command {
-  
-  private Option tserverOption, disablePaginationOpt;
-  
-  @Override
-  public String description() {
-    return "lists what scans are currently running in accumulo. See the accumulo.core.client.admin.ActiveScan javadoc for more information about columns.";
-  }
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    
-    List<String> tservers;
-    
-    final InstanceOperations instanceOps = shellState.getConnector().instanceOperations();
-    
-    final boolean paginate = !cl.hasOption(disablePaginationOpt.getOpt());
-    
-    if (cl.hasOption(tserverOption.getOpt())) {
-      tservers = new ArrayList<String>();
-      tservers.add(cl.getOptionValue(tserverOption.getOpt()));
-    } else {
-      tservers = instanceOps.getTabletServers();
-    }
-    
-    shellState.printLines(new ActiveScanIterator(tservers, instanceOps), paginate);
-    
-    return 0;
-  }
-  
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options opts = new Options();
-    
-    tserverOption = new Option("ts", "tabletServer", true, "tablet server to list scans for");
-    tserverOption.setArgName("tablet server");
-    opts.addOption(tserverOption);
-    
-    disablePaginationOpt = new Option("np", "no-pagination", false, "disable pagination of output");
-    opts.addOption(disablePaginationOpt);
-    
-    return opts;
-  }
-  
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ListShellIterCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ListShellIterCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ListShellIterCommand.java
deleted file mode 100644
index 7f6ad84..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ListShellIterCommand.java
+++ /dev/null
@@ -1,105 +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.accumulo.core.util.shell.commands;
-
-import java.util.List;
-import java.util.Map.Entry;
-import java.util.Set;
-
-import org.apache.accumulo.core.client.IteratorSetting;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-
-/**
- * 
- */
-public class ListShellIterCommand extends Command {
-  
-  private Option nameOpt, profileOpt;
-
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    if (shellState.iteratorProfiles.size() == 0)
-      return 0;
-    
-    final StringBuilder sb = new StringBuilder();
-
-    String profile = null;
-    if (cl.hasOption(profileOpt.getOpt()))
-      profile = cl.getOptionValue(profileOpt.getOpt());
-
-    String name = null;
-    if (cl.hasOption(nameOpt.getOpt()))
-      name = cl.getOptionValue(nameOpt.getOpt());
-
-    Set<Entry<String,List<IteratorSetting>>> es = shellState.iteratorProfiles.entrySet();
-    for (Entry<String,List<IteratorSetting>> entry : es) {
-      if (profile != null && !profile.equals(entry.getKey()))
-        continue;
-
-      sb.append("-\n");
-      sb.append("- Profile : " + entry.getKey() + "\n");
-      for (IteratorSetting setting : entry.getValue()) {
-        if (name != null && !name.equals(setting.getName()))
-          continue;
-
-        sb.append("-    Iterator ").append(setting.getName()).append(", ").append(" options:\n");
-        sb.append("-        ").append("iteratorPriority").append(" = ").append(setting.getPriority()).append("\n");
-        sb.append("-        ").append("iteratorClassName").append(" = ").append(setting.getIteratorClass()).append("\n");
-        for (Entry<String,String> optEntry : setting.getOptions().entrySet()) {
-          sb.append("-        ").append(optEntry.getKey()).append(" = ").append(optEntry.getValue()).append("\n");
-        }
-      }
-    }
-    
-    if (sb.length() > 0) {
-      sb.append("-\n");
-    }
-
-    shellState.getReader().print(sb.toString());
-
-    return 0;
-  }
-  
-  public String description() {
-    return "lists iterators profiles configured in shell";
-  }
-  
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-    
-    profileOpt = new Option("pn", "profile", true, "iterator profile name");
-    profileOpt.setArgName("profile");
-
-    nameOpt = new Option("n", "name", true, "iterator to list");
-    nameOpt.setArgName("itername");
-    
-    o.addOption(profileOpt);
-    o.addOption(nameOpt);
-
-    return o;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/MaxRowCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/MaxRowCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/MaxRowCommand.java
deleted file mode 100644
index ddb6cc1..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/MaxRowCommand.java
+++ /dev/null
@@ -1,55 +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.accumulo.core.util.shell.commands;
-
-import org.apache.accumulo.core.data.Range;
-import org.apache.accumulo.core.security.Authorizations;
-import org.apache.accumulo.core.util.interpret.ScanInterpreter;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.commons.cli.CommandLine;
-import org.apache.hadoop.io.Text;
-
-public class MaxRowCommand extends ScanCommand {
-  
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    final String tableName = OptUtil.getTableOpt(cl, shellState);
-    
-    final ScanInterpreter interpeter = getInterpreter(cl, tableName, shellState);
-    
-    final Range range = getRange(cl, interpeter);
-    final Authorizations auths = getAuths(cl, shellState);
-    final Text startRow = range.getStartKey() == null ? null : range.getStartKey().getRow();
-    final Text endRow = range.getEndKey() == null ? null : range.getEndKey().getRow();
-    
-    try {
-      final Text max = shellState.getConnector().tableOperations()
-          .getMaxRow(tableName, auths, startRow, range.isStartKeyInclusive(), endRow, range.isEndKeyInclusive());
-      if (max != null) {
-        shellState.getReader().println(max.toString());
-      }
-    } catch (Exception e) {
-      e.printStackTrace();
-    }
-    
-    return 0;
-  }
-  
-  @Override
-  public String description() {
-    return "finds the max row in a table within a given range";
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/MergeCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/MergeCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/MergeCommand.java
deleted file mode 100644
index 9774e36..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/MergeCommand.java
+++ /dev/null
@@ -1,111 +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.accumulo.core.util.shell.commands;
-
-import java.io.IOException;
-
-import org.apache.accumulo.core.conf.AccumuloConfiguration;
-import org.apache.accumulo.core.util.Merge;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-import org.apache.hadoop.io.Text;
-
-public class MergeCommand extends Command {
-  private Option verboseOpt, forceOpt, sizeOpt, allOpt;
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    boolean verbose = shellState.isVerbose();
-    boolean force = false;
-    boolean all = false;
-    long size = -1;
-    final String tableName = OptUtil.getTableOpt(cl, shellState);
-    final Text startRow = OptUtil.getStartRow(cl);
-    final Text endRow = OptUtil.getEndRow(cl);
-    if (cl.hasOption(verboseOpt.getOpt())) {
-      verbose = true;
-    }
-    if (cl.hasOption(forceOpt.getOpt())) {
-      force = true;
-    }
-    if (cl.hasOption(allOpt.getOpt())) {
-      all = true;
-    }
-    if (cl.hasOption(sizeOpt.getOpt())) {
-      size = AccumuloConfiguration.getMemoryInBytes(cl.getOptionValue(sizeOpt.getOpt()));
-    }
-    if (startRow == null && endRow == null && size < 0 && !all) {
-      shellState.getReader().flush();
-      String line = shellState.getReader().readLine("Merge the entire table { " + tableName + " } into one tablet (yes|no)? ");
-      if (line == null)
-        return 0;
-      if (!line.equalsIgnoreCase("y") && !line.equalsIgnoreCase("yes"))
-        return 0;
-    }
-    if (size < 0) {
-      shellState.getConnector().tableOperations().merge(tableName, startRow, endRow);
-    } else {
-      final boolean finalVerbose = verbose;
-      final Merge merge = new Merge() {
-        protected void message(String fmt, Object... args) {
-          if (finalVerbose) {
-            try {
-              shellState.getReader().println(String.format(fmt, args));
-            } catch (IOException ex) {
-              throw new RuntimeException(ex);
-            }
-          }
-        }
-      };
-      merge.mergomatic(shellState.getConnector(), tableName, startRow, endRow, size, force);
-    }
-    return 0;
-  }
-  
-  @Override
-  public String description() {
-    return "merges tablets in a table";
-  }
-  
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-    verboseOpt = new Option("v", "verbose", false, "verbose output during merge");
-    sizeOpt = new Option("s", "size", true, "merge tablets to the given size over the entire table");
-    forceOpt = new Option("f", "force", false, "merge small tablets to large tablets, even if it goes over the given size");
-    allOpt = new Option("", "all", false, "allow an entire table to be merged into one tablet without prompting the user for confirmation");
-    Option startRowOpt = OptUtil.startRowOpt();
-    startRowOpt.setDescription("begin row (NOT inclusive)");
-    o.addOption(startRowOpt);
-    o.addOption(OptUtil.endRowOpt());
-    o.addOption(OptUtil.tableOpt("table to be merged"));
-    o.addOption(verboseOpt);
-    o.addOption(sizeOpt);
-    o.addOption(forceOpt);
-    o.addOption(allOpt);
-    return o;
-  }
-  
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/NamespacePermissionsCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/NamespacePermissionsCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/NamespacePermissionsCommand.java
deleted file mode 100644
index 2dcba55..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/NamespacePermissionsCommand.java
+++ /dev/null
@@ -1,44 +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.accumulo.core.util.shell.commands;
-
-import java.io.IOException;
-
-import org.apache.accumulo.core.security.NamespacePermission;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-
-public class NamespacePermissionsCommand extends Command {
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws IOException {
-    for (String p : NamespacePermission.printableValues()) {
-      shellState.getReader().println(p);
-    }
-    return 0;
-  }
-
-  @Override
-  public String description() {
-    return "displays a list of valid namespace permissions";
-  }
-
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/NamespacesCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/NamespacesCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/NamespacesCommand.java
deleted file mode 100644
index 16ee645..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/NamespacesCommand.java
+++ /dev/null
@@ -1,83 +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.accumulo.core.util.shell.commands;
-
-import java.io.IOException;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.TreeMap;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.impl.Namespaces;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-
-import com.google.common.base.Function;
-import com.google.common.collect.Iterators;
-
-public class NamespacesCommand extends Command {
-  private Option disablePaginationOpt, namespaceIdOption;
-
-  private static final String DEFAULT_NAMESPACE_DISPLAY_NAME = "\"\"";
-
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException, IOException {
-    Map<String,String> namespaces = new TreeMap<String,String>(shellState.getConnector().namespaceOperations().namespaceIdMap());
-
-    Iterator<String> it = Iterators.transform(namespaces.entrySet().iterator(), new Function<Entry<String,String>,String>() {
-      @Override
-      public String apply(Map.Entry<String,String> entry) {
-        String name = entry.getKey();
-        if (Namespaces.DEFAULT_NAMESPACE.equals(name))
-          name = DEFAULT_NAMESPACE_DISPLAY_NAME;
-        String id = entry.getValue();
-        if (cl.hasOption(namespaceIdOption.getOpt()))
-          return String.format(TablesCommand.NAME_AND_ID_FORMAT, name, id);
-        else
-          return name;
-      };
-    });
-
-    shellState.printLines(it, !cl.hasOption(disablePaginationOpt.getOpt()));
-    return 0;
-  }
-
-  @Override
-  public String description() {
-    return "displays a list of all existing namespaces";
-  }
-
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-    namespaceIdOption = new Option("l", "list-ids", false, "display internal namespace ids along with the name");
-    o.addOption(namespaceIdOption);
-    disablePaginationOpt = new Option("np", "no-pagination", false, "disable pagination of output");
-    o.addOption(disablePaginationOpt);
-    return o;
-  }
-
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/NoTableCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/NoTableCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/NoTableCommand.java
deleted file mode 100644
index afdab53..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/NoTableCommand.java
+++ /dev/null
@@ -1,40 +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.accumulo.core.util.shell.commands;
-
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-
-public class NoTableCommand extends Command {
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    shellState.setTableName("");
-    
-    return 0;
-  }
-  
-  @Override
-  public String description() {
-    return "returns to a tableless shell state";
-  }
-  
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-}


[42/53] [abbrv] ACCUMULO-1879 Move shell into new package and module

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/OfflineCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/OfflineCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/OfflineCommand.java
deleted file mode 100644
index fde4514..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/OfflineCommand.java
+++ /dev/null
@@ -1,61 +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.accumulo.core.util.shell.commands;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.TableNotFoundException;
-import org.apache.accumulo.core.metadata.MetadataTable;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-
-public class OfflineCommand extends TableOperation {
-  
-  private boolean wait;
-  private Option waitOpt;
-  
-  @Override
-  public String description() {
-    return "starts the process of taking table offline";
-  }
-  
-  protected void doTableOp(final Shell shellState, final String tableName) throws AccumuloException, AccumuloSecurityException, TableNotFoundException {
-    if (tableName.equals(MetadataTable.NAME)) {
-      Shell.log.info("  You cannot take the " + MetadataTable.NAME + " offline.");
-    } else {
-      shellState.getConnector().tableOperations().offline(tableName, wait);
-      Shell.log.info("Offline of table " + tableName + (wait ? " completed." : " initiated..."));
-    }
-  }
-  
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    wait = cl.hasOption(waitOpt.getLongOpt());
-    return super.execute(fullCommand, cl, shellState);
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options opts = super.getOptions();
-    waitOpt = new Option("w", "wait", false, "wait for offline to finish");
-    opts.addOption(waitOpt); 
-    return opts;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/OnlineCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/OnlineCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/OnlineCommand.java
deleted file mode 100644
index 7b6ebe2..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/OnlineCommand.java
+++ /dev/null
@@ -1,61 +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.accumulo.core.util.shell.commands;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.TableNotFoundException;
-import org.apache.accumulo.core.metadata.RootTable;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-
-public class OnlineCommand extends TableOperation {
-  
-  private boolean wait;
-  private Option waitOpt;
-  
-  @Override
-  public String description() {
-    return "starts the process of putting a table online";
-  }
-  
-  @Override
-  protected void doTableOp(final Shell shellState, final String tableName) throws AccumuloException, AccumuloSecurityException, TableNotFoundException {
-    if (tableName.equals(RootTable.NAME)) {
-      Shell.log.info("  The " + RootTable.NAME + " is always online.");
-    } else {
-      shellState.getConnector().tableOperations().online(tableName, wait);
-      Shell.log.info("Online of table " + tableName + (wait ? " completed." : " initiated..."));
-    }
-  }
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    wait = cl.hasOption(waitOpt.getLongOpt());
-    return super.execute(fullCommand, cl, shellState);
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options opts = super.getOptions();
-    waitOpt = new Option("w", "wait", false, "wait for online to finish");
-    opts.addOption(waitOpt); 
-    return opts;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/OptUtil.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/OptUtil.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/OptUtil.java
deleted file mode 100644
index 9915bdf..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/OptUtil.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.accumulo.core.util.shell.commands;
-
-import java.io.UnsupportedEncodingException;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.NamespaceNotFoundException;
-import org.apache.accumulo.core.client.TableNotFoundException;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.OptionGroup;
-import org.apache.hadoop.io.Text;
-
-public abstract class OptUtil {
-  public static final String START_ROW_OPT = "b";
-  public static final String END_ROW_OPT = "e";
-
-  public static String getTableOpt(final CommandLine cl, final Shell shellState) throws TableNotFoundException {
-    String tableName;
-
-    if (cl.hasOption(Shell.tableOption)) {
-      tableName = cl.getOptionValue(Shell.tableOption);
-      if (!shellState.getConnector().tableOperations().exists(tableName)) {
-        throw new TableNotFoundException(tableName, tableName, "specified table that doesn't exist");
-      }
-    } else {
-      shellState.checkTableState();
-      tableName = shellState.getTableName();
-    }
-
-    return tableName;
-  }
-
-  public static String getNamespaceOpt(final CommandLine cl, final Shell shellState) throws NamespaceNotFoundException, AccumuloException,
-      AccumuloSecurityException {
-    String namespace = null;
-    if (cl.hasOption(Shell.namespaceOption)) {
-      namespace = cl.getOptionValue(Shell.namespaceOption);
-      if (!shellState.getConnector().namespaceOperations().exists(namespace)) {
-        throw new NamespaceNotFoundException(namespace, namespace, "specified namespace that doesn't exist");
-      }
-    } else {
-      throw new NamespaceNotFoundException(null, null, "no namespace specified");
-    }
-    return namespace;
-  }
-
-  public static Option tableOpt() {
-    return tableOpt("tableName");
-  }
-
-  public static Option tableOpt(final String description) {
-    final Option tableOpt = new Option(Shell.tableOption, "table", true, description);
-    tableOpt.setArgName("table");
-    tableOpt.setRequired(false);
-    return tableOpt;
-  }
-
-  public static Option namespaceOpt() {
-    return namespaceOpt("namespace");
-  }
-
-  public static Option namespaceOpt(final String description) {
-    final Option namespaceOpt = new Option(Shell.namespaceOption, "namespace", true, description);
-    namespaceOpt.setArgName("namespace");
-    namespaceOpt.setRequired(false);
-    return namespaceOpt;
-  }
-
-  public static enum AdlOpt {
-    ADD("a"), DELETE("d"), LIST("l");
-
-    public final String opt;
-
-    private AdlOpt(String opt) {
-      this.opt = opt;
-    }
-  }
-
-  public static AdlOpt getAldOpt(final CommandLine cl) {
-    if (cl.hasOption(AdlOpt.ADD.opt)) {
-      return AdlOpt.ADD;
-    } else if (cl.hasOption(AdlOpt.DELETE.opt)) {
-      return AdlOpt.DELETE;
-    } else {
-      return AdlOpt.LIST;
-    }
-  }
-
-  public static OptionGroup addListDeleteGroup(final String name) {
-    final Option addOpt = new Option(AdlOpt.ADD.opt, "add", false, "add " + name);
-    final Option deleteOpt = new Option(AdlOpt.DELETE.opt, "delete", false, "delete " + name);
-    final Option listOpt = new Option(AdlOpt.LIST.opt, "list", false, "list " + name + "(s)");
-    final OptionGroup og = new OptionGroup();
-    og.addOption(addOpt);
-    og.addOption(deleteOpt);
-    og.addOption(listOpt);
-    og.setRequired(true);
-    return og;
-  }
-
-  public static Option startRowOpt() {
-    final Option o = new Option(START_ROW_OPT, "begin-row", true, "begin row (inclusive)");
-    o.setArgName("begin-row");
-    return o;
-  }
-
-  public static Option endRowOpt() {
-    final Option o = new Option(END_ROW_OPT, "end-row", true, "end row (inclusive)");
-    o.setArgName("end-row");
-    return o;
-  }
-
-  public static Text getStartRow(final CommandLine cl) throws UnsupportedEncodingException {
-    if (cl.hasOption(START_ROW_OPT)) {
-      return new Text(cl.getOptionValue(START_ROW_OPT).getBytes(Shell.CHARSET));
-    } else {
-      return null;
-    }
-  }
-
-  public static Text getEndRow(final CommandLine cl) throws UnsupportedEncodingException {
-    if (cl.hasOption(END_ROW_OPT)) {
-      return new Text(cl.getOptionValue(END_ROW_OPT).getBytes(Shell.CHARSET));
-    } else {
-      return null;
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/PasswdCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/PasswdCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/PasswdCommand.java
deleted file mode 100644
index 86446a2..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/PasswdCommand.java
+++ /dev/null
@@ -1,96 +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.accumulo.core.util.shell.commands;
-
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.impl.thrift.SecurityErrorCode;
-import org.apache.accumulo.core.client.security.tokens.PasswordToken;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-
-public class PasswdCommand extends Command {
-  private Option userOpt;
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException, IOException {
-    final String currentUser = shellState.getConnector().whoami();
-    final String user = cl.getOptionValue(userOpt.getOpt(), currentUser);
-    
-    String password = null;
-    String passwordConfirm = null;
-    String oldPassword = null;
-    
-    oldPassword = shellState.readMaskedLine("Enter current password for '" + currentUser + "': ", '*');
-    if (oldPassword == null) {
-      shellState.getReader().println();
-      return 0;
-    } // user canceled
-    
-    if (!shellState.getConnector().securityOperations().authenticateUser(currentUser, new PasswordToken(oldPassword)))
-      throw new AccumuloSecurityException(user, SecurityErrorCode.BAD_CREDENTIALS);
-    
-    password = shellState.readMaskedLine("Enter new password for '" + user + "': ", '*');
-    if (password == null) {
-      shellState.getReader().println();
-      return 0;
-    } // user canceled
-    passwordConfirm = shellState.readMaskedLine("Please confirm new password for '" + user + "': ", '*');
-    if (passwordConfirm == null) {
-      shellState.getReader().println();
-      return 0;
-    } // user canceled
-    
-    if (!password.equals(passwordConfirm)) {
-      throw new IllegalArgumentException("Passwords do not match");
-    }
-    byte[] pass = password.getBytes(StandardCharsets.UTF_8);
-    shellState.getConnector().securityOperations().changeLocalUserPassword(user, new PasswordToken(pass));
-    // update the current credentials if the password changed was for
-    // the current user
-    if (shellState.getConnector().whoami().equals(user)) {
-      shellState.updateUser(user, new PasswordToken(pass));
-    }
-    Shell.log.debug("Changed password for user " + user);
-    return 0;
-  }
-  
-  @Override
-  public String description() {
-    return "changes a user's password";
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-    userOpt = new Option(Shell.userOption, "user", true, "user to operate on");
-    userOpt.setArgName("user");
-    o.addOption(userOpt);
-    return o;
-  }
-  
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/PingCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/PingCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/PingCommand.java
deleted file mode 100644
index d0eb615..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/PingCommand.java
+++ /dev/null
@@ -1,82 +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.accumulo.core.util.shell.commands;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.accumulo.core.client.admin.InstanceOperations;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-
-/**
- * 
- */
-public class PingCommand extends Command {
-  
-  private Option tserverOption, disablePaginationOpt;
-  
-  @Override
-  public String description() {
-    return "ping tablet servers";
-  }
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    
-    List<String> tservers;
-    
-    final InstanceOperations instanceOps = shellState.getConnector().instanceOperations();
-    
-    final boolean paginate = !cl.hasOption(disablePaginationOpt.getOpt());
-    
-    if (cl.hasOption(tserverOption.getOpt())) {
-      tservers = new ArrayList<String>();
-      tservers.add(cl.getOptionValue(tserverOption.getOpt()));
-    } else {
-      tservers = instanceOps.getTabletServers();
-    }
-    
-    shellState.printLines(new PingIterator(tservers, instanceOps), paginate);
-    
-    return 0;
-  }
-  
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options opts = new Options();
-    
-    tserverOption = new Option("ts", "tabletServer", true, "tablet server to ping");
-    tserverOption.setArgName("tablet server");
-    opts.addOption(tserverOption);
-    
-    disablePaginationOpt = new Option("np", "no-pagination", false, "disable pagination of output");
-    opts.addOption(disablePaginationOpt);
-    
-    return opts;
-  }
-  
-}
-

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/PingIterator.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/PingIterator.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/PingIterator.java
deleted file mode 100644
index 2a1020e..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/PingIterator.java
+++ /dev/null
@@ -1,58 +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.accumulo.core.util.shell.commands;
-
-import java.util.Iterator;
-import java.util.List;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.admin.InstanceOperations;
-
-class PingIterator implements Iterator<String> {
-  
-  private Iterator<String> iter;
-  private InstanceOperations instanceOps;
-
-  PingIterator(List<String> tservers, InstanceOperations instanceOps) {
-    iter = tservers.iterator();
-    this.instanceOps = instanceOps;
-  }
-  
-  @Override
-  public boolean hasNext() {
-    return iter.hasNext();
-  }
-  
-  @Override
-  public String next() {
-    String tserver = iter.next();
-    
-    try {
-      instanceOps.ping(tserver);
-    } catch (AccumuloException e) {
-      return tserver + " ERROR " + e.getMessage();
-    }
-    
-    return tserver + " OK";
-  }
-  
-  @Override
-  public void remove() {
-    throw new UnsupportedOperationException();
-  }
-  
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/QuestionCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/QuestionCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/QuestionCommand.java
deleted file mode 100644
index b12c2cb..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/QuestionCommand.java
+++ /dev/null
@@ -1,24 +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.accumulo.core.util.shell.commands;
-
-public class QuestionCommand extends HelpCommand {
-  @Override
-  public String getName() {
-    return "?";
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/QuitCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/QuitCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/QuitCommand.java
deleted file mode 100644
index 8aa95f5..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/QuitCommand.java
+++ /dev/null
@@ -1,19 +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.accumulo.core.util.shell.commands;
-
-public class QuitCommand extends ExitCommand {}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/QuotedStringTokenizer.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/QuotedStringTokenizer.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/QuotedStringTokenizer.java
deleted file mode 100644
index 76ebb8f..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/QuotedStringTokenizer.java
+++ /dev/null
@@ -1,141 +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.accumulo.core.util.shell.commands;
-
-import java.io.UnsupportedEncodingException;
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.Iterator;
-
-import org.apache.accumulo.core.util.BadArgumentException;
-import org.apache.accumulo.core.util.shell.Shell;
-
-/**
- * A basic tokenizer for generating tokens from a string. It understands quoted strings and escaped quote characters.
- * 
- * You can use the escape sequence '\' to escape single quotes, double quotes, and spaces only, in addition to the escape character itself.
- * 
- * The behavior is the same for single and double quoted strings. (i.e. '\'' is the same as "\'")
- */
-
-public class QuotedStringTokenizer implements Iterable<String> {
-  private ArrayList<String> tokens;
-  private String input;
-  
-  public QuotedStringTokenizer(final String t) throws BadArgumentException {
-    tokens = new ArrayList<String>();
-    this.input = t;
-    try {
-      createTokens();
-    } catch (UnsupportedEncodingException e) {
-      throw new IllegalArgumentException(e.getMessage());
-    }
-  }
-  
-  public String[] getTokens() {
-    return tokens.toArray(new String[tokens.size()]);
-  }
-  
-  private void createTokens() throws BadArgumentException, UnsupportedEncodingException {
-    boolean inQuote = false;
-    boolean inEscapeSequence = false;
-    String hexChars = null;
-    char inQuoteChar = '"';
-    
-    final byte[] token = new byte[input.length()];
-    int tokenLength = 0;
-    final byte[] inputBytes = input.getBytes(StandardCharsets.UTF_8);
-    for (int i = 0; i < input.length(); ++i) {
-      final char ch = input.charAt(i);
-      
-      // if I ended up in an escape sequence, check for valid escapable character, and add it as a literal
-      if (inEscapeSequence) {
-        inEscapeSequence = false;
-        if (ch == 'x') {
-          hexChars = "";
-        } else if (ch == ' ' || ch == '\'' || ch == '"' || ch == '\\') {
-          token[tokenLength++] = inputBytes[i];
-        } else {
-          throw new BadArgumentException("can only escape single quotes, double quotes, the space character, the backslash, and hex input", input, i);
-        }
-      }
-      // in a hex escape sequence
-      else if (hexChars != null) {
-        final int digit = Character.digit(ch, 16);
-        if (digit < 0) {
-          throw new BadArgumentException("expected hex character", input, i);
-        }
-        hexChars += ch;
-        if (hexChars.length() == 2) {
-          byte b;
-          try {
-            b = (byte) (0xff & Short.parseShort(hexChars, 16));
-            if (!Character.isValidCodePoint(0xff & b))
-              throw new NumberFormatException();
-          } catch (NumberFormatException e) {
-            throw new BadArgumentException("unsupported non-ascii character", input, i);
-          }
-          token[tokenLength++] = b;
-          hexChars = null;
-        }
-      }
-      // in a quote, either end the quote, start escape, or continue a token
-      else if (inQuote) {
-        if (ch == inQuoteChar) {
-          inQuote = false;
-          tokens.add(new String(token, 0, tokenLength, Shell.CHARSET));
-          tokenLength = 0;
-        } else if (ch == '\\') {
-          inEscapeSequence = true;
-        } else {
-          token[tokenLength++] = inputBytes[i];
-        }
-      }
-      // not in a quote, either enter a quote, end a token, start escape, or continue a token
-      else {
-        if (ch == '\'' || ch == '"') {
-          if (tokenLength > 0) {
-            tokens.add(new String(token, 0, tokenLength, Shell.CHARSET));
-            tokenLength = 0;
-          }
-          inQuote = true;
-          inQuoteChar = ch;
-        } else if (ch == ' ' && tokenLength > 0) {
-          tokens.add(new String(token, 0, tokenLength, Shell.CHARSET));
-          tokenLength = 0;
-        } else if (ch == '\\') {
-          inEscapeSequence = true;
-        } else if (ch != ' ') {
-          token[tokenLength++] = inputBytes[i];
-        }
-      }
-    }
-    if (inQuote) {
-      throw new BadArgumentException("missing terminating quote", input, input.length());
-    } else if (inEscapeSequence || hexChars != null) {
-      throw new BadArgumentException("escape sequence not complete", input, input.length());
-    }
-    if (tokenLength > 0) {
-      tokens.add(new String(token, 0, tokenLength, Shell.CHARSET));
-    }
-  }
-  
-  @Override
-  public Iterator<String> iterator() {
-    return tokens.iterator();
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/RenameNamespaceCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/RenameNamespaceCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/RenameNamespaceCommand.java
deleted file mode 100644
index d7ff7c3..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/RenameNamespaceCommand.java
+++ /dev/null
@@ -1,79 +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.accumulo.core.util.shell.commands;
-
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.NamespaceExistsException;
-import org.apache.accumulo.core.client.NamespaceNotFoundException;
-import org.apache.accumulo.core.client.TableExistsException;
-import org.apache.accumulo.core.client.TableNotFoundException;
-import org.apache.accumulo.core.client.impl.Namespaces;
-import org.apache.accumulo.core.client.impl.Tables;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.accumulo.core.util.shell.Token;
-import org.apache.commons.cli.CommandLine;
-
-public class RenameNamespaceCommand extends Command {
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException,
-      TableNotFoundException, TableExistsException, NamespaceNotFoundException, NamespaceExistsException {
-    String old = cl.getArgs()[0];
-    String newer = cl.getArgs()[1];
-    boolean resetContext = false;
-    String currentTableId = "";
-    if (!(shellState.getTableName() == null) && !shellState.getTableName().isEmpty()) {
-      String namespaceId = Namespaces.getNamespaceId(shellState.getInstance(), old);
-      List<String> tableIds = Namespaces.getTableIds(shellState.getInstance(), namespaceId);
-      currentTableId = Tables.getTableId(shellState.getInstance(), shellState.getTableName());
-      resetContext = tableIds.contains(currentTableId);
-    }
-
-    shellState.getConnector().namespaceOperations().rename(old, newer);
-
-    if (resetContext) {
-      shellState.setTableName(Tables.getTableName(shellState.getInstance(), currentTableId));
-    }
-
-    return 0;
-  }
-
-  @Override
-  public String usage() {
-    return getName() + " <current namespace> <new namespace>";
-  }
-
-  @Override
-  public String description() {
-    return "renames a namespace";
-  }
-
-  @Override
-  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> special) {
-    registerCompletionForNamespaces(root, special);
-  }
-
-  @Override
-  public int numArgs() {
-    return 2;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/RenameTableCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/RenameTableCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/RenameTableCommand.java
deleted file mode 100644
index 38d8158..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/RenameTableCommand.java
+++ /dev/null
@@ -1,62 +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.accumulo.core.util.shell.commands;
-
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.TableExistsException;
-import org.apache.accumulo.core.client.TableNotFoundException;
-import org.apache.accumulo.core.client.impl.Tables;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.accumulo.core.util.shell.Token;
-import org.apache.commons.cli.CommandLine;
-
-public class RenameTableCommand extends Command {
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException,
-      TableNotFoundException, TableExistsException {
-    shellState.getConnector().tableOperations().rename(cl.getArgs()[0], cl.getArgs()[1]);
-    if (shellState.getTableName().equals(Tables.qualified(cl.getArgs()[0]))) {
-      shellState.setTableName(cl.getArgs()[1]);
-    }
-    return 0;
-  }
-
-  @Override
-  public String usage() {
-    return getName() + " <current table name> <new table name>";
-  }
-
-  @Override
-  public String description() {
-    return "renames a table";
-  }
-
-  @Override
-  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> completionSet) {
-    registerCompletionForTables(root, completionSet);
-  }
-
-  @Override
-  public int numArgs() {
-    return 2;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/RevokeCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/RevokeCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/RevokeCommand.java
deleted file mode 100644
index dac864d..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/RevokeCommand.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.accumulo.core.util.shell.commands;
-
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.accumulo.core.security.NamespacePermission;
-import org.apache.accumulo.core.security.SystemPermission;
-import org.apache.accumulo.core.security.TablePermission;
-import org.apache.accumulo.core.util.BadArgumentException;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.accumulo.core.util.shell.Token;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.OptionGroup;
-import org.apache.commons.cli.Options;
-
-public class RevokeCommand extends TableOperation {
-  {
-    disableUnflaggedTableOptions();
-  }
-
-  private Option systemOpt, userOpt;
-  private String user;
-  private String[] permission;
-
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    user = cl.hasOption(userOpt.getOpt()) ? cl.getOptionValue(userOpt.getOpt()) : shellState.getConnector().whoami();
-
-    permission = cl.getArgs()[0].split("\\.", 2);
-    if (cl.hasOption(systemOpt.getOpt()) && permission[0].equalsIgnoreCase("System")) {
-      try {
-        shellState.getConnector().securityOperations().revokeSystemPermission(user, SystemPermission.valueOf(permission[1]));
-        Shell.log.debug("Revoked from " + user + " the " + permission[1] + " permission");
-      } catch (IllegalArgumentException e) {
-        throw new BadArgumentException("No such system permission", fullCommand, fullCommand.indexOf(cl.getArgs()[0]));
-      }
-    } else if (permission[0].equalsIgnoreCase("Table")) {
-      super.execute(fullCommand, cl, shellState);
-    } else if (permission[0].equalsIgnoreCase("Namespace")) {
-      if (cl.hasOption(optNamespace.getOpt())) {
-        try {
-          shellState.getConnector().securityOperations()
-              .revokeNamespacePermission(user, cl.getOptionValue(optNamespace.getOpt()), NamespacePermission.valueOf(permission[1]));
-        } catch (IllegalArgumentException e) {
-          throw new BadArgumentException("No such namespace permission", fullCommand, fullCommand.indexOf(cl.getArgs()[0]));
-        }
-      } else {
-        throw new BadArgumentException("No namespace specified to apply permission to", fullCommand, fullCommand.indexOf(cl.getArgs()[0]));
-      }
-    } else {
-      throw new BadArgumentException("Unrecognized permission", fullCommand, fullCommand.indexOf(cl.getArgs()[0]));
-    }
-    return 0;
-  }
-
-  @Override
-  protected void doTableOp(final Shell shellState, final String tableName) throws Exception {
-    try {
-      shellState.getConnector().securityOperations().revokeTablePermission(user, tableName, TablePermission.valueOf(permission[1]));
-      Shell.log.debug("Revoked from " + user + " the " + permission[1] + " permission on table " + tableName);
-    } catch (IllegalArgumentException e) {
-      throw new IllegalArgumentException("No such table permission", e);
-    }
-  }
-
-  @Override
-  public String description() {
-    return "revokes system or table permissions from a user";
-  }
-
-  @Override
-  public String usage() {
-    return getName() + " <permission>";
-  }
-
-  @Override
-  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> completionSet) {
-    final Token cmd = new Token(getName());
-    cmd.addSubcommand(new Token(TablePermission.printableValues()));
-    cmd.addSubcommand(new Token(SystemPermission.printableValues()));
-    cmd.addSubcommand(new Token(NamespacePermission.printableValues()));
-    root.addSubcommand(cmd);
-  }
-
-  @Override
-  public Options getOptions() {
-    super.getOptions();
-    final Options o = new Options();
-
-    final OptionGroup group = new OptionGroup();
-
-    systemOpt = new Option("s", "system", false, "revoke a system permission");
-
-    optNamespace = new Option(Shell.namespaceOption, "namespace", true, "name of a namespace to operate on");
-    optNamespace.setArgName("namespace");
-
-    group.addOption(systemOpt);
-    group.addOption(optTableName);
-    group.addOption(optTablePattern);
-    group.addOption(optNamespace);
-
-    o.addOptionGroup(group);
-    userOpt = new Option(Shell.userOption, "user", true, "user to operate on");
-    userOpt.setArgName("username");
-    userOpt.setRequired(true);
-    o.addOption(userOpt);
-
-    return o;
-  }
-
-  @Override
-  public int numArgs() {
-    return 1;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ScanCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ScanCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ScanCommand.java
deleted file mode 100644
index f3a0663..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ScanCommand.java
+++ /dev/null
@@ -1,334 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.accumulo.core.util.shell.commands;
-
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.util.List;
-import java.util.Map.Entry;
-import java.util.concurrent.TimeUnit;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.IteratorSetting;
-import org.apache.accumulo.core.client.Scanner;
-import org.apache.accumulo.core.client.ScannerBase;
-import org.apache.accumulo.core.conf.AccumuloConfiguration;
-import org.apache.accumulo.core.data.Key;
-import org.apache.accumulo.core.data.Range;
-import org.apache.accumulo.core.data.Value;
-import org.apache.accumulo.core.security.Authorizations;
-import org.apache.accumulo.core.util.format.BinaryFormatter;
-import org.apache.accumulo.core.util.format.Formatter;
-import org.apache.accumulo.core.util.interpret.DefaultScanInterpreter;
-import org.apache.accumulo.core.util.interpret.ScanInterpreter;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.accumulo.core.util.shell.Shell.PrintFile;
-import org.apache.accumulo.start.classloader.vfs.AccumuloVFSClassLoader;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-import org.apache.hadoop.io.Text;
-
-public class ScanCommand extends Command {
-  
-  private Option scanOptAuths, scanOptRow, scanOptColumns, disablePaginationOpt, showFewOpt, formatterOpt, interpreterOpt, formatterInterpeterOpt,
-      outputFileOpt;
-  
-  protected Option timestampOpt;
-  private Option optStartRowExclusive;
-  private Option optEndRowExclusive;
-  private Option timeoutOption;
-  private Option profileOpt;
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    final PrintFile printFile = getOutputFile(cl);
-    final String tableName = OptUtil.getTableOpt(cl, shellState);
-    
-    final Class<? extends Formatter> formatter = getFormatter(cl, tableName, shellState);
-    final ScanInterpreter interpeter = getInterpreter(cl, tableName, shellState);
-    
-    // handle first argument, if present, the authorizations list to
-    // scan with
-    final Authorizations auths = getAuths(cl, shellState);
-    final Scanner scanner = shellState.getConnector().createScanner(tableName, auths);
-    
-    // handle session-specific scan iterators
-    addScanIterators(shellState, cl, scanner, tableName);
-    
-    // handle remaining optional arguments
-    scanner.setRange(getRange(cl, interpeter));
-    
-    // handle columns
-    fetchColumns(cl, scanner, interpeter);
-    
-    // set timeout
-    scanner.setTimeout(getTimeout(cl), TimeUnit.MILLISECONDS);
-    
-    // output the records
-    if (cl.hasOption(showFewOpt.getOpt())) {
-      final String showLength = cl.getOptionValue(showFewOpt.getOpt());
-      try {
-        final int length = Integer.parseInt(showLength);
-        if (length < 1) {
-          throw new IllegalArgumentException();
-        }
-        BinaryFormatter.getlength(length);
-        printBinaryRecords(cl, shellState, scanner, printFile);
-      } catch (NumberFormatException nfe) {
-        shellState.getReader().println("Arg must be an integer.");
-      } catch (IllegalArgumentException iae) {
-        shellState.getReader().println("Arg must be greater than one.");
-      }
-      
-    } else {
-      printRecords(cl, shellState, scanner, formatter, printFile);
-    }
-    if (printFile != null) {
-      printFile.close();
-    }
-    
-    return 0;
-  }
-  
-  protected long getTimeout(final CommandLine cl) {
-    if (cl.hasOption(timeoutOption.getLongOpt())) {
-      return AccumuloConfiguration.getTimeInMillis(cl.getOptionValue(timeoutOption.getLongOpt()));
-    }
-    
-    return Long.MAX_VALUE;
-  }
-  
-  protected void addScanIterators(final Shell shellState, CommandLine cl, final Scanner scanner, final String tableName) {
-    
-    List<IteratorSetting> tableScanIterators;
-    if (cl.hasOption(profileOpt.getOpt())) {
-      String profile = cl.getOptionValue(profileOpt.getOpt());
-      tableScanIterators = shellState.iteratorProfiles.get(profile);
-      
-      if (tableScanIterators == null) {
-        throw new IllegalArgumentException("Profile " + profile + " does not exist");
-      }
-    } else {
-      tableScanIterators = shellState.scanIteratorOptions.get(tableName);
-      if (tableScanIterators == null) {
-        Shell.log.debug("Found no scan iterators to set");
-        return;
-      }
-    }
-    
-    Shell.log.debug("Found " + tableScanIterators.size() + " scan iterators to set");
-    
-    for (IteratorSetting setting : tableScanIterators) {
-      Shell.log.debug("Setting scan iterator " + setting.getName() + " at priority " + setting.getPriority() + " using class name "
-          + setting.getIteratorClass());
-      for (Entry<String,String> option : setting.getOptions().entrySet()) {
-        Shell.log.debug("Setting option for " + setting.getName() + ": " + option.getKey() + "=" + option.getValue());
-      }
-      scanner.addScanIterator(setting);
-    }
-  }
-  
-  protected void printRecords(final CommandLine cl, final Shell shellState, final Iterable<Entry<Key,Value>> scanner, final Class<? extends Formatter> formatter)
-      throws IOException {
-    printRecords(cl, shellState, scanner, formatter, null);
-  }
-  
-  protected void printRecords(final CommandLine cl, final Shell shellState, final Iterable<Entry<Key,Value>> scanner,
-      final Class<? extends Formatter> formatter, PrintFile outFile) throws IOException {
-    if (outFile == null) {
-      shellState.printRecords(scanner, cl.hasOption(timestampOpt.getOpt()), !cl.hasOption(disablePaginationOpt.getOpt()), formatter);
-    } else {
-      shellState.printRecords(scanner, cl.hasOption(timestampOpt.getOpt()), !cl.hasOption(disablePaginationOpt.getOpt()), formatter, outFile);
-    }
-  }
-  
-  protected void printBinaryRecords(final CommandLine cl, final Shell shellState, final Iterable<Entry<Key,Value>> scanner) throws IOException {
-    printBinaryRecords(cl, shellState, scanner, null);
-  }
-  
-  protected void printBinaryRecords(final CommandLine cl, final Shell shellState, final Iterable<Entry<Key,Value>> scanner, PrintFile outFile)
-      throws IOException {
-    if (outFile == null) {
-      shellState.printBinaryRecords(scanner, cl.hasOption(timestampOpt.getOpt()), !cl.hasOption(disablePaginationOpt.getOpt()));
-    } else {
-      shellState.printBinaryRecords(scanner, cl.hasOption(timestampOpt.getOpt()), !cl.hasOption(disablePaginationOpt.getOpt()), outFile);
-    }
-  }
-  
-  protected ScanInterpreter getInterpreter(final CommandLine cl, final String tableName, final Shell shellState) throws Exception {
-    
-    Class<? extends ScanInterpreter> clazz = null;
-    try {
-      if (cl.hasOption(interpreterOpt.getOpt())) {
-        clazz = AccumuloVFSClassLoader.loadClass(cl.getOptionValue(interpreterOpt.getOpt()), ScanInterpreter.class);
-      } else if (cl.hasOption(formatterInterpeterOpt.getOpt())) {
-        clazz = AccumuloVFSClassLoader.loadClass(cl.getOptionValue(formatterInterpeterOpt.getOpt()), ScanInterpreter.class);
-      }
-    } catch (ClassNotFoundException e) {
-      shellState.getReader().println("Interpreter class could not be loaded.\n" + e.getMessage());
-    }
-    
-    if (clazz == null)
-      clazz = InterpreterCommand.getCurrentInterpreter(tableName, shellState);
-    
-    if (clazz == null)
-      clazz = DefaultScanInterpreter.class;
-    
-    return clazz.newInstance();
-  }
-  
-  protected Class<? extends Formatter> getFormatter(final CommandLine cl, final String tableName, final Shell shellState) throws IOException {
-    
-    try {
-      if (cl.hasOption(formatterOpt.getOpt())) {
-        return AccumuloVFSClassLoader.loadClass(cl.getOptionValue(formatterOpt.getOpt()), Formatter.class);
-        
-      } else if (cl.hasOption(formatterInterpeterOpt.getOpt())) {
-        return AccumuloVFSClassLoader.loadClass(cl.getOptionValue(formatterInterpeterOpt.getOpt()), Formatter.class);
-      }
-    } catch (ClassNotFoundException e) {
-      shellState.getReader().println("Formatter class could not be loaded.\n" + e.getMessage());
-    }
-    
-    return shellState.getFormatter(tableName);
-  }
-  
-  protected void fetchColumns(final CommandLine cl, final ScannerBase scanner, final ScanInterpreter formatter) throws UnsupportedEncodingException {
-    if (cl.hasOption(scanOptColumns.getOpt())) {
-      for (String a : cl.getOptionValue(scanOptColumns.getOpt()).split(",")) {
-        final String sa[] = a.split(":", 2);
-        if (sa.length == 1) {
-          scanner.fetchColumnFamily(formatter.interpretColumnFamily(new Text(a.getBytes(Shell.CHARSET))));
-        } else {
-          scanner.fetchColumn(formatter.interpretColumnFamily(new Text(sa[0].getBytes(Shell.CHARSET))),
-              formatter.interpretColumnQualifier(new Text(sa[1].getBytes(Shell.CHARSET))));
-        }
-      }
-    }
-  }
-  
-  protected Range getRange(final CommandLine cl, final ScanInterpreter formatter) throws UnsupportedEncodingException {
-    if ((cl.hasOption(OptUtil.START_ROW_OPT) || cl.hasOption(OptUtil.END_ROW_OPT)) && cl.hasOption(scanOptRow.getOpt())) {
-      // did not see a way to make commons cli do this check... it has mutually exclusive options but does not support the or
-      throw new IllegalArgumentException("Options -" + scanOptRow.getOpt() + " AND (-" + OptUtil.START_ROW_OPT + " OR -" + OptUtil.END_ROW_OPT
-          + ") are mutally exclusive ");
-    }
-    
-    if (cl.hasOption(scanOptRow.getOpt())) {
-      return new Range(formatter.interpretRow(new Text(cl.getOptionValue(scanOptRow.getOpt()).getBytes(Shell.CHARSET))));
-    } else {
-      Text startRow = OptUtil.getStartRow(cl);
-      if (startRow != null)
-        startRow = formatter.interpretBeginRow(startRow);
-      Text endRow = OptUtil.getEndRow(cl);
-      if (endRow != null)
-        endRow = formatter.interpretEndRow(endRow);
-      final boolean startInclusive = !cl.hasOption(optStartRowExclusive.getOpt());
-      final boolean endInclusive = !cl.hasOption(optEndRowExclusive.getOpt());
-      return new Range(startRow, startInclusive, endRow, endInclusive);
-    }
-  }
-  
-  protected Authorizations getAuths(final CommandLine cl, final Shell shellState) throws AccumuloSecurityException, AccumuloException {
-    final String user = shellState.getConnector().whoami();
-    Authorizations auths = shellState.getConnector().securityOperations().getUserAuthorizations(user);
-    if (cl.hasOption(scanOptAuths.getOpt())) {
-      auths = ScanCommand.parseAuthorizations(cl.getOptionValue(scanOptAuths.getOpt()));
-    }
-    return auths;
-  }
-  
-  static Authorizations parseAuthorizations(final String field) {
-    if (field == null || field.isEmpty()) {
-      return Authorizations.EMPTY;
-    }
-    return new Authorizations(field.split(","));
-  }
-  
-  @Override
-  public String description() {
-    return "scans the table, and displays the resulting records";
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-    
-    scanOptAuths = new Option("s", "scan-authorizations", true, "scan authorizations (all user auths are used if this argument is not specified)");
-    optStartRowExclusive = new Option("be", "begin-exclusive", false, "make start row exclusive (by default it's inclusive)");
-    optStartRowExclusive.setArgName("begin-exclusive");
-    optEndRowExclusive = new Option("ee", "end-exclusive", false, "make end row exclusive (by default it's inclusive)");
-    optEndRowExclusive.setArgName("end-exclusive");
-    scanOptRow = new Option("r", "row", true, "row to scan");
-    scanOptColumns = new Option("c", "columns", true, "comma-separated columns");
-    timestampOpt = new Option("st", "show-timestamps", false, "display timestamps");
-    disablePaginationOpt = new Option("np", "no-pagination", false, "disable pagination of output");
-    showFewOpt = new Option("f", "show few", true, "show only a specified number of characters");
-    formatterOpt = new Option("fm", "formatter", true, "fully qualified name of the formatter class to use");
-    interpreterOpt = new Option("i", "interpreter", true, "fully qualified name of the interpreter class to use");
-    formatterInterpeterOpt = new Option("fi", "fmt-interpreter", true, "fully qualified name of a class that is a formatter and interpreter");
-    timeoutOption = new Option(null, "timeout", true,
-        "time before scan should fail if no data is returned. If no unit is given assumes seconds.  Units d,h,m,s,and ms are supported.  e.g. 30s or 100ms");
-    outputFileOpt = new Option("o", "output", true, "local file to write the scan output to");
-    
-    scanOptAuths.setArgName("comma-separated-authorizations");
-    scanOptRow.setArgName("row");
-    scanOptColumns.setArgName("<columnfamily>[:<columnqualifier>]{,<columnfamily>[:<columnqualifier>]}");
-    showFewOpt.setRequired(false);
-    showFewOpt.setArgName("int");
-    formatterOpt.setArgName("className");
-    timeoutOption.setArgName("timeout");
-    outputFileOpt.setArgName("file");
-    
-    profileOpt = new Option("pn", "profile", true, "iterator profile name");
-    profileOpt.setArgName("profile");
-    
-    o.addOption(scanOptAuths);
-    o.addOption(scanOptRow);
-    o.addOption(OptUtil.startRowOpt());
-    o.addOption(OptUtil.endRowOpt());
-    o.addOption(optStartRowExclusive);
-    o.addOption(optEndRowExclusive);
-    o.addOption(scanOptColumns);
-    o.addOption(timestampOpt);
-    o.addOption(disablePaginationOpt);
-    o.addOption(OptUtil.tableOpt("table to be scanned"));
-    o.addOption(showFewOpt);
-    o.addOption(formatterOpt);
-    o.addOption(interpreterOpt);
-    o.addOption(formatterInterpeterOpt);
-    o.addOption(timeoutOption);
-    o.addOption(outputFileOpt);
-    o.addOption(profileOpt);
-    
-    return o;
-  }
-  
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-  
-  protected PrintFile getOutputFile(final CommandLine cl) throws FileNotFoundException {
-    final String outputFile = cl.getOptionValue(outputFileOpt.getOpt());
-    return (outputFile == null ? null : new PrintFile(outputFile));
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ScriptCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ScriptCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ScriptCommand.java
deleted file mode 100644
index 5a0eee0..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ScriptCommand.java
+++ /dev/null
@@ -1,290 +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.accumulo.core.util.shell.commands;
-
-import java.io.File;
-import java.io.FileReader;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.Reader;
-import java.io.Writer;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Set;
-import java.util.TreeSet;
-
-import javax.script.Bindings;
-import javax.script.Compilable;
-import javax.script.CompiledScript;
-import javax.script.Invocable;
-import javax.script.ScriptContext;
-import javax.script.ScriptEngine;
-import javax.script.ScriptEngineFactory;
-import javax.script.ScriptEngineManager;
-import javax.script.ScriptException;
-import javax.script.SimpleScriptContext;
-
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.OptionGroup;
-import org.apache.commons.cli.Options;
-
-public class ScriptCommand extends Command {
-  
-  // Command to allow user to run scripts, see JSR-223
-  // http://www.oracle.com/technetwork/articles/javase/scripting-140262.html
-  
-  protected Option list, engine, script, file, args, out, function, object;
-  private static final String DEFAULT_ENGINE = "rhino";
-  
-  public int execute(String fullCommand, CommandLine cl, Shell shellState) throws Exception {
-
-    boolean invoke = false;
-    ScriptEngineManager mgr = new ScriptEngineManager();
-    
-    if (cl.hasOption(list.getOpt())) {
-      listJSREngineInfo(mgr, shellState);
-    } else if (cl.hasOption(file.getOpt()) || cl.hasOption(script.getOpt())) {
-      String engineName = DEFAULT_ENGINE;
-      if (cl.hasOption(engine.getOpt())) {
-        engineName = cl.getOptionValue(engine.getOpt());
-      }
-      ScriptEngine engine = mgr.getEngineByName(engineName);
-      if (null == engine) {
-        shellState.printException(new Exception(engineName + " not found"));
-        return 1;
-      }
-      
-      if (cl.hasOption(object.getOpt()) || cl.hasOption(function.getOpt())) {
-        if (!(engine instanceof Invocable)) {
-          shellState.printException(new Exception(engineName + " does not support invoking functions or methods"));
-          return 1;
-        }
-        invoke = true;
-      }
-      
-      ScriptContext ctx = new SimpleScriptContext();
-      
-      // Put the following objects into the context so that they
-      // are available to the scripts
-      // TODO: What else should go in here?
-      Bindings b = engine.getBindings(ScriptContext.ENGINE_SCOPE);
-      b.put("connection", shellState.getConnector());
-      
-      List<Object> argValues = new ArrayList<Object>();
-      if (cl.hasOption(args.getOpt())) {
-        String[] argList = cl.getOptionValue(args.getOpt()).split(",");
-        for (String arg : argList) {
-          String[] parts = arg.split("=");
-          if (parts.length == 0) {
-            continue;
-          } else if (parts.length == 1) {
-            b.put(parts[0], null);
-            argValues.add(null);
-          } else if (parts.length == 2) {
-            b.put(parts[0], parts[1]);
-            argValues.add(parts[1]);
-          }
-        }
-      }
-      ctx.setBindings(b, ScriptContext.ENGINE_SCOPE);
-      Object[] argArray = argValues.toArray(new Object[argValues.size()]);
-      
-      Writer writer = null;
-      if (cl.hasOption(out.getOpt())) {
-        File f = new File(cl.getOptionValue(out.getOpt()));
-        writer = new FileWriter(f);
-        ctx.setWriter(writer);
-      }
-      
-      if (cl.hasOption(file.getOpt())) {
-        File f = new File(cl.getOptionValue(file.getOpt()));
-        if (!f.exists()) {
-          if (null != writer) {
-            writer.close();
-          }
-          shellState.printException(new Exception(f.getAbsolutePath() + " not found"));
-          return 1;
-        }
-        Reader reader = new FileReader(f);
-        try {
-          engine.eval(reader, ctx);
-          if (invoke) {
-            this.invokeFunctionOrMethod(shellState, engine, cl, argArray);
-          }
-        } catch (ScriptException ex) {
-          shellState.printException(ex);
-          return 1;
-        } finally {
-          reader.close();
-          if (null != writer) {
-            writer.close();
-          }
-        }
-      } else if (cl.hasOption(script.getOpt())) {
-        String inlineScript = cl.getOptionValue(script.getOpt());
-        try {
-          if (engine instanceof Compilable) {
-            Compilable compiledEng = (Compilable) engine;
-            CompiledScript script = compiledEng.compile(inlineScript);
-            script.eval(ctx);
-            if (invoke) {
-              this.invokeFunctionOrMethod(shellState, engine, cl, argArray);
-            }
-          } else {
-            engine.eval(inlineScript, ctx);
-            if (invoke) {
-              this.invokeFunctionOrMethod(shellState, engine, cl, argArray);
-            }
-          }
-        } catch (ScriptException ex) {
-          shellState.printException(ex);
-          return 1;
-        } finally {
-          if (null != writer) {
-            writer.close();
-          }
-        }
-      }
-      if (null != writer) {
-        writer.close();
-      }
-      
-    } else {
-      printHelp(shellState);
-    }
-    return 0;
-  }
-  
-  public String description() {
-    return "execute JSR-223 scripts";
-  }
-  
-  public int numArgs() {
-    return 0;
-  }
-  
-  @Override
-  public String getName() {
-    return "script";
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-    
-    engine = new Option("e", "engine", false, "engine name, defaults to JDK default (Rhino)");
-    engine.setArgName("engineName");
-    engine.setArgs(1);
-    engine.setRequired(false);
-    o.addOption(engine);
-    
-    OptionGroup inputGroup = new OptionGroup();
-    list = new Option("l", "list", false, "list available script engines");
-    inputGroup.addOption(list);
-
-    script = new Option("s", "script", true, "use inline script");
-    script.setArgName("script text");
-    script.setArgs(1);
-    script.setRequired(false);
-    inputGroup.addOption(script);
-    
-    file = new Option("f", "file", true, "use script file");
-    file.setArgName("fileName");
-    file.setArgs(1);
-    file.setRequired(false);
-    
-    inputGroup.addOption(file);
-    inputGroup.setRequired(true);
-    o.addOptionGroup(inputGroup);
-    
-    OptionGroup invokeGroup = new OptionGroup();
-    object = new Option("obj", "object", true, "name of object");
-    object.setArgs(1);
-    object.setArgName("objectName:methodName");
-    object.setRequired(false);
-    invokeGroup.addOption(object);
-    
-    function = new Option("fx", "function", true, "invoke a script function");
-    function.setArgName("functionName");
-    function.setArgs(1);
-    function.setRequired(false);
-    invokeGroup.addOption(function);
-    invokeGroup.setRequired(false);
-    o.addOptionGroup(invokeGroup);
-    
-    args = new Option("a", "args", true, "comma separated list of key=value arguments");
-    args.setArgName("property1=value1,propert2=value2,...");
-    args.setArgs(Option.UNLIMITED_VALUES);
-    args.setRequired(false);
-    o.addOption(args);
-    
-    out = new Option("o", "output", true, "output file");
-    out.setArgName("fileName");
-    out.setArgs(1);
-    out.setRequired(false);
-    o.addOption(out);
-    
-    return o;
-  }
-  
-  private void listJSREngineInfo(ScriptEngineManager mgr, Shell shellState) throws IOException {
-    List<ScriptEngineFactory> factories = mgr.getEngineFactories();
-    Set<String> lines = new TreeSet<String>();
-    for (ScriptEngineFactory factory : factories) {
-      lines.add("ScriptEngineFactory Info");
-      String engName = factory.getEngineName();
-      String engVersion = factory.getEngineVersion();
-      String langName = factory.getLanguageName();
-      String langVersion = factory.getLanguageVersion();
-      lines.add("\tScript Engine: " + engName + " (" + engVersion + ")");
-      List<String> engNames = factory.getNames();
-      for (String name : engNames) {
-        lines.add("\tEngine Alias: " + name);
-      }
-      lines.add("\tLanguage: " + langName + " (" + langVersion + ")");
-    }
-    shellState.printLines(lines.iterator(), true);
-    
-  }
-  
-  private void invokeFunctionOrMethod(Shell shellState, ScriptEngine engine, CommandLine cl, Object[] args) {
-    try {
-      Invocable inv = (Invocable) engine;
-      if (cl.hasOption(function.getOpt())) {
-        inv.invokeFunction(cl.getOptionValue(function.getOpt()), args);
-      } else if (cl.hasOption(object.getOpt())) {
-        String objectMethod = cl.getOptionValue(object.getOpt());
-        String[] parts = objectMethod.split(":");
-        if (!(parts.length == 2)) {
-          shellState.printException(new Exception("Object and Method must be supplied"));
-          return;
-        }
-        String objectName = parts[0];
-        String methodName = parts[1];
-        Object obj = engine.get(objectName);
-        inv.invokeMethod(obj, methodName, args);
-        
-      }
-    } catch (Exception e) {
-      shellState.printException(e);
-    }
-  }
-  
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SetAuthsCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SetAuthsCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SetAuthsCommand.java
deleted file mode 100644
index 256720c..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SetAuthsCommand.java
+++ /dev/null
@@ -1,77 +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.accumulo.core.util.shell.commands;
-
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.accumulo.core.util.shell.Token;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.OptionGroup;
-import org.apache.commons.cli.Options;
-
-public class SetAuthsCommand extends Command {
-  private Option userOpt;
-  private Option scanOptAuths;
-  private Option clearOptAuths;
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException {
-    final String user = cl.getOptionValue(userOpt.getOpt(), shellState.getConnector().whoami());
-    final String scanOpts = cl.hasOption(clearOptAuths.getOpt()) ? null : cl.getOptionValue(scanOptAuths.getOpt());
-    shellState.getConnector().securityOperations().changeUserAuthorizations(user, ScanCommand.parseAuthorizations(scanOpts));
-    Shell.log.debug("Changed record-level authorizations for user " + user);
-    return 0;
-  }
-  
-  @Override
-  public String description() {
-    return "sets the maximum scan authorizations for a user";
-  }
-  
-  @Override
-  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> completionSet) {
-    registerCompletionForUsers(root, completionSet);
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-    final OptionGroup setOrClear = new OptionGroup();
-    scanOptAuths = new Option("s", "scan-authorizations", true, "scan authorizations to set");
-    scanOptAuths.setArgName("comma-separated-authorizations");
-    setOrClear.addOption(scanOptAuths);
-    clearOptAuths = new Option("c", "clear-authorizations", false, "clear the scan authorizations");
-    setOrClear.addOption(clearOptAuths);
-    setOrClear.setRequired(true);
-    o.addOptionGroup(setOrClear);
-    userOpt = new Option(Shell.userOption, "user", true, "user to operate on");
-    userOpt.setArgName("user");
-    o.addOption(userOpt);
-    return o;
-  }
-  
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SetGroupsCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SetGroupsCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SetGroupsCommand.java
deleted file mode 100644
index 157dbd2..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SetGroupsCommand.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.accumulo.core.util.shell.commands;
-
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Set;
-
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Options;
-import org.apache.hadoop.io.Text;
-
-public class SetGroupsCommand extends Command {
-  @Override
-  public String description() {
-    return "sets the locality groups for a given table (for binary or commas, use Java API)";
-  }
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    final String tableName = OptUtil.getTableOpt(cl, shellState);
-    
-    final HashMap<String,Set<Text>> groups = new HashMap<String,Set<Text>>();
-    
-    for (String arg : cl.getArgs()) {
-      final String sa[] = arg.split("=", 2);
-      if (sa.length < 2) {
-        throw new IllegalArgumentException("Missing '='");
-      }
-      final String group = sa[0];
-      final HashSet<Text> colFams = new HashSet<Text>();
-      
-      for (String family : sa[1].split(",")) {
-        colFams.add(new Text(family.getBytes(Shell.CHARSET)));
-      }
-      
-      groups.put(group, colFams);
-    }
-    
-    shellState.getConnector().tableOperations().setLocalityGroups(tableName, groups);
-    
-    return 0;
-  }
-  
-  @Override
-  public int numArgs() {
-    return Shell.NO_FIXED_ARG_LENGTH_CHECK;
-  }
-  
-  @Override
-  public String usage() {
-    return getName() + " <group>=<col fam>{,<col fam>}{ <group>=<col fam>{,<col fam>}}";
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options opts = new Options();
-    opts.addOption(OptUtil.tableOpt("table to fetch locality groups for"));
-    return opts;
-  }
-  
-}


[36/53] [abbrv] ACCUMULO-1879 Move shell into new package and module

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/ImportDirectoryCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/ImportDirectoryCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/ImportDirectoryCommand.java
new file mode 100644
index 0000000..56c27c2
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/ImportDirectoryCommand.java
@@ -0,0 +1,58 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.io.IOException;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+
+public class ImportDirectoryCommand extends Command {
+  
+  @Override
+  public String description() {
+    return "bulk imports an entire directory of data files to the current table.  The boolean argument determines if accumulo sets the time.";
+  }
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws IOException, AccumuloException, AccumuloSecurityException,
+      TableNotFoundException {
+    shellState.checkTableState();
+    
+    String dir = cl.getArgs()[0];
+    String failureDir = cl.getArgs()[1];
+    final boolean setTime = Boolean.parseBoolean(cl.getArgs()[2]);
+
+    shellState.getConnector().tableOperations().importDirectory(shellState.getTableName(), dir, failureDir, setTime);
+    return 0;
+  }
+  
+  @Override
+  public int numArgs() {
+    return 3;
+  }
+  
+  @Override
+  public String usage() {
+    return getName() + " <directory> <failureDirectory> true|false";
+  }
+  
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/ImportTableCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/ImportTableCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/ImportTableCommand.java
new file mode 100644
index 0000000..46c941f
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/ImportTableCommand.java
@@ -0,0 +1,51 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.TableExistsException;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+
+public class ImportTableCommand extends Command {
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException, TableNotFoundException,
+      TableExistsException {
+    
+    shellState.getConnector().tableOperations().importTable(cl.getArgs()[0], cl.getArgs()[1]);
+    return 0;
+  }
+  
+  @Override
+  public String usage() {
+    return getName() + " <table name> <import dir>";
+  }
+  
+  @Override
+  public String description() {
+    return "imports a table";
+  }
+  
+  @Override
+  public int numArgs() {
+    return 2;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/InfoCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/InfoCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/InfoCommand.java
new file mode 100644
index 0000000..df5cfbb
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/InfoCommand.java
@@ -0,0 +1,19 @@
+/*
+ * 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.accumulo.shell.commands;
+
+public class InfoCommand extends AboutCommand {}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/InsertCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/InsertCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/InsertCommand.java
new file mode 100644
index 0000000..19ae5b8
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/InsertCommand.java
@@ -0,0 +1,148 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.BatchWriter;
+import org.apache.accumulo.core.client.BatchWriterConfig;
+import org.apache.accumulo.core.client.MutationsRejectedException;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.core.client.security.SecurityErrorCode;
+import org.apache.accumulo.core.conf.AccumuloConfiguration;
+import org.apache.accumulo.core.data.ConstraintViolationSummary;
+import org.apache.accumulo.core.data.KeyExtent;
+import org.apache.accumulo.core.data.Mutation;
+import org.apache.accumulo.core.data.Value;
+import org.apache.accumulo.core.security.ColumnVisibility;
+import org.apache.accumulo.core.tabletserver.thrift.ConstraintViolationException;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+import org.apache.hadoop.io.Text;
+
+public class InsertCommand extends Command {
+  private Option insertOptAuths, timestampOpt;
+  private Option timeoutOption;
+  
+  protected long getTimeout(final CommandLine cl) {
+    if (cl.hasOption(timeoutOption.getLongOpt())) {
+      return AccumuloConfiguration.getTimeInMillis(cl.getOptionValue(timeoutOption.getLongOpt()));
+    }
+    
+    return Long.MAX_VALUE;
+  }
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException,
+      TableNotFoundException, IOException, ConstraintViolationException {
+    shellState.checkTableState();
+    
+    final Mutation m = new Mutation(new Text(cl.getArgs()[0].getBytes(Shell.CHARSET)));
+    final Text colf = new Text(cl.getArgs()[1].getBytes(Shell.CHARSET));
+    final Text colq = new Text(cl.getArgs()[2].getBytes(Shell.CHARSET));
+    final Value val = new Value(cl.getArgs()[3].getBytes(Shell.CHARSET));
+    
+    if (cl.hasOption(insertOptAuths.getOpt())) {
+      final ColumnVisibility le = new ColumnVisibility(cl.getOptionValue(insertOptAuths.getOpt()));
+      Shell.log.debug("Authorization label will be set to: " + le.toString());
+      
+      if (cl.hasOption(timestampOpt.getOpt()))
+        m.put(colf, colq, le, Long.parseLong(cl.getOptionValue(timestampOpt.getOpt())), val);
+      else
+        m.put(colf, colq, le, val);
+    } else if (cl.hasOption(timestampOpt.getOpt()))
+      m.put(colf, colq, Long.parseLong(cl.getOptionValue(timestampOpt.getOpt())), val);
+    else
+      m.put(colf, colq, val);
+    
+    final BatchWriter bw = shellState.getConnector().createBatchWriter(shellState.getTableName(),
+        new BatchWriterConfig().setMaxMemory(Math.max(m.estimatedMemoryUsed(), 1024)).setMaxWriteThreads(1).setTimeout(getTimeout(cl), TimeUnit.MILLISECONDS));
+    bw.addMutation(m);
+    try {
+      bw.close();
+    } catch (MutationsRejectedException e) {
+      final ArrayList<String> lines = new ArrayList<String>();
+      if (e.getAuthorizationFailuresMap().isEmpty() == false) {
+        lines.add("	Authorization Failures:");
+      }
+      for (Entry<KeyExtent,Set<SecurityErrorCode>> entry : e.getAuthorizationFailuresMap().entrySet()) {
+        lines.add("		" + entry);
+      }
+      if (e.getConstraintViolationSummaries().isEmpty() == false) {
+        lines.add("	Constraint Failures:");
+      }
+      for (ConstraintViolationSummary cvs : e.getConstraintViolationSummaries()) {
+        lines.add("		" + cvs.toString());
+      }
+      
+      if (lines.size() == 0 || e.getUnknownExceptions() > 0) {
+        // must always print something
+        lines.add(" " + e.getClass().getName() + " : " + e.getMessage());
+        if (e.getCause() != null)
+          lines.add("   Caused by : " + e.getCause().getClass().getName() + " : " + e.getCause().getMessage());
+      }
+      
+      shellState.printLines(lines.iterator(), false);
+      
+      return 1;
+    }
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "inserts a record";
+  }
+  
+  @Override
+  public String usage() {
+    return getName() + " <row> <colfamily> <colqualifier> <value>";
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+    insertOptAuths = new Option("l", "visibility-label", true, "formatted visibility");
+    insertOptAuths.setArgName("expression");
+    o.addOption(insertOptAuths);
+    
+    timestampOpt = new Option("ts", "timestamp", true, "timestamp to use for insert");
+    timestampOpt.setArgName("timestamp");
+    o.addOption(timestampOpt);
+    
+    timeoutOption = new Option(null, "timeout", true,
+        "time before insert should fail if no data is written. If no unit is given assumes seconds.  Units d,h,m,s,and ms are supported.  e.g. 30s or 100ms");
+    timeoutOption.setArgName("timeout");
+    o.addOption(timeoutOption);
+    
+    return o;
+  }
+  
+  @Override
+  public int numArgs() {
+    return 4;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/InterpreterCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/InterpreterCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/InterpreterCommand.java
new file mode 100644
index 0000000..9d79601
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/InterpreterCommand.java
@@ -0,0 +1,40 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import org.apache.accumulo.core.conf.Property;
+import org.apache.accumulo.core.util.interpret.ScanInterpreter;
+import org.apache.accumulo.shell.Shell;
+
+/**
+ * 
+ */
+public class InterpreterCommand extends ShellPluginConfigurationCommand {
+  
+  public InterpreterCommand() {
+    super("interpreter", Property.TABLE_INTERPRETER_CLASS, "i");
+  }
+  
+  @Override
+  public String description() {
+    return "specifies a scan interpreter to interpret scan range and column arguments";
+  }
+  
+  public static Class<? extends ScanInterpreter> getCurrentInterpreter(final String tableName, final Shell shellState) {
+    return ShellPluginConfigurationCommand.getPluginClass(tableName, shellState, ScanInterpreter.class, Property.TABLE_INTERPRETER_CLASS);
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/ListCompactionsCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/ListCompactionsCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/ListCompactionsCommand.java
new file mode 100644
index 0000000..809ef8c
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/ListCompactionsCommand.java
@@ -0,0 +1,78 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.accumulo.core.client.admin.InstanceOperations;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+
+public class ListCompactionsCommand extends Command {
+  
+  private Option tserverOption, disablePaginationOpt;
+  
+  @Override
+  public String description() {
+    return "lists what compactions are currently running in accumulo. See the accumulo.core.client.admin.ActiveCompaciton javadoc for more information about columns.";
+  }
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    
+    List<String> tservers;
+    
+    final InstanceOperations instanceOps = shellState.getConnector().instanceOperations();
+    
+    final boolean paginate = !cl.hasOption(disablePaginationOpt.getOpt());
+    
+    if (cl.hasOption(tserverOption.getOpt())) {
+      tservers = new ArrayList<String>();
+      tservers.add(cl.getOptionValue(tserverOption.getOpt()));
+    } else {
+      tservers = instanceOps.getTabletServers();
+    }
+    
+    shellState.printLines(new ActiveCompactionIterator(tservers, instanceOps), paginate);
+    
+    return 0;
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options opts = new Options();
+    
+    tserverOption = new Option("ts", "tabletServer", true, "tablet server to list compactions for");
+    tserverOption.setArgName("tablet server");
+    opts.addOption(tserverOption);
+    
+    disablePaginationOpt = new Option("np", "no-pagination", false, "disable pagination of output");
+    opts.addOption(disablePaginationOpt);
+    
+    return opts;
+  }
+  
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/ListIterCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/ListIterCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/ListIterCommand.java
new file mode 100644
index 0000000..fcebd1f
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/ListIterCommand.java
@@ -0,0 +1,140 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.util.EnumMap;
+import java.util.EnumSet;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import org.apache.accumulo.core.client.IteratorSetting;
+import org.apache.accumulo.core.iterators.IteratorUtil.IteratorScope;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.OptionGroup;
+import org.apache.commons.cli.Options;
+
+public class ListIterCommand extends Command {
+  private Option nameOpt, allScopesOpt;
+  private Map<IteratorScope,Option> scopeOpts;
+
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+
+    boolean tables = cl.hasOption(OptUtil.tableOpt().getOpt()) || !shellState.getTableName().isEmpty();
+    boolean namespaces = cl.hasOption(OptUtil.namespaceOpt().getOpt());
+
+    final Map<String,EnumSet<IteratorScope>> iterators;
+    if (namespaces) {
+      iterators = shellState.getConnector().namespaceOperations().listIterators(OptUtil.getNamespaceOpt(cl, shellState));
+    } else if (tables) {
+      iterators = shellState.getConnector().tableOperations().listIterators(OptUtil.getTableOpt(cl, shellState));
+    } else {
+      throw new IllegalArgumentException("No table or namespace specified");
+    }
+
+    if (cl.hasOption(nameOpt.getOpt())) {
+      final String name = cl.getOptionValue(nameOpt.getOpt());
+      if (!iterators.containsKey(name)) {
+        Shell.log.warn("no iterators found that match your criteria");
+        return 0;
+      }
+      final EnumSet<IteratorScope> scopes = iterators.get(name);
+      iterators.clear();
+      iterators.put(name, scopes);
+    }
+
+    final boolean allScopes = cl.hasOption(allScopesOpt.getOpt());
+    Set<IteratorScope> desiredScopes = new HashSet<IteratorScope>();
+    for (IteratorScope scope : IteratorScope.values()) {
+      if (allScopes || cl.hasOption(scopeOpts.get(scope).getOpt()))
+        desiredScopes.add(scope);
+    }
+    if (desiredScopes.isEmpty()) {
+      throw new IllegalArgumentException("You must select at least one scope to configure");
+    }
+    final StringBuilder sb = new StringBuilder("-\n");
+    for (Entry<String,EnumSet<IteratorScope>> entry : iterators.entrySet()) {
+      final String name = entry.getKey();
+      final EnumSet<IteratorScope> scopes = entry.getValue();
+      for (IteratorScope scope : scopes) {
+        if (desiredScopes.contains(scope)) {
+          IteratorSetting setting;
+          if (namespaces) {
+            setting = shellState.getConnector().namespaceOperations().getIteratorSetting(OptUtil.getNamespaceOpt(cl, shellState), name, scope);
+          } else if (tables) {
+            setting = shellState.getConnector().tableOperations().getIteratorSetting(OptUtil.getTableOpt(cl, shellState), name, scope);
+          } else {
+            throw new IllegalArgumentException("No table or namespace specified");
+          }
+          sb.append("-    Iterator ").append(setting.getName()).append(", ").append(scope).append(" scope options:\n");
+          sb.append("-        ").append("iteratorPriority").append(" = ").append(setting.getPriority()).append("\n");
+          sb.append("-        ").append("iteratorClassName").append(" = ").append(setting.getIteratorClass()).append("\n");
+          for (Entry<String,String> optEntry : setting.getOptions().entrySet()) {
+            sb.append("-        ").append(optEntry.getKey()).append(" = ").append(optEntry.getValue()).append("\n");
+          }
+        }
+      }
+    }
+    sb.append("-");
+    shellState.getReader().println(sb.toString());
+
+    return 0;
+  }
+
+  @Override
+  public String description() {
+    return "lists table-specific or namespace-specific iterators configured in this shell session";
+  }
+
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+
+    nameOpt = new Option("n", "name", true, "iterator to list");
+    nameOpt.setArgName("itername");
+
+    allScopesOpt = new Option("all", "all-scopes", false, "list from all scopes");
+    o.addOption(allScopesOpt);
+    
+    scopeOpts = new EnumMap<IteratorScope,Option>(IteratorScope.class);
+    scopeOpts.put(IteratorScope.minc, new Option(IteratorScope.minc.name(), "minor-compaction", false, "list iterator for minor compaction scope"));
+    scopeOpts.put(IteratorScope.majc, new Option(IteratorScope.majc.name(), "major-compaction", false, "list iterator for major compaction scope"));
+    scopeOpts.put(IteratorScope.scan, new Option(IteratorScope.scan.name(), "scan-time", false, "list iterator for scan scope"));
+
+    OptionGroup grp = new OptionGroup();
+    grp.addOption(OptUtil.tableOpt("table to list the configured iterators on"));
+    grp.addOption(OptUtil.namespaceOpt("namespace to list the configured iterators on"));
+    o.addOptionGroup(grp);
+    o.addOption(nameOpt);
+
+    for (Option opt : scopeOpts.values()) {
+      o.addOption(opt);
+    }
+
+    return o;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/ListScansCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/ListScansCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/ListScansCommand.java
new file mode 100644
index 0000000..598503e
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/ListScansCommand.java
@@ -0,0 +1,78 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.accumulo.core.client.admin.InstanceOperations;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+
+public class ListScansCommand extends Command {
+  
+  private Option tserverOption, disablePaginationOpt;
+  
+  @Override
+  public String description() {
+    return "lists what scans are currently running in accumulo. See the accumulo.core.client.admin.ActiveScan javadoc for more information about columns.";
+  }
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    
+    List<String> tservers;
+    
+    final InstanceOperations instanceOps = shellState.getConnector().instanceOperations();
+    
+    final boolean paginate = !cl.hasOption(disablePaginationOpt.getOpt());
+    
+    if (cl.hasOption(tserverOption.getOpt())) {
+      tservers = new ArrayList<String>();
+      tservers.add(cl.getOptionValue(tserverOption.getOpt()));
+    } else {
+      tservers = instanceOps.getTabletServers();
+    }
+    
+    shellState.printLines(new ActiveScanIterator(tservers, instanceOps), paginate);
+    
+    return 0;
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options opts = new Options();
+    
+    tserverOption = new Option("ts", "tabletServer", true, "tablet server to list scans for");
+    tserverOption.setArgName("tablet server");
+    opts.addOption(tserverOption);
+    
+    disablePaginationOpt = new Option("np", "no-pagination", false, "disable pagination of output");
+    opts.addOption(disablePaginationOpt);
+    
+    return opts;
+  }
+  
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/ListShellIterCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/ListShellIterCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/ListShellIterCommand.java
new file mode 100644
index 0000000..59f8f46
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/ListShellIterCommand.java
@@ -0,0 +1,105 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.util.List;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import org.apache.accumulo.core.client.IteratorSetting;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+
+/**
+ * 
+ */
+public class ListShellIterCommand extends Command {
+  
+  private Option nameOpt, profileOpt;
+
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    if (shellState.iteratorProfiles.size() == 0)
+      return 0;
+    
+    final StringBuilder sb = new StringBuilder();
+
+    String profile = null;
+    if (cl.hasOption(profileOpt.getOpt()))
+      profile = cl.getOptionValue(profileOpt.getOpt());
+
+    String name = null;
+    if (cl.hasOption(nameOpt.getOpt()))
+      name = cl.getOptionValue(nameOpt.getOpt());
+
+    Set<Entry<String,List<IteratorSetting>>> es = shellState.iteratorProfiles.entrySet();
+    for (Entry<String,List<IteratorSetting>> entry : es) {
+      if (profile != null && !profile.equals(entry.getKey()))
+        continue;
+
+      sb.append("-\n");
+      sb.append("- Profile : " + entry.getKey() + "\n");
+      for (IteratorSetting setting : entry.getValue()) {
+        if (name != null && !name.equals(setting.getName()))
+          continue;
+
+        sb.append("-    Iterator ").append(setting.getName()).append(", ").append(" options:\n");
+        sb.append("-        ").append("iteratorPriority").append(" = ").append(setting.getPriority()).append("\n");
+        sb.append("-        ").append("iteratorClassName").append(" = ").append(setting.getIteratorClass()).append("\n");
+        for (Entry<String,String> optEntry : setting.getOptions().entrySet()) {
+          sb.append("-        ").append(optEntry.getKey()).append(" = ").append(optEntry.getValue()).append("\n");
+        }
+      }
+    }
+    
+    if (sb.length() > 0) {
+      sb.append("-\n");
+    }
+
+    shellState.getReader().print(sb.toString());
+
+    return 0;
+  }
+  
+  public String description() {
+    return "lists iterators profiles configured in shell";
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+    
+    profileOpt = new Option("pn", "profile", true, "iterator profile name");
+    profileOpt.setArgName("profile");
+
+    nameOpt = new Option("n", "name", true, "iterator to list");
+    nameOpt.setArgName("itername");
+    
+    o.addOption(profileOpt);
+    o.addOption(nameOpt);
+
+    return o;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/MaxRowCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/MaxRowCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/MaxRowCommand.java
new file mode 100644
index 0000000..1794b57
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/MaxRowCommand.java
@@ -0,0 +1,55 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import org.apache.accumulo.core.data.Range;
+import org.apache.accumulo.core.security.Authorizations;
+import org.apache.accumulo.core.util.interpret.ScanInterpreter;
+import org.apache.accumulo.shell.Shell;
+import org.apache.commons.cli.CommandLine;
+import org.apache.hadoop.io.Text;
+
+public class MaxRowCommand extends ScanCommand {
+  
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    final String tableName = OptUtil.getTableOpt(cl, shellState);
+    
+    final ScanInterpreter interpeter = getInterpreter(cl, tableName, shellState);
+    
+    final Range range = getRange(cl, interpeter);
+    final Authorizations auths = getAuths(cl, shellState);
+    final Text startRow = range.getStartKey() == null ? null : range.getStartKey().getRow();
+    final Text endRow = range.getEndKey() == null ? null : range.getEndKey().getRow();
+    
+    try {
+      final Text max = shellState.getConnector().tableOperations()
+          .getMaxRow(tableName, auths, startRow, range.isStartKeyInclusive(), endRow, range.isEndKeyInclusive());
+      if (max != null) {
+        shellState.getReader().println(max.toString());
+      }
+    } catch (Exception e) {
+      e.printStackTrace();
+    }
+    
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "finds the max row in a table within a given range";
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/MergeCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/MergeCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/MergeCommand.java
new file mode 100644
index 0000000..33d63fa
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/MergeCommand.java
@@ -0,0 +1,111 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.io.IOException;
+
+import org.apache.accumulo.core.conf.AccumuloConfiguration;
+import org.apache.accumulo.core.util.Merge;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+import org.apache.hadoop.io.Text;
+
+public class MergeCommand extends Command {
+  private Option verboseOpt, forceOpt, sizeOpt, allOpt;
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    boolean verbose = shellState.isVerbose();
+    boolean force = false;
+    boolean all = false;
+    long size = -1;
+    final String tableName = OptUtil.getTableOpt(cl, shellState);
+    final Text startRow = OptUtil.getStartRow(cl);
+    final Text endRow = OptUtil.getEndRow(cl);
+    if (cl.hasOption(verboseOpt.getOpt())) {
+      verbose = true;
+    }
+    if (cl.hasOption(forceOpt.getOpt())) {
+      force = true;
+    }
+    if (cl.hasOption(allOpt.getOpt())) {
+      all = true;
+    }
+    if (cl.hasOption(sizeOpt.getOpt())) {
+      size = AccumuloConfiguration.getMemoryInBytes(cl.getOptionValue(sizeOpt.getOpt()));
+    }
+    if (startRow == null && endRow == null && size < 0 && !all) {
+      shellState.getReader().flush();
+      String line = shellState.getReader().readLine("Merge the entire table { " + tableName + " } into one tablet (yes|no)? ");
+      if (line == null)
+        return 0;
+      if (!line.equalsIgnoreCase("y") && !line.equalsIgnoreCase("yes"))
+        return 0;
+    }
+    if (size < 0) {
+      shellState.getConnector().tableOperations().merge(tableName, startRow, endRow);
+    } else {
+      final boolean finalVerbose = verbose;
+      final Merge merge = new Merge() {
+        protected void message(String fmt, Object... args) {
+          if (finalVerbose) {
+            try {
+              shellState.getReader().println(String.format(fmt, args));
+            } catch (IOException ex) {
+              throw new RuntimeException(ex);
+            }
+          }
+        }
+      };
+      merge.mergomatic(shellState.getConnector(), tableName, startRow, endRow, size, force);
+    }
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "merges tablets in a table";
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+    verboseOpt = new Option("v", "verbose", false, "verbose output during merge");
+    sizeOpt = new Option("s", "size", true, "merge tablets to the given size over the entire table");
+    forceOpt = new Option("f", "force", false, "merge small tablets to large tablets, even if it goes over the given size");
+    allOpt = new Option("", "all", false, "allow an entire table to be merged into one tablet without prompting the user for confirmation");
+    Option startRowOpt = OptUtil.startRowOpt();
+    startRowOpt.setDescription("begin row (NOT inclusive)");
+    o.addOption(startRowOpt);
+    o.addOption(OptUtil.endRowOpt());
+    o.addOption(OptUtil.tableOpt("table to be merged"));
+    o.addOption(verboseOpt);
+    o.addOption(sizeOpt);
+    o.addOption(forceOpt);
+    o.addOption(allOpt);
+    return o;
+  }
+  
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/NamespacePermissionsCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/NamespacePermissionsCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/NamespacePermissionsCommand.java
new file mode 100644
index 0000000..99ba6ad
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/NamespacePermissionsCommand.java
@@ -0,0 +1,44 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.io.IOException;
+
+import org.apache.accumulo.core.security.NamespacePermission;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+
+public class NamespacePermissionsCommand extends Command {
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws IOException {
+    for (String p : NamespacePermission.printableValues()) {
+      shellState.getReader().println(p);
+    }
+    return 0;
+  }
+
+  @Override
+  public String description() {
+    return "displays a list of valid namespace permissions";
+  }
+
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/NamespacesCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/NamespacesCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/NamespacesCommand.java
new file mode 100644
index 0000000..d822cf6
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/NamespacesCommand.java
@@ -0,0 +1,83 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.TreeMap;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.impl.Namespaces;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+
+import com.google.common.base.Function;
+import com.google.common.collect.Iterators;
+
+public class NamespacesCommand extends Command {
+  private Option disablePaginationOpt, namespaceIdOption;
+
+  private static final String DEFAULT_NAMESPACE_DISPLAY_NAME = "\"\"";
+
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException, IOException {
+    Map<String,String> namespaces = new TreeMap<String,String>(shellState.getConnector().namespaceOperations().namespaceIdMap());
+
+    Iterator<String> it = Iterators.transform(namespaces.entrySet().iterator(), new Function<Entry<String,String>,String>() {
+      @Override
+      public String apply(Map.Entry<String,String> entry) {
+        String name = entry.getKey();
+        if (Namespaces.DEFAULT_NAMESPACE.equals(name))
+          name = DEFAULT_NAMESPACE_DISPLAY_NAME;
+        String id = entry.getValue();
+        if (cl.hasOption(namespaceIdOption.getOpt()))
+          return String.format(TablesCommand.NAME_AND_ID_FORMAT, name, id);
+        else
+          return name;
+      };
+    });
+
+    shellState.printLines(it, !cl.hasOption(disablePaginationOpt.getOpt()));
+    return 0;
+  }
+
+  @Override
+  public String description() {
+    return "displays a list of all existing namespaces";
+  }
+
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+    namespaceIdOption = new Option("l", "list-ids", false, "display internal namespace ids along with the name");
+    o.addOption(namespaceIdOption);
+    disablePaginationOpt = new Option("np", "no-pagination", false, "disable pagination of output");
+    o.addOption(disablePaginationOpt);
+    return o;
+  }
+
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/NoTableCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/NoTableCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/NoTableCommand.java
new file mode 100644
index 0000000..7ff6358
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/NoTableCommand.java
@@ -0,0 +1,40 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+
+public class NoTableCommand extends Command {
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    shellState.setTableName("");
+    
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "returns to a tableless shell state";
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/OfflineCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/OfflineCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/OfflineCommand.java
new file mode 100644
index 0000000..6ac397c
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/OfflineCommand.java
@@ -0,0 +1,61 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.core.metadata.MetadataTable;
+import org.apache.accumulo.shell.Shell;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+
+public class OfflineCommand extends TableOperation {
+  
+  private boolean wait;
+  private Option waitOpt;
+  
+  @Override
+  public String description() {
+    return "starts the process of taking table offline";
+  }
+  
+  protected void doTableOp(final Shell shellState, final String tableName) throws AccumuloException, AccumuloSecurityException, TableNotFoundException {
+    if (tableName.equals(MetadataTable.NAME)) {
+      Shell.log.info("  You cannot take the " + MetadataTable.NAME + " offline.");
+    } else {
+      shellState.getConnector().tableOperations().offline(tableName, wait);
+      Shell.log.info("Offline of table " + tableName + (wait ? " completed." : " initiated..."));
+    }
+  }
+  
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    wait = cl.hasOption(waitOpt.getLongOpt());
+    return super.execute(fullCommand, cl, shellState);
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options opts = super.getOptions();
+    waitOpt = new Option("w", "wait", false, "wait for offline to finish");
+    opts.addOption(waitOpt); 
+    return opts;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/OnlineCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/OnlineCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/OnlineCommand.java
new file mode 100644
index 0000000..ace069f
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/OnlineCommand.java
@@ -0,0 +1,61 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.core.metadata.RootTable;
+import org.apache.accumulo.shell.Shell;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+
+public class OnlineCommand extends TableOperation {
+  
+  private boolean wait;
+  private Option waitOpt;
+  
+  @Override
+  public String description() {
+    return "starts the process of putting a table online";
+  }
+  
+  @Override
+  protected void doTableOp(final Shell shellState, final String tableName) throws AccumuloException, AccumuloSecurityException, TableNotFoundException {
+    if (tableName.equals(RootTable.NAME)) {
+      Shell.log.info("  The " + RootTable.NAME + " is always online.");
+    } else {
+      shellState.getConnector().tableOperations().online(tableName, wait);
+      Shell.log.info("Online of table " + tableName + (wait ? " completed." : " initiated..."));
+    }
+  }
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    wait = cl.hasOption(waitOpt.getLongOpt());
+    return super.execute(fullCommand, cl, shellState);
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options opts = super.getOptions();
+    waitOpt = new Option("w", "wait", false, "wait for online to finish");
+    opts.addOption(waitOpt); 
+    return opts;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/OptUtil.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/OptUtil.java b/shell/src/main/java/org/apache/accumulo/shell/commands/OptUtil.java
new file mode 100644
index 0000000..6243761
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/OptUtil.java
@@ -0,0 +1,146 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.io.UnsupportedEncodingException;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.NamespaceNotFoundException;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.shell.Shell;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.OptionGroup;
+import org.apache.hadoop.io.Text;
+
+public abstract class OptUtil {
+  public static final String START_ROW_OPT = "b";
+  public static final String END_ROW_OPT = "e";
+
+  public static String getTableOpt(final CommandLine cl, final Shell shellState) throws TableNotFoundException {
+    String tableName;
+
+    if (cl.hasOption(Shell.tableOption)) {
+      tableName = cl.getOptionValue(Shell.tableOption);
+      if (!shellState.getConnector().tableOperations().exists(tableName)) {
+        throw new TableNotFoundException(tableName, tableName, "specified table that doesn't exist");
+      }
+    } else {
+      shellState.checkTableState();
+      tableName = shellState.getTableName();
+    }
+
+    return tableName;
+  }
+
+  public static String getNamespaceOpt(final CommandLine cl, final Shell shellState) throws NamespaceNotFoundException, AccumuloException,
+      AccumuloSecurityException {
+    String namespace = null;
+    if (cl.hasOption(Shell.namespaceOption)) {
+      namespace = cl.getOptionValue(Shell.namespaceOption);
+      if (!shellState.getConnector().namespaceOperations().exists(namespace)) {
+        throw new NamespaceNotFoundException(namespace, namespace, "specified namespace that doesn't exist");
+      }
+    } else {
+      throw new NamespaceNotFoundException(null, null, "no namespace specified");
+    }
+    return namespace;
+  }
+
+  public static Option tableOpt() {
+    return tableOpt("tableName");
+  }
+
+  public static Option tableOpt(final String description) {
+    final Option tableOpt = new Option(Shell.tableOption, "table", true, description);
+    tableOpt.setArgName("table");
+    tableOpt.setRequired(false);
+    return tableOpt;
+  }
+
+  public static Option namespaceOpt() {
+    return namespaceOpt("namespace");
+  }
+
+  public static Option namespaceOpt(final String description) {
+    final Option namespaceOpt = new Option(Shell.namespaceOption, "namespace", true, description);
+    namespaceOpt.setArgName("namespace");
+    namespaceOpt.setRequired(false);
+    return namespaceOpt;
+  }
+
+  public static enum AdlOpt {
+    ADD("a"), DELETE("d"), LIST("l");
+
+    public final String opt;
+
+    private AdlOpt(String opt) {
+      this.opt = opt;
+    }
+  }
+
+  public static AdlOpt getAldOpt(final CommandLine cl) {
+    if (cl.hasOption(AdlOpt.ADD.opt)) {
+      return AdlOpt.ADD;
+    } else if (cl.hasOption(AdlOpt.DELETE.opt)) {
+      return AdlOpt.DELETE;
+    } else {
+      return AdlOpt.LIST;
+    }
+  }
+
+  public static OptionGroup addListDeleteGroup(final String name) {
+    final Option addOpt = new Option(AdlOpt.ADD.opt, "add", false, "add " + name);
+    final Option deleteOpt = new Option(AdlOpt.DELETE.opt, "delete", false, "delete " + name);
+    final Option listOpt = new Option(AdlOpt.LIST.opt, "list", false, "list " + name + "(s)");
+    final OptionGroup og = new OptionGroup();
+    og.addOption(addOpt);
+    og.addOption(deleteOpt);
+    og.addOption(listOpt);
+    og.setRequired(true);
+    return og;
+  }
+
+  public static Option startRowOpt() {
+    final Option o = new Option(START_ROW_OPT, "begin-row", true, "begin row (inclusive)");
+    o.setArgName("begin-row");
+    return o;
+  }
+
+  public static Option endRowOpt() {
+    final Option o = new Option(END_ROW_OPT, "end-row", true, "end row (inclusive)");
+    o.setArgName("end-row");
+    return o;
+  }
+
+  public static Text getStartRow(final CommandLine cl) throws UnsupportedEncodingException {
+    if (cl.hasOption(START_ROW_OPT)) {
+      return new Text(cl.getOptionValue(START_ROW_OPT).getBytes(Shell.CHARSET));
+    } else {
+      return null;
+    }
+  }
+
+  public static Text getEndRow(final CommandLine cl) throws UnsupportedEncodingException {
+    if (cl.hasOption(END_ROW_OPT)) {
+      return new Text(cl.getOptionValue(END_ROW_OPT).getBytes(Shell.CHARSET));
+    } else {
+      return null;
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/PasswdCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/PasswdCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/PasswdCommand.java
new file mode 100644
index 0000000..c1ef990
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/PasswdCommand.java
@@ -0,0 +1,96 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.impl.thrift.SecurityErrorCode;
+import org.apache.accumulo.core.client.security.tokens.PasswordToken;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+
+public class PasswdCommand extends Command {
+  private Option userOpt;
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException, IOException {
+    final String currentUser = shellState.getConnector().whoami();
+    final String user = cl.getOptionValue(userOpt.getOpt(), currentUser);
+    
+    String password = null;
+    String passwordConfirm = null;
+    String oldPassword = null;
+    
+    oldPassword = shellState.readMaskedLine("Enter current password for '" + currentUser + "': ", '*');
+    if (oldPassword == null) {
+      shellState.getReader().println();
+      return 0;
+    } // user canceled
+    
+    if (!shellState.getConnector().securityOperations().authenticateUser(currentUser, new PasswordToken(oldPassword)))
+      throw new AccumuloSecurityException(user, SecurityErrorCode.BAD_CREDENTIALS);
+    
+    password = shellState.readMaskedLine("Enter new password for '" + user + "': ", '*');
+    if (password == null) {
+      shellState.getReader().println();
+      return 0;
+    } // user canceled
+    passwordConfirm = shellState.readMaskedLine("Please confirm new password for '" + user + "': ", '*');
+    if (passwordConfirm == null) {
+      shellState.getReader().println();
+      return 0;
+    } // user canceled
+    
+    if (!password.equals(passwordConfirm)) {
+      throw new IllegalArgumentException("Passwords do not match");
+    }
+    byte[] pass = password.getBytes(StandardCharsets.UTF_8);
+    shellState.getConnector().securityOperations().changeLocalUserPassword(user, new PasswordToken(pass));
+    // update the current credentials if the password changed was for
+    // the current user
+    if (shellState.getConnector().whoami().equals(user)) {
+      shellState.updateUser(user, new PasswordToken(pass));
+    }
+    Shell.log.debug("Changed password for user " + user);
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "changes a user's password";
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+    userOpt = new Option(Shell.userOption, "user", true, "user to operate on");
+    userOpt.setArgName("user");
+    o.addOption(userOpt);
+    return o;
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/PingCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/PingCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/PingCommand.java
new file mode 100644
index 0000000..ef7a9e4
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/PingCommand.java
@@ -0,0 +1,82 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.accumulo.core.client.admin.InstanceOperations;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+
+/**
+ * 
+ */
+public class PingCommand extends Command {
+  
+  private Option tserverOption, disablePaginationOpt;
+  
+  @Override
+  public String description() {
+    return "ping tablet servers";
+  }
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    
+    List<String> tservers;
+    
+    final InstanceOperations instanceOps = shellState.getConnector().instanceOperations();
+    
+    final boolean paginate = !cl.hasOption(disablePaginationOpt.getOpt());
+    
+    if (cl.hasOption(tserverOption.getOpt())) {
+      tservers = new ArrayList<String>();
+      tservers.add(cl.getOptionValue(tserverOption.getOpt()));
+    } else {
+      tservers = instanceOps.getTabletServers();
+    }
+    
+    shellState.printLines(new PingIterator(tservers, instanceOps), paginate);
+    
+    return 0;
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options opts = new Options();
+    
+    tserverOption = new Option("ts", "tabletServer", true, "tablet server to ping");
+    tserverOption.setArgName("tablet server");
+    opts.addOption(tserverOption);
+    
+    disablePaginationOpt = new Option("np", "no-pagination", false, "disable pagination of output");
+    opts.addOption(disablePaginationOpt);
+    
+    return opts;
+  }
+  
+}
+

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/PingIterator.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/PingIterator.java b/shell/src/main/java/org/apache/accumulo/shell/commands/PingIterator.java
new file mode 100644
index 0000000..e414ed4
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/PingIterator.java
@@ -0,0 +1,58 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.admin.InstanceOperations;
+
+class PingIterator implements Iterator<String> {
+  
+  private Iterator<String> iter;
+  private InstanceOperations instanceOps;
+
+  PingIterator(List<String> tservers, InstanceOperations instanceOps) {
+    iter = tservers.iterator();
+    this.instanceOps = instanceOps;
+  }
+  
+  @Override
+  public boolean hasNext() {
+    return iter.hasNext();
+  }
+  
+  @Override
+  public String next() {
+    String tserver = iter.next();
+    
+    try {
+      instanceOps.ping(tserver);
+    } catch (AccumuloException e) {
+      return tserver + " ERROR " + e.getMessage();
+    }
+    
+    return tserver + " OK";
+  }
+  
+  @Override
+  public void remove() {
+    throw new UnsupportedOperationException();
+  }
+  
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/QuestionCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/QuestionCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/QuestionCommand.java
new file mode 100644
index 0000000..ae6b0a1
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/QuestionCommand.java
@@ -0,0 +1,24 @@
+/*
+ * 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.accumulo.shell.commands;
+
+public class QuestionCommand extends HelpCommand {
+  @Override
+  public String getName() {
+    return "?";
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/QuitCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/QuitCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/QuitCommand.java
new file mode 100644
index 0000000..3ad2274
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/QuitCommand.java
@@ -0,0 +1,19 @@
+/*
+ * 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.accumulo.shell.commands;
+
+public class QuitCommand extends ExitCommand {}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/QuotedStringTokenizer.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/QuotedStringTokenizer.java b/shell/src/main/java/org/apache/accumulo/shell/commands/QuotedStringTokenizer.java
new file mode 100644
index 0000000..ecc51eb
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/QuotedStringTokenizer.java
@@ -0,0 +1,141 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.io.UnsupportedEncodingException;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Iterator;
+
+import org.apache.accumulo.core.util.BadArgumentException;
+import org.apache.accumulo.shell.Shell;
+
+/**
+ * A basic tokenizer for generating tokens from a string. It understands quoted strings and escaped quote characters.
+ * 
+ * You can use the escape sequence '\' to escape single quotes, double quotes, and spaces only, in addition to the escape character itself.
+ * 
+ * The behavior is the same for single and double quoted strings. (i.e. '\'' is the same as "\'")
+ */
+
+public class QuotedStringTokenizer implements Iterable<String> {
+  private ArrayList<String> tokens;
+  private String input;
+  
+  public QuotedStringTokenizer(final String t) throws BadArgumentException {
+    tokens = new ArrayList<String>();
+    this.input = t;
+    try {
+      createTokens();
+    } catch (UnsupportedEncodingException e) {
+      throw new IllegalArgumentException(e.getMessage());
+    }
+  }
+  
+  public String[] getTokens() {
+    return tokens.toArray(new String[tokens.size()]);
+  }
+  
+  private void createTokens() throws BadArgumentException, UnsupportedEncodingException {
+    boolean inQuote = false;
+    boolean inEscapeSequence = false;
+    String hexChars = null;
+    char inQuoteChar = '"';
+    
+    final byte[] token = new byte[input.length()];
+    int tokenLength = 0;
+    final byte[] inputBytes = input.getBytes(StandardCharsets.UTF_8);
+    for (int i = 0; i < input.length(); ++i) {
+      final char ch = input.charAt(i);
+      
+      // if I ended up in an escape sequence, check for valid escapable character, and add it as a literal
+      if (inEscapeSequence) {
+        inEscapeSequence = false;
+        if (ch == 'x') {
+          hexChars = "";
+        } else if (ch == ' ' || ch == '\'' || ch == '"' || ch == '\\') {
+          token[tokenLength++] = inputBytes[i];
+        } else {
+          throw new BadArgumentException("can only escape single quotes, double quotes, the space character, the backslash, and hex input", input, i);
+        }
+      }
+      // in a hex escape sequence
+      else if (hexChars != null) {
+        final int digit = Character.digit(ch, 16);
+        if (digit < 0) {
+          throw new BadArgumentException("expected hex character", input, i);
+        }
+        hexChars += ch;
+        if (hexChars.length() == 2) {
+          byte b;
+          try {
+            b = (byte) (0xff & Short.parseShort(hexChars, 16));
+            if (!Character.isValidCodePoint(0xff & b))
+              throw new NumberFormatException();
+          } catch (NumberFormatException e) {
+            throw new BadArgumentException("unsupported non-ascii character", input, i);
+          }
+          token[tokenLength++] = b;
+          hexChars = null;
+        }
+      }
+      // in a quote, either end the quote, start escape, or continue a token
+      else if (inQuote) {
+        if (ch == inQuoteChar) {
+          inQuote = false;
+          tokens.add(new String(token, 0, tokenLength, Shell.CHARSET));
+          tokenLength = 0;
+        } else if (ch == '\\') {
+          inEscapeSequence = true;
+        } else {
+          token[tokenLength++] = inputBytes[i];
+        }
+      }
+      // not in a quote, either enter a quote, end a token, start escape, or continue a token
+      else {
+        if (ch == '\'' || ch == '"') {
+          if (tokenLength > 0) {
+            tokens.add(new String(token, 0, tokenLength, Shell.CHARSET));
+            tokenLength = 0;
+          }
+          inQuote = true;
+          inQuoteChar = ch;
+        } else if (ch == ' ' && tokenLength > 0) {
+          tokens.add(new String(token, 0, tokenLength, Shell.CHARSET));
+          tokenLength = 0;
+        } else if (ch == '\\') {
+          inEscapeSequence = true;
+        } else if (ch != ' ') {
+          token[tokenLength++] = inputBytes[i];
+        }
+      }
+    }
+    if (inQuote) {
+      throw new BadArgumentException("missing terminating quote", input, input.length());
+    } else if (inEscapeSequence || hexChars != null) {
+      throw new BadArgumentException("escape sequence not complete", input, input.length());
+    }
+    if (tokenLength > 0) {
+      tokens.add(new String(token, 0, tokenLength, Shell.CHARSET));
+    }
+  }
+  
+  @Override
+  public Iterator<String> iterator() {
+    return tokens.iterator();
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/RenameNamespaceCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/RenameNamespaceCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/RenameNamespaceCommand.java
new file mode 100644
index 0000000..f456a30
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/RenameNamespaceCommand.java
@@ -0,0 +1,79 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.NamespaceExistsException;
+import org.apache.accumulo.core.client.NamespaceNotFoundException;
+import org.apache.accumulo.core.client.TableExistsException;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.core.client.impl.Namespaces;
+import org.apache.accumulo.core.client.impl.Tables;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Token;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+
+public class RenameNamespaceCommand extends Command {
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException,
+      TableNotFoundException, TableExistsException, NamespaceNotFoundException, NamespaceExistsException {
+    String old = cl.getArgs()[0];
+    String newer = cl.getArgs()[1];
+    boolean resetContext = false;
+    String currentTableId = "";
+    if (!(shellState.getTableName() == null) && !shellState.getTableName().isEmpty()) {
+      String namespaceId = Namespaces.getNamespaceId(shellState.getInstance(), old);
+      List<String> tableIds = Namespaces.getTableIds(shellState.getInstance(), namespaceId);
+      currentTableId = Tables.getTableId(shellState.getInstance(), shellState.getTableName());
+      resetContext = tableIds.contains(currentTableId);
+    }
+
+    shellState.getConnector().namespaceOperations().rename(old, newer);
+
+    if (resetContext) {
+      shellState.setTableName(Tables.getTableName(shellState.getInstance(), currentTableId));
+    }
+
+    return 0;
+  }
+
+  @Override
+  public String usage() {
+    return getName() + " <current namespace> <new namespace>";
+  }
+
+  @Override
+  public String description() {
+    return "renames a namespace";
+  }
+
+  @Override
+  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> special) {
+    registerCompletionForNamespaces(root, special);
+  }
+
+  @Override
+  public int numArgs() {
+    return 2;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/RenameTableCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/RenameTableCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/RenameTableCommand.java
new file mode 100644
index 0000000..a810320
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/RenameTableCommand.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.accumulo.shell.commands;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.TableExistsException;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.core.client.impl.Tables;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Token;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+
+public class RenameTableCommand extends Command {
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException,
+      TableNotFoundException, TableExistsException {
+    shellState.getConnector().tableOperations().rename(cl.getArgs()[0], cl.getArgs()[1]);
+    if (shellState.getTableName().equals(Tables.qualified(cl.getArgs()[0]))) {
+      shellState.setTableName(cl.getArgs()[1]);
+    }
+    return 0;
+  }
+
+  @Override
+  public String usage() {
+    return getName() + " <current table name> <new table name>";
+  }
+
+  @Override
+  public String description() {
+    return "renames a table";
+  }
+
+  @Override
+  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> completionSet) {
+    registerCompletionForTables(root, completionSet);
+  }
+
+  @Override
+  public int numArgs() {
+    return 2;
+  }
+}


[15/53] [abbrv] git commit: ACCUMULO-2558 Add unit tests for server/gc

Posted by el...@apache.org.
ACCUMULO-2558 Add unit tests for server/gc

Code changes accompanying unit tests:
- visibility of methods under test changed from private to package
- some methods refactored to take arguments, to permit testability
- GarbageCollectWriteAheadLogs.isUUID() improved to check for null and to check
  length of potential UUID, since UUID.fromString() will accept UUIDs with extraneous
  leading zeroes in components
- SimpleGarbageCollector.getZooLock() finds ZK root using instance field of class
  instead of calling HdfsZooInstance.getInstance() again
- SimpleGarbageCollector.init() no longer declares throwing IOException


Project: http://git-wip-us.apache.org/repos/asf/accumulo/repo
Commit: http://git-wip-us.apache.org/repos/asf/accumulo/commit/88f24d23
Tree: http://git-wip-us.apache.org/repos/asf/accumulo/tree/88f24d23
Diff: http://git-wip-us.apache.org/repos/asf/accumulo/diff/88f24d23

Branch: refs/heads/ACCUMULO-378
Commit: 88f24d2323efd1aa33de1bf2cd5a0241cbd78306
Parents: 8d6a4cf
Author: Bill Havanki <bh...@cloudera.com>
Authored: Thu Mar 27 11:27:15 2014 -0400
Committer: Bill Havanki <bh...@cloudera.com>
Committed: Mon Apr 7 17:05:03 2014 -0400

----------------------------------------------------------------------
 server/gc/pom.xml                               |   5 +
 .../gc/GarbageCollectWriteAheadLogs.java        |  89 ++++++-
 .../accumulo/gc/SimpleGarbageCollector.java     | 134 +++++++++-
 .../gc/GarbageCollectWriteAheadLogsTest.java    | 264 +++++++++++++++++++
 .../gc/SimpleGarbageCollectorOptsTest.java      |  37 +++
 .../accumulo/gc/SimpleGarbageCollectorTest.java | 146 ++++++++++
 6 files changed, 657 insertions(+), 18 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/accumulo/blob/88f24d23/server/gc/pom.xml
----------------------------------------------------------------------
diff --git a/server/gc/pom.xml b/server/gc/pom.xml
index 6f95273..33cc596 100644
--- a/server/gc/pom.xml
+++ b/server/gc/pom.xml
@@ -73,6 +73,11 @@
       <scope>test</scope>
     </dependency>
     <dependency>
+      <groupId>org.easymock</groupId>
+      <artifactId>easymock</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
       <groupId>org.slf4j</groupId>
       <artifactId>slf4j-api</artifactId>
       <scope>test</scope>

http://git-wip-us.apache.org/repos/asf/accumulo/blob/88f24d23/server/gc/src/main/java/org/apache/accumulo/gc/GarbageCollectWriteAheadLogs.java
----------------------------------------------------------------------
diff --git a/server/gc/src/main/java/org/apache/accumulo/gc/GarbageCollectWriteAheadLogs.java b/server/gc/src/main/java/org/apache/accumulo/gc/GarbageCollectWriteAheadLogs.java
index ab2ab42..ae850af 100644
--- a/server/gc/src/main/java/org/apache/accumulo/gc/GarbageCollectWriteAheadLogs.java
+++ b/server/gc/src/main/java/org/apache/accumulo/gc/GarbageCollectWriteAheadLogs.java
@@ -64,12 +64,44 @@ public class GarbageCollectWriteAheadLogs {
   
   private boolean useTrash;
   
+  /**
+   * Creates a new GC WAL object.
+   *
+   * @param instance instance to use
+   * @param fs volume manager to use
+   * @param useTrash true to move files to trash rather than delete them
+   */
   GarbageCollectWriteAheadLogs(Instance instance, VolumeManager fs, boolean useTrash) throws IOException {
     this.instance = instance;
     this.fs = fs;
     this.useTrash = useTrash;
   }
   
+  /**
+   * Gets the instance used by this object.
+   *
+   * @return instance
+   */
+  Instance getInstance() {
+    return instance;
+  }
+  /**
+   * Gets the volume manager used by this object.
+   *
+   * @return volume manager
+   */
+  VolumeManager getVolumeManager() {
+    return fs;
+  }
+  /**
+   * Checks if the volume manager should move files to the trash rather than
+   * delete them.
+   *
+   * @return true if trash is used
+   */
+  boolean isUsingTrash() {
+    return useTrash;
+  }
   public void collect(GCStatus status) {
     
     Span span = Trace.start("scanServers");
@@ -205,14 +237,29 @@ public class GarbageCollectWriteAheadLogs {
     return 0;
   }
   
-  private List<String> paths2strings(ArrayList<Path> paths) {
+  /**
+   * Converts a list of paths to their corresponding strings.
+   *
+   * @param paths list of paths
+   * @return string forms of paths
+   */
+  static List<String> paths2strings(List<Path> paths) {
     List<String> result = new ArrayList<String>(paths.size());
     for (Path path : paths)
       result.add(path.toString());
     return result;
   }
   
-  private static Map<String,ArrayList<Path>> mapServersToFiles(Map<Path,String> fileToServerMap, Map<String,Path> nameToFileMap) {
+  /**
+   * Reverses the given mapping of file paths to servers. The returned map
+   * provides a list of file paths for each server. Any path whose name is not
+   * in the mapping of file names to paths is skipped.
+   *
+   * @param fileToServerMap map of file paths to servers
+   * @param nameToFileMap map of file names to paths
+   * @return map of servers to lists of file paths
+   */
+  static Map<String,ArrayList<Path>> mapServersToFiles(Map<Path,String> fileToServerMap, Map<String,Path> nameToFileMap) {
     Map<String,ArrayList<Path>> result = new HashMap<String,ArrayList<Path>>();
     for (Entry<Path,String> fileServer : fileToServerMap.entrySet()) {
       if (!nameToFileMap.containsKey(fileServer.getKey().getName()))
@@ -251,11 +298,23 @@ public class GarbageCollectWriteAheadLogs {
     return count;
   }
 
+  private int scanServers(Map<Path,String> fileToServerMap, Map<String,Path> nameToFileMap) throws Exception {
+    return scanServers(ServerConstants.getWalDirs(), fileToServerMap, nameToFileMap);
+  }
   //TODO Remove deprecation warning suppression when Hadoop1 support is dropped
   @SuppressWarnings("deprecation")
-  private int scanServers(Map<Path,String> fileToServerMap, Map<String,Path> nameToFileMap) throws Exception {
+  /**
+   * Scans write-ahead log directories for logs. The maps passed in are
+   * populated with scan information.
+   *
+   * @param walDirs write-ahead log directories
+   * @param fileToServerMap map of file paths to servers
+   * @param nameToFileMap map of file names to paths
+   * @return number of servers located (including those with no logs present)
+   */
+  int scanServers(String[] walDirs, Map<Path,String> fileToServerMap, Map<String,Path> nameToFileMap) throws Exception {
     Set<String> servers = new HashSet<String>();
-    for (String walDir : ServerConstants.getWalDirs()) {
+    for (String walDir : walDirs) {
       Path walRoot = new Path(walDir);
       FileStatus[] listing = null;
       try {
@@ -290,9 +349,18 @@ public class GarbageCollectWriteAheadLogs {
   }
   
   private Map<String, Path> getSortedWALogs() throws IOException {
+    return getSortedWALogs(ServerConstants.getRecoveryDirs());
+  }
+  /**
+   * Looks for write-ahead logs in recovery directories.
+   *
+   * @param recoveryDirs recovery directories
+   * @return map of log file names to paths
+   */
+  Map<String, Path> getSortedWALogs(String[] recoveryDirs) throws IOException {
     Map<String, Path> result = new HashMap<String, Path>();
     
-    for (String dir : ServerConstants.getRecoveryDirs()) {
+    for (String dir : recoveryDirs) {
       Path recoveryDir = new Path(dir);
       
       if (fs.exists(recoveryDir)) {
@@ -309,7 +377,16 @@ public class GarbageCollectWriteAheadLogs {
     return result;
   }
   
-  static private boolean isUUID(String name) {
+  /**
+   * Checks if a string is a valid UUID.
+   *
+   * @param name string to check
+   * @return true if string is a UUID
+   */
+  static boolean isUUID(String name) {
+    if (name == null || name.length() != 36) {
+      return false;
+    }
     try {
       UUID.fromString(name);
       return true;

http://git-wip-us.apache.org/repos/asf/accumulo/blob/88f24d23/server/gc/src/main/java/org/apache/accumulo/gc/SimpleGarbageCollector.java
----------------------------------------------------------------------
diff --git a/server/gc/src/main/java/org/apache/accumulo/gc/SimpleGarbageCollector.java b/server/gc/src/main/java/org/apache/accumulo/gc/SimpleGarbageCollector.java
index 89925b4..39716eb 100644
--- a/server/gc/src/main/java/org/apache/accumulo/gc/SimpleGarbageCollector.java
+++ b/server/gc/src/main/java/org/apache/accumulo/gc/SimpleGarbageCollector.java
@@ -108,6 +108,9 @@ import com.google.common.net.HostAndPort;
 public class SimpleGarbageCollector implements Iface {
   private static final Text EMPTY_TEXT = new Text();
 
+  /**
+   * Options for the garbage collector.
+   */
   static class Opts extends ServerOpts {
     @Parameter(names = {"-v", "--verbose"}, description = "extra information will get printed to stdout also")
     boolean verbose = false;
@@ -115,8 +118,11 @@ public class SimpleGarbageCollector implements Iface {
     boolean safeMode = false;
   }
 
-  // how much of the JVM's available memory should it use gathering candidates
-  private static final float CANDIDATE_MEMORY_PERCENTAGE = 0.75f;
+  /**
+   * A fraction representing how much of the JVM's available memory should be
+   * used for gathering candidates.
+   */
+  static final float CANDIDATE_MEMORY_PERCENTAGE = 0.75f;
 
   private static final Logger log = Logger.getLogger(SimpleGarbageCollector.class);
 
@@ -148,18 +154,100 @@ public class SimpleGarbageCollector implements Iface {
     gc.run();
   }
 
+  /**
+   * Creates a new garbage collector.
+   *
+   * @param opts options
+   */
   public SimpleGarbageCollector(Opts opts) {
     this.opts = opts;
   }
 
-  public void init(VolumeManager fs, Instance instance, Credentials credentials, boolean noTrash) throws IOException {
+  /**
+   * Gets the credentials used by this GC.
+   *
+   * @return credentials
+   */
+  Credentials getCredentials() {
+    return credentials;
+  }
+  /**
+   * Gets the delay before the first collection.
+   *
+   * @return start delay, in milliseconds
+   */
+  long getStartDelay() {
+    return gcStartDelay;
+  }
+  /**
+   * Gets the volume manager used by this GC.
+   *
+   * @return volume manager
+   */
+  VolumeManager getVolumeManager() {
+    return fs;
+  }
+  /**
+   * Checks if the volume manager should move files to the trash rather than
+   * delete them.
+   *
+   * @return true if trash is used
+   */
+  boolean isUsingTrash() {
+    return useTrash;
+  }
+  /**
+   * Gets the options for this garbage collector.
+   */
+  Opts getOpts() {
+    return opts;
+  }
+  /**
+   * Gets the number of threads used for deleting files.
+   *
+   * @return number of delete threads
+   */
+  int getNumDeleteThreads() {
+    return numDeleteThreads;
+  }
+  /**
+   * Gets the instance used by this GC.
+   *
+   * @return instance
+   */
+  Instance getInstance() {
+    return instance;
+  }
+
+  /**
+   * Initializes this garbage collector with the current system configuration.
+   *
+   * @param fs volume manager
+   * @param instance instance
+   * @param credentials credentials
+   * @param noTrash true to not move files to trash instead of deleting
+   */
+  public void init(VolumeManager fs, Instance instance, Credentials credentials, boolean noTrash) {
+    init(fs, instance, credentials, noTrash, ServerConfiguration.getSystemConfiguration(instance));
+  }
+
+  /**
+   * Initializes this garbage collector.
+   *
+   * @param fs volume manager
+   * @param instance instance
+   * @param credentials credentials
+   * @param noTrash true to not move files to trash instead of deleting
+   * @param systemConfig system configuration
+   */
+  public void init(VolumeManager fs, Instance instance, Credentials credentials, boolean noTrash, AccumuloConfiguration systemConfig) {
     this.fs = fs;
     this.credentials = credentials;
     this.instance = instance;
 
-    gcStartDelay = ServerConfiguration.getSystemConfiguration(instance).getTimeInMillis(Property.GC_CYCLE_START);
-    long gcDelay = ServerConfiguration.getSystemConfiguration(instance).getTimeInMillis(Property.GC_CYCLE_DELAY);
-    numDeleteThreads = ServerConfiguration.getSystemConfiguration(instance).getCount(Property.GC_DELETE_THREADS);
+    gcStartDelay = systemConfig.getTimeInMillis(Property.GC_CYCLE_START);
+    long gcDelay = systemConfig.getTimeInMillis(Property.GC_CYCLE_DELAY);
+    numDeleteThreads = systemConfig.getCount(Property.GC_DELETE_THREADS);
     log.info("start delay: " + gcStartDelay + " milliseconds");
     log.info("time delay: " + gcDelay + " milliseconds");
     log.info("safemode: " + opts.safeMode);
@@ -194,7 +282,7 @@ public class SimpleGarbageCollector implements Iface {
       for (Entry<Key,Value> entry : scanner) {
         String cand = entry.getKey().getRow().toString().substring(MetadataSchema.DeletesSection.getRowPrefix().length());
         result.add(cand);
-        if (almostOutOfMemory()) {
+        if (almostOutOfMemory(Runtime.getRuntime())) {
           log.info("List of delete candidates has exceeded the memory threshold. Attempting to delete what has been gathered so far.");
           break;
         }
@@ -506,7 +594,16 @@ public class SimpleGarbageCollector implements Iface {
     }
   }
 
-  private boolean moveToTrash(Path path) throws IOException {
+  /**
+   * Moves a file to trash. If this garbage collector is not using trash, this
+   * method returns false and leaves the file alone. If the file is missing,
+   * this method returns false as opposed to throwing an exception.
+   *
+   * @param path
+   * @return true if the file was moved to trash
+   * @throws IOException if the volume manager encountered a problem
+   */
+  boolean moveToTrash(Path path) throws IOException {
     if (!useTrash)
       return false;
     try {
@@ -517,7 +614,7 @@ public class SimpleGarbageCollector implements Iface {
   }
 
   private void getZooLock(HostAndPort addr) throws KeeperException, InterruptedException {
-    String path = ZooUtil.getRoot(HdfsZooInstance.getInstance()) + Constants.ZGC_LOCK;
+    String path = ZooUtil.getRoot(instance) + Constants.ZGC_LOCK;
 
     LockWatcher lockWatcher = new LockWatcher() {
       @Override
@@ -563,8 +660,14 @@ public class SimpleGarbageCollector implements Iface {
     }
   }
 
-  static public boolean almostOutOfMemory() {
-    Runtime runtime = Runtime.getRuntime();
+  /**
+   * Checks if the system is almost out of memory.
+   *
+   * @param runtime Java runtime
+   * @return true if system is almost out of memory
+   * @see #CANDIDATE_MEMORY_PERCENTAGE
+   */
+  static boolean almostOutOfMemory(Runtime runtime) {
     return runtime.totalMemory() - runtime.freeMemory() > CANDIDATE_MEMORY_PERCENTAGE * runtime.maxMemory();
   }
 
@@ -576,7 +679,14 @@ public class SimpleGarbageCollector implements Iface {
     writer.addMutation(m);
   }
 
-  private boolean isDir(String delete) {
+  /**
+   * Checks if the given string is a directory.
+   *
+   * @param delete possible directory
+   * @return true if string is a directory
+   */
+  static boolean isDir(String delete) {
+    if (delete == null) { return false; }
     int slashCount = 0;
     for (int i = 0; i < delete.length(); i++)
       if (delete.charAt(i) == '/')

http://git-wip-us.apache.org/repos/asf/accumulo/blob/88f24d23/server/gc/src/test/java/org/apache/accumulo/gc/GarbageCollectWriteAheadLogsTest.java
----------------------------------------------------------------------
diff --git a/server/gc/src/test/java/org/apache/accumulo/gc/GarbageCollectWriteAheadLogsTest.java b/server/gc/src/test/java/org/apache/accumulo/gc/GarbageCollectWriteAheadLogsTest.java
new file mode 100644
index 0000000..f90b965
--- /dev/null
+++ b/server/gc/src/test/java/org/apache/accumulo/gc/GarbageCollectWriteAheadLogsTest.java
@@ -0,0 +1,264 @@
+/*
+ * 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.accumulo.gc;
+
+import java.io.FileNotFoundException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import org.apache.accumulo.core.client.Instance;
+import org.apache.accumulo.server.fs.VolumeManager;
+import org.apache.hadoop.fs.FileStatus;
+import org.apache.hadoop.fs.Path;
+
+import org.junit.Before;
+import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+
+public class GarbageCollectWriteAheadLogsTest {
+  private static final long BLOCK_SIZE = 64000000L;
+
+  private static final Path DIR_1_PATH = new Path("/dir1");
+  private static final Path DIR_2_PATH = new Path("/dir2");
+  private static final Path DIR_3_PATH = new Path("/dir3");
+  private static final String UUID1 = UUID.randomUUID().toString();
+  private static final String UUID2 = UUID.randomUUID().toString();
+  private static final String UUID3 = UUID.randomUUID().toString();
+
+  private Instance instance;
+  private VolumeManager volMgr;
+  private GarbageCollectWriteAheadLogs gcwal;
+  private long modTime;
+
+  @Before
+  public void setUp() throws Exception {
+    instance = createMock(Instance.class);
+    volMgr = createMock(VolumeManager.class);
+    gcwal = new GarbageCollectWriteAheadLogs(instance, volMgr, false);
+    modTime = System.currentTimeMillis();
+  }
+
+  @Test
+  public void testGetters() {
+    assertSame(instance, gcwal.getInstance());
+    assertSame(volMgr, gcwal.getVolumeManager());
+    assertFalse(gcwal.isUsingTrash());
+  }
+
+  @Test
+  public void testPathsToStrings() {
+    ArrayList<Path> paths = new ArrayList<Path>();
+    paths.add(new Path(DIR_1_PATH, "file1"));
+    paths.add(DIR_2_PATH);
+    paths.add(new Path(DIR_3_PATH, "file3"));
+    List<String> strings = GarbageCollectWriteAheadLogs.paths2strings(paths);
+    int len = 3;
+    assertEquals(len, strings.size());
+    for (int i = 0; i < len; i++) {
+      assertEquals(paths.get(i).toString(), strings.get(i));
+    }
+  }
+
+  @Test
+  public void testMapServersToFiles() {
+    /*
+     * Test fileToServerMap:
+     * /dir1/server1/uuid1 -> server1 (new-style)
+     * /dir1/uuid2 -> "" (old-style)
+     * /dir3/server3/uuid3 -> server3 (new-style)
+     */
+    Map<Path,String> fileToServerMap = new java.util.HashMap<Path,String>();
+    Path path1 = new Path(new Path(DIR_1_PATH, "server1"), UUID1);
+    fileToServerMap.put(path1, "server1"); // new-style
+    Path path2 = new Path(DIR_1_PATH, UUID2);
+    fileToServerMap.put(path2, ""); // old-style
+    Path path3 = new Path(new Path(DIR_3_PATH, "server3"), UUID3);
+    fileToServerMap.put(path3, "server3"); // old-style
+    /*
+     * Test nameToFileMap:
+     * uuid1 -> /dir1/server1/uuid1
+     * uuid3 -> /dir3/server3/uuid3
+     */
+    Map<String,Path> nameToFileMap = new java.util.HashMap<String,Path>();
+    nameToFileMap.put(UUID1, path1);
+    nameToFileMap.put(UUID3, path3);
+
+    /**
+     * Expected map:
+     * server1 -> [ /dir1/server1/uuid1 ]
+     * server3 -> [ /dir3/server3/uuid3 ]
+     */
+    Map<String,ArrayList<Path>> result = GarbageCollectWriteAheadLogs.mapServersToFiles(fileToServerMap, nameToFileMap);
+    assertEquals(2, result.size());
+    ArrayList<Path> list1 = result.get("server1");
+    assertEquals(1, list1.size());
+    assertTrue(list1.contains(path1));
+    ArrayList<Path> list3 = result.get("server3");
+    assertEquals(1, list3.size());
+    assertTrue(list3.contains(path3));
+  }
+
+  private FileStatus makeFileStatus(int size, Path path) {
+    boolean isDir = (size == 0);
+    return new FileStatus(size, isDir, 3, BLOCK_SIZE, modTime, path);
+  }
+  private void mockListStatus(Path dir, FileStatus... fileStatuses) throws Exception {
+    expect(volMgr.listStatus(dir)).andReturn(fileStatuses);
+  }
+
+  @Test
+  public void testScanServers_NewStyle() throws Exception {
+    String[] walDirs = new String[] {"/dir1", "/dir2", "/dir3"};
+    /*
+     * Test directory layout:
+     * /dir1/
+     *   server1/
+     *     uuid1
+     *     file2
+     *   subdir2/
+     * /dir2/ missing
+     * /dir3/
+     *   server3/
+     *     uuid3
+     */
+    Path serverDir1Path = new Path(DIR_1_PATH, "server1");
+    FileStatus serverDir1 = makeFileStatus(0, serverDir1Path);
+    Path subDir2Path = new Path(DIR_1_PATH, "subdir2");
+    FileStatus serverDir2 = makeFileStatus(0, subDir2Path);
+    mockListStatus(DIR_1_PATH, serverDir1, serverDir2);
+    Path path1 = new Path(serverDir1Path, UUID1);
+    FileStatus file1 = makeFileStatus(100, path1);
+    FileStatus file2 = makeFileStatus(200, new Path(serverDir1Path, "file2"));
+    mockListStatus(serverDir1Path, file1, file2);
+    mockListStatus(subDir2Path);
+    expect(volMgr.listStatus(DIR_2_PATH)).andThrow(new FileNotFoundException());
+    Path serverDir3Path = new Path(DIR_3_PATH, "server3");
+    FileStatus serverDir3 = makeFileStatus(0, serverDir3Path);
+    mockListStatus(DIR_3_PATH, serverDir3);
+    Path path3 = new Path(serverDir3Path, UUID3);
+    FileStatus file3 = makeFileStatus(300, path3);
+    mockListStatus(serverDir3Path, file3);
+    replay(volMgr);
+
+    Map<Path,String> fileToServerMap = new java.util.HashMap<Path,String>();
+    Map<String,Path> nameToFileMap = new java.util.HashMap<String,Path>();
+    int count = gcwal.scanServers(walDirs, fileToServerMap, nameToFileMap);
+    assertEquals(3, count);
+    /*
+     * Expected fileToServerMap:
+     * /dir1/server1/uuid1 -> server1
+     * /dir3/server3/uuid3 -> server3
+     */
+    assertEquals(2, fileToServerMap.size());
+    assertEquals("server1", fileToServerMap.get(path1));
+    assertEquals("server3", fileToServerMap.get(path3));
+    /*
+     * Expected nameToFileMap:
+     * uuid1 -> /dir1/server1/uuid1
+     * uuid3 -> /dir3/server3/uuid3
+     */
+    assertEquals(2, nameToFileMap.size());
+    assertEquals(path1, nameToFileMap.get(UUID1));
+    assertEquals(path3, nameToFileMap.get(UUID3));
+  }
+
+  @Test
+  public void testScanServers_OldStyle() throws Exception {
+    /*
+     * Test directory layout:
+     * /dir1/
+     *   uuid1
+     * /dir3/
+     *   uuid3
+     */
+    String[] walDirs = new String[] {"/dir1", "/dir3"};
+    Path serverFile1Path = new Path(DIR_1_PATH, UUID1);
+    FileStatus serverFile1 = makeFileStatus(100, serverFile1Path);
+    mockListStatus(DIR_1_PATH, serverFile1);
+    Path serverFile3Path = new Path(DIR_3_PATH, UUID3);
+    FileStatus serverFile3 = makeFileStatus(300, serverFile3Path);
+    mockListStatus(DIR_3_PATH, serverFile3);
+    replay(volMgr);
+
+    Map<Path,String> fileToServerMap = new java.util.HashMap<Path,String>();
+    Map<String,Path> nameToFileMap = new java.util.HashMap<String,Path>();
+    int count = gcwal.scanServers(walDirs, fileToServerMap, nameToFileMap);
+    /*
+     * Expected fileToServerMap:
+     * /dir1/uuid1 -> ""
+     * /dir3/uuid3 -> ""
+     */
+    assertEquals(2, count);
+    assertEquals(2, fileToServerMap.size());
+    assertEquals("", fileToServerMap.get(serverFile1Path));
+    assertEquals("", fileToServerMap.get(serverFile3Path));
+    /*
+     * Expected nameToFileMap: empty
+     */
+    assertEquals(0, nameToFileMap.size());
+  }
+
+  @Test
+  public void testGetSortedWALogs() throws Exception {
+    String[] recoveryDirs = new String[] {"/dir1", "/dir2", "/dir3"};
+    /*
+     * Test directory layout:
+     * /dir1/
+     *   uuid1
+     *   file2
+     * /dir2/ missing
+     * /dir3/
+     *   uuid3
+     */
+    expect(volMgr.exists(DIR_1_PATH)).andReturn(true);
+    expect(volMgr.exists(DIR_2_PATH)).andReturn(false);
+    expect(volMgr.exists(DIR_3_PATH)).andReturn(true);
+    Path path1 = new Path(DIR_1_PATH, UUID1);
+    FileStatus file1 = makeFileStatus(100, path1);
+    FileStatus file2 = makeFileStatus(200, new Path(DIR_1_PATH, "file2"));
+    mockListStatus(DIR_1_PATH, file1, file2);
+    Path path3 = new Path(DIR_3_PATH, UUID3);
+    FileStatus file3 = makeFileStatus(300, path3);
+    mockListStatus(DIR_3_PATH, file3);
+    replay(volMgr);
+
+    Map<String,Path> sortedWalogs = gcwal.getSortedWALogs(recoveryDirs);
+    /**
+     * Expected map:
+     * uuid1 -> /dir1/uuid1
+     * uuid3 -> /dir3/uuid3
+     */
+    assertEquals(2, sortedWalogs.size());
+    assertEquals(path1, sortedWalogs.get(UUID1));
+    assertEquals(path3, sortedWalogs.get(UUID3));
+  }
+
+  @Test
+  public void testIsUUID() {
+    assertTrue(GarbageCollectWriteAheadLogs.isUUID(UUID.randomUUID().toString()));
+    assertFalse(GarbageCollectWriteAheadLogs.isUUID("foo"));
+    assertFalse(GarbageCollectWriteAheadLogs.isUUID("0" + UUID.randomUUID().toString()));
+    assertFalse(GarbageCollectWriteAheadLogs.isUUID(null));
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/88f24d23/server/gc/src/test/java/org/apache/accumulo/gc/SimpleGarbageCollectorOptsTest.java
----------------------------------------------------------------------
diff --git a/server/gc/src/test/java/org/apache/accumulo/gc/SimpleGarbageCollectorOptsTest.java b/server/gc/src/test/java/org/apache/accumulo/gc/SimpleGarbageCollectorOptsTest.java
new file mode 100644
index 0000000..d484741
--- /dev/null
+++ b/server/gc/src/test/java/org/apache/accumulo/gc/SimpleGarbageCollectorOptsTest.java
@@ -0,0 +1,37 @@
+/*
+ * 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.accumulo.gc;
+
+import org.apache.accumulo.gc.SimpleGarbageCollector.Opts;
+import org.junit.Before;
+import org.junit.Test;
+import static org.junit.Assert.assertFalse;
+
+public class SimpleGarbageCollectorOptsTest {
+  private Opts opts;
+
+  @Before
+  public void setUp() {
+    opts = new Opts();
+  }
+
+  @Test
+  public void testIt() {
+    assertFalse(opts.verbose);
+    assertFalse(opts.safeMode);
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/88f24d23/server/gc/src/test/java/org/apache/accumulo/gc/SimpleGarbageCollectorTest.java
----------------------------------------------------------------------
diff --git a/server/gc/src/test/java/org/apache/accumulo/gc/SimpleGarbageCollectorTest.java b/server/gc/src/test/java/org/apache/accumulo/gc/SimpleGarbageCollectorTest.java
new file mode 100644
index 0000000..532eeba
--- /dev/null
+++ b/server/gc/src/test/java/org/apache/accumulo/gc/SimpleGarbageCollectorTest.java
@@ -0,0 +1,146 @@
+/*
+ * 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.accumulo.gc;
+
+import java.io.FileNotFoundException;
+import org.apache.accumulo.core.client.Instance;
+import org.apache.accumulo.core.conf.AccumuloConfiguration;
+import org.apache.accumulo.core.conf.Property;
+import org.apache.accumulo.core.security.Credentials;
+import org.apache.accumulo.core.security.thrift.TCredentials;
+import org.apache.accumulo.gc.SimpleGarbageCollector.Opts;
+import static org.apache.accumulo.gc.SimpleGarbageCollector.CANDIDATE_MEMORY_PERCENTAGE;
+import org.apache.accumulo.server.fs.VolumeManager;
+import org.apache.accumulo.trace.thrift.TInfo;
+import org.apache.hadoop.fs.Path;
+import org.junit.Before;
+import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.expectLastCall;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+
+public class SimpleGarbageCollectorTest {
+  private VolumeManager volMgr;
+  private Instance instance;
+  private Credentials credentials;
+  private Opts opts;
+  private SimpleGarbageCollector gc;
+  private AccumuloConfiguration systemConfig;
+
+  @Before
+  public void setUp() {
+    volMgr = createMock(VolumeManager.class);
+    instance = createMock(Instance.class);
+    credentials = createMock(Credentials.class);
+
+    opts = new Opts();
+    gc = new SimpleGarbageCollector(opts);
+    systemConfig = mockSystemConfig();
+  }
+
+  @Test
+  public void testConstruction() {
+    assertSame(opts, gc.getOpts());
+    assertNotNull(gc.getStatus(createMock(TInfo.class), createMock(TCredentials.class)));
+  }
+
+  private AccumuloConfiguration mockSystemConfig() {
+    AccumuloConfiguration systemConfig = createMock(AccumuloConfiguration.class);
+    expect(systemConfig.getTimeInMillis(Property.GC_CYCLE_START)).andReturn(1000L);
+    expect(systemConfig.getTimeInMillis(Property.GC_CYCLE_DELAY)).andReturn(20000L);
+    expect(systemConfig.getCount(Property.GC_DELETE_THREADS)).andReturn(2);
+    replay(systemConfig);
+    return systemConfig;
+  }
+
+  @Test
+  public void testInit() throws Exception {
+    gc.init(volMgr, instance, credentials, false, systemConfig);
+    assertSame(volMgr, gc.getVolumeManager());
+    assertSame(instance, gc.getInstance());
+    assertSame(credentials, gc.getCredentials());
+    assertTrue(gc.isUsingTrash());
+    assertEquals(1000L, gc.getStartDelay());
+    assertEquals(2, gc.getNumDeleteThreads());
+  }
+
+  @Test
+  public void testMoveToTrash_UsingTrash() throws Exception {
+    gc.init(volMgr, instance, credentials, false, systemConfig);
+    Path path = createMock(Path.class);
+    expect(volMgr.moveToTrash(path)).andReturn(true);
+    replay(volMgr);
+    assertTrue(gc.moveToTrash(path));
+    verify(volMgr);
+  }
+
+  @Test
+  public void testMoveToTrash_UsingTrash_VolMgrFailure() throws Exception {
+    gc.init(volMgr, instance, credentials, false, systemConfig);
+    Path path = createMock(Path.class);
+    expect(volMgr.moveToTrash(path)).andThrow(new FileNotFoundException());
+    replay(volMgr);
+    assertFalse(gc.moveToTrash(path));
+    verify(volMgr);
+  }
+
+  @Test
+  public void testMoveToTrash_NotUsingTrash() throws Exception {
+    gc.init(volMgr, instance, credentials, true, systemConfig);
+    Path path = createMock(Path.class);
+    assertFalse(gc.moveToTrash(path));
+  }
+
+  @Test
+  public void testAlmostOutOfMemory_Pass() {
+    testAlmostOutOfMemory(1.0f - (CANDIDATE_MEMORY_PERCENTAGE - 0.05f), false);
+  }
+
+  @Test
+  public void testAlmostOutOfMemory_Fail() {
+    testAlmostOutOfMemory(1.0f - (CANDIDATE_MEMORY_PERCENTAGE + 0.05f), true);
+  }
+
+  private void testAlmostOutOfMemory(float freeFactor, boolean expected) {
+    Runtime runtime = createMock(Runtime.class);
+    expect(runtime.totalMemory()).andReturn(1000L);
+    expectLastCall().anyTimes();
+    expect(runtime.maxMemory()).andReturn(1000L);
+    expectLastCall().anyTimes();
+    expect(runtime.freeMemory()).andReturn((long) (freeFactor * 1000.0f));
+    expectLastCall().anyTimes();
+    replay(runtime);
+
+    assertEquals(expected, SimpleGarbageCollector.almostOutOfMemory(runtime));
+  }
+
+  @Test
+  public void testIsDir() {
+    assertTrue(SimpleGarbageCollector.isDir("/dir1"));
+    assertFalse(SimpleGarbageCollector.isDir("file1"));
+    assertFalse(SimpleGarbageCollector.isDir("/dir1/file1"));
+    assertFalse(SimpleGarbageCollector.isDir(""));
+    assertFalse(SimpleGarbageCollector.isDir(null));
+  }
+}


[29/53] [abbrv] Revert "ACCUMULO-1897 Move shell into new package and module"

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/OfflineCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/OfflineCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/OfflineCommand.java
new file mode 100644
index 0000000..fde4514
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/OfflineCommand.java
@@ -0,0 +1,61 @@
+/*
+ * 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.accumulo.core.util.shell.commands;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.core.metadata.MetadataTable;
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+
+public class OfflineCommand extends TableOperation {
+  
+  private boolean wait;
+  private Option waitOpt;
+  
+  @Override
+  public String description() {
+    return "starts the process of taking table offline";
+  }
+  
+  protected void doTableOp(final Shell shellState, final String tableName) throws AccumuloException, AccumuloSecurityException, TableNotFoundException {
+    if (tableName.equals(MetadataTable.NAME)) {
+      Shell.log.info("  You cannot take the " + MetadataTable.NAME + " offline.");
+    } else {
+      shellState.getConnector().tableOperations().offline(tableName, wait);
+      Shell.log.info("Offline of table " + tableName + (wait ? " completed." : " initiated..."));
+    }
+  }
+  
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    wait = cl.hasOption(waitOpt.getLongOpt());
+    return super.execute(fullCommand, cl, shellState);
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options opts = super.getOptions();
+    waitOpt = new Option("w", "wait", false, "wait for offline to finish");
+    opts.addOption(waitOpt); 
+    return opts;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/OnlineCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/OnlineCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/OnlineCommand.java
new file mode 100644
index 0000000..7b6ebe2
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/OnlineCommand.java
@@ -0,0 +1,61 @@
+/*
+ * 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.accumulo.core.util.shell.commands;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.core.metadata.RootTable;
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+
+public class OnlineCommand extends TableOperation {
+  
+  private boolean wait;
+  private Option waitOpt;
+  
+  @Override
+  public String description() {
+    return "starts the process of putting a table online";
+  }
+  
+  @Override
+  protected void doTableOp(final Shell shellState, final String tableName) throws AccumuloException, AccumuloSecurityException, TableNotFoundException {
+    if (tableName.equals(RootTable.NAME)) {
+      Shell.log.info("  The " + RootTable.NAME + " is always online.");
+    } else {
+      shellState.getConnector().tableOperations().online(tableName, wait);
+      Shell.log.info("Online of table " + tableName + (wait ? " completed." : " initiated..."));
+    }
+  }
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    wait = cl.hasOption(waitOpt.getLongOpt());
+    return super.execute(fullCommand, cl, shellState);
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options opts = super.getOptions();
+    waitOpt = new Option("w", "wait", false, "wait for online to finish");
+    opts.addOption(waitOpt); 
+    return opts;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/OptUtil.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/OptUtil.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/OptUtil.java
new file mode 100644
index 0000000..9915bdf
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/OptUtil.java
@@ -0,0 +1,146 @@
+/*
+ * 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.accumulo.core.util.shell.commands;
+
+import java.io.UnsupportedEncodingException;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.NamespaceNotFoundException;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.OptionGroup;
+import org.apache.hadoop.io.Text;
+
+public abstract class OptUtil {
+  public static final String START_ROW_OPT = "b";
+  public static final String END_ROW_OPT = "e";
+
+  public static String getTableOpt(final CommandLine cl, final Shell shellState) throws TableNotFoundException {
+    String tableName;
+
+    if (cl.hasOption(Shell.tableOption)) {
+      tableName = cl.getOptionValue(Shell.tableOption);
+      if (!shellState.getConnector().tableOperations().exists(tableName)) {
+        throw new TableNotFoundException(tableName, tableName, "specified table that doesn't exist");
+      }
+    } else {
+      shellState.checkTableState();
+      tableName = shellState.getTableName();
+    }
+
+    return tableName;
+  }
+
+  public static String getNamespaceOpt(final CommandLine cl, final Shell shellState) throws NamespaceNotFoundException, AccumuloException,
+      AccumuloSecurityException {
+    String namespace = null;
+    if (cl.hasOption(Shell.namespaceOption)) {
+      namespace = cl.getOptionValue(Shell.namespaceOption);
+      if (!shellState.getConnector().namespaceOperations().exists(namespace)) {
+        throw new NamespaceNotFoundException(namespace, namespace, "specified namespace that doesn't exist");
+      }
+    } else {
+      throw new NamespaceNotFoundException(null, null, "no namespace specified");
+    }
+    return namespace;
+  }
+
+  public static Option tableOpt() {
+    return tableOpt("tableName");
+  }
+
+  public static Option tableOpt(final String description) {
+    final Option tableOpt = new Option(Shell.tableOption, "table", true, description);
+    tableOpt.setArgName("table");
+    tableOpt.setRequired(false);
+    return tableOpt;
+  }
+
+  public static Option namespaceOpt() {
+    return namespaceOpt("namespace");
+  }
+
+  public static Option namespaceOpt(final String description) {
+    final Option namespaceOpt = new Option(Shell.namespaceOption, "namespace", true, description);
+    namespaceOpt.setArgName("namespace");
+    namespaceOpt.setRequired(false);
+    return namespaceOpt;
+  }
+
+  public static enum AdlOpt {
+    ADD("a"), DELETE("d"), LIST("l");
+
+    public final String opt;
+
+    private AdlOpt(String opt) {
+      this.opt = opt;
+    }
+  }
+
+  public static AdlOpt getAldOpt(final CommandLine cl) {
+    if (cl.hasOption(AdlOpt.ADD.opt)) {
+      return AdlOpt.ADD;
+    } else if (cl.hasOption(AdlOpt.DELETE.opt)) {
+      return AdlOpt.DELETE;
+    } else {
+      return AdlOpt.LIST;
+    }
+  }
+
+  public static OptionGroup addListDeleteGroup(final String name) {
+    final Option addOpt = new Option(AdlOpt.ADD.opt, "add", false, "add " + name);
+    final Option deleteOpt = new Option(AdlOpt.DELETE.opt, "delete", false, "delete " + name);
+    final Option listOpt = new Option(AdlOpt.LIST.opt, "list", false, "list " + name + "(s)");
+    final OptionGroup og = new OptionGroup();
+    og.addOption(addOpt);
+    og.addOption(deleteOpt);
+    og.addOption(listOpt);
+    og.setRequired(true);
+    return og;
+  }
+
+  public static Option startRowOpt() {
+    final Option o = new Option(START_ROW_OPT, "begin-row", true, "begin row (inclusive)");
+    o.setArgName("begin-row");
+    return o;
+  }
+
+  public static Option endRowOpt() {
+    final Option o = new Option(END_ROW_OPT, "end-row", true, "end row (inclusive)");
+    o.setArgName("end-row");
+    return o;
+  }
+
+  public static Text getStartRow(final CommandLine cl) throws UnsupportedEncodingException {
+    if (cl.hasOption(START_ROW_OPT)) {
+      return new Text(cl.getOptionValue(START_ROW_OPT).getBytes(Shell.CHARSET));
+    } else {
+      return null;
+    }
+  }
+
+  public static Text getEndRow(final CommandLine cl) throws UnsupportedEncodingException {
+    if (cl.hasOption(END_ROW_OPT)) {
+      return new Text(cl.getOptionValue(END_ROW_OPT).getBytes(Shell.CHARSET));
+    } else {
+      return null;
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/PasswdCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/PasswdCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/PasswdCommand.java
new file mode 100644
index 0000000..86446a2
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/PasswdCommand.java
@@ -0,0 +1,96 @@
+/*
+ * 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.accumulo.core.util.shell.commands;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.impl.thrift.SecurityErrorCode;
+import org.apache.accumulo.core.client.security.tokens.PasswordToken;
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.core.util.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+
+public class PasswdCommand extends Command {
+  private Option userOpt;
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException, IOException {
+    final String currentUser = shellState.getConnector().whoami();
+    final String user = cl.getOptionValue(userOpt.getOpt(), currentUser);
+    
+    String password = null;
+    String passwordConfirm = null;
+    String oldPassword = null;
+    
+    oldPassword = shellState.readMaskedLine("Enter current password for '" + currentUser + "': ", '*');
+    if (oldPassword == null) {
+      shellState.getReader().println();
+      return 0;
+    } // user canceled
+    
+    if (!shellState.getConnector().securityOperations().authenticateUser(currentUser, new PasswordToken(oldPassword)))
+      throw new AccumuloSecurityException(user, SecurityErrorCode.BAD_CREDENTIALS);
+    
+    password = shellState.readMaskedLine("Enter new password for '" + user + "': ", '*');
+    if (password == null) {
+      shellState.getReader().println();
+      return 0;
+    } // user canceled
+    passwordConfirm = shellState.readMaskedLine("Please confirm new password for '" + user + "': ", '*');
+    if (passwordConfirm == null) {
+      shellState.getReader().println();
+      return 0;
+    } // user canceled
+    
+    if (!password.equals(passwordConfirm)) {
+      throw new IllegalArgumentException("Passwords do not match");
+    }
+    byte[] pass = password.getBytes(StandardCharsets.UTF_8);
+    shellState.getConnector().securityOperations().changeLocalUserPassword(user, new PasswordToken(pass));
+    // update the current credentials if the password changed was for
+    // the current user
+    if (shellState.getConnector().whoami().equals(user)) {
+      shellState.updateUser(user, new PasswordToken(pass));
+    }
+    Shell.log.debug("Changed password for user " + user);
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "changes a user's password";
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+    userOpt = new Option(Shell.userOption, "user", true, "user to operate on");
+    userOpt.setArgName("user");
+    o.addOption(userOpt);
+    return o;
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/PingCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/PingCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/PingCommand.java
new file mode 100644
index 0000000..d0eb615
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/PingCommand.java
@@ -0,0 +1,82 @@
+/*
+ * 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.accumulo.core.util.shell.commands;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.accumulo.core.client.admin.InstanceOperations;
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.core.util.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+
+/**
+ * 
+ */
+public class PingCommand extends Command {
+  
+  private Option tserverOption, disablePaginationOpt;
+  
+  @Override
+  public String description() {
+    return "ping tablet servers";
+  }
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    
+    List<String> tservers;
+    
+    final InstanceOperations instanceOps = shellState.getConnector().instanceOperations();
+    
+    final boolean paginate = !cl.hasOption(disablePaginationOpt.getOpt());
+    
+    if (cl.hasOption(tserverOption.getOpt())) {
+      tservers = new ArrayList<String>();
+      tservers.add(cl.getOptionValue(tserverOption.getOpt()));
+    } else {
+      tservers = instanceOps.getTabletServers();
+    }
+    
+    shellState.printLines(new PingIterator(tservers, instanceOps), paginate);
+    
+    return 0;
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options opts = new Options();
+    
+    tserverOption = new Option("ts", "tabletServer", true, "tablet server to ping");
+    tserverOption.setArgName("tablet server");
+    opts.addOption(tserverOption);
+    
+    disablePaginationOpt = new Option("np", "no-pagination", false, "disable pagination of output");
+    opts.addOption(disablePaginationOpt);
+    
+    return opts;
+  }
+  
+}
+

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/PingIterator.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/PingIterator.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/PingIterator.java
new file mode 100644
index 0000000..2a1020e
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/PingIterator.java
@@ -0,0 +1,58 @@
+/*
+ * 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.accumulo.core.util.shell.commands;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.admin.InstanceOperations;
+
+class PingIterator implements Iterator<String> {
+  
+  private Iterator<String> iter;
+  private InstanceOperations instanceOps;
+
+  PingIterator(List<String> tservers, InstanceOperations instanceOps) {
+    iter = tservers.iterator();
+    this.instanceOps = instanceOps;
+  }
+  
+  @Override
+  public boolean hasNext() {
+    return iter.hasNext();
+  }
+  
+  @Override
+  public String next() {
+    String tserver = iter.next();
+    
+    try {
+      instanceOps.ping(tserver);
+    } catch (AccumuloException e) {
+      return tserver + " ERROR " + e.getMessage();
+    }
+    
+    return tserver + " OK";
+  }
+  
+  @Override
+  public void remove() {
+    throw new UnsupportedOperationException();
+  }
+  
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/QuestionCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/QuestionCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/QuestionCommand.java
new file mode 100644
index 0000000..b12c2cb
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/QuestionCommand.java
@@ -0,0 +1,24 @@
+/*
+ * 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.accumulo.core.util.shell.commands;
+
+public class QuestionCommand extends HelpCommand {
+  @Override
+  public String getName() {
+    return "?";
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/QuitCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/QuitCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/QuitCommand.java
new file mode 100644
index 0000000..8aa95f5
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/QuitCommand.java
@@ -0,0 +1,19 @@
+/*
+ * 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.accumulo.core.util.shell.commands;
+
+public class QuitCommand extends ExitCommand {}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/QuotedStringTokenizer.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/QuotedStringTokenizer.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/QuotedStringTokenizer.java
new file mode 100644
index 0000000..76ebb8f
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/QuotedStringTokenizer.java
@@ -0,0 +1,141 @@
+/*
+ * 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.accumulo.core.util.shell.commands;
+
+import java.io.UnsupportedEncodingException;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Iterator;
+
+import org.apache.accumulo.core.util.BadArgumentException;
+import org.apache.accumulo.core.util.shell.Shell;
+
+/**
+ * A basic tokenizer for generating tokens from a string. It understands quoted strings and escaped quote characters.
+ * 
+ * You can use the escape sequence '\' to escape single quotes, double quotes, and spaces only, in addition to the escape character itself.
+ * 
+ * The behavior is the same for single and double quoted strings. (i.e. '\'' is the same as "\'")
+ */
+
+public class QuotedStringTokenizer implements Iterable<String> {
+  private ArrayList<String> tokens;
+  private String input;
+  
+  public QuotedStringTokenizer(final String t) throws BadArgumentException {
+    tokens = new ArrayList<String>();
+    this.input = t;
+    try {
+      createTokens();
+    } catch (UnsupportedEncodingException e) {
+      throw new IllegalArgumentException(e.getMessage());
+    }
+  }
+  
+  public String[] getTokens() {
+    return tokens.toArray(new String[tokens.size()]);
+  }
+  
+  private void createTokens() throws BadArgumentException, UnsupportedEncodingException {
+    boolean inQuote = false;
+    boolean inEscapeSequence = false;
+    String hexChars = null;
+    char inQuoteChar = '"';
+    
+    final byte[] token = new byte[input.length()];
+    int tokenLength = 0;
+    final byte[] inputBytes = input.getBytes(StandardCharsets.UTF_8);
+    for (int i = 0; i < input.length(); ++i) {
+      final char ch = input.charAt(i);
+      
+      // if I ended up in an escape sequence, check for valid escapable character, and add it as a literal
+      if (inEscapeSequence) {
+        inEscapeSequence = false;
+        if (ch == 'x') {
+          hexChars = "";
+        } else if (ch == ' ' || ch == '\'' || ch == '"' || ch == '\\') {
+          token[tokenLength++] = inputBytes[i];
+        } else {
+          throw new BadArgumentException("can only escape single quotes, double quotes, the space character, the backslash, and hex input", input, i);
+        }
+      }
+      // in a hex escape sequence
+      else if (hexChars != null) {
+        final int digit = Character.digit(ch, 16);
+        if (digit < 0) {
+          throw new BadArgumentException("expected hex character", input, i);
+        }
+        hexChars += ch;
+        if (hexChars.length() == 2) {
+          byte b;
+          try {
+            b = (byte) (0xff & Short.parseShort(hexChars, 16));
+            if (!Character.isValidCodePoint(0xff & b))
+              throw new NumberFormatException();
+          } catch (NumberFormatException e) {
+            throw new BadArgumentException("unsupported non-ascii character", input, i);
+          }
+          token[tokenLength++] = b;
+          hexChars = null;
+        }
+      }
+      // in a quote, either end the quote, start escape, or continue a token
+      else if (inQuote) {
+        if (ch == inQuoteChar) {
+          inQuote = false;
+          tokens.add(new String(token, 0, tokenLength, Shell.CHARSET));
+          tokenLength = 0;
+        } else if (ch == '\\') {
+          inEscapeSequence = true;
+        } else {
+          token[tokenLength++] = inputBytes[i];
+        }
+      }
+      // not in a quote, either enter a quote, end a token, start escape, or continue a token
+      else {
+        if (ch == '\'' || ch == '"') {
+          if (tokenLength > 0) {
+            tokens.add(new String(token, 0, tokenLength, Shell.CHARSET));
+            tokenLength = 0;
+          }
+          inQuote = true;
+          inQuoteChar = ch;
+        } else if (ch == ' ' && tokenLength > 0) {
+          tokens.add(new String(token, 0, tokenLength, Shell.CHARSET));
+          tokenLength = 0;
+        } else if (ch == '\\') {
+          inEscapeSequence = true;
+        } else if (ch != ' ') {
+          token[tokenLength++] = inputBytes[i];
+        }
+      }
+    }
+    if (inQuote) {
+      throw new BadArgumentException("missing terminating quote", input, input.length());
+    } else if (inEscapeSequence || hexChars != null) {
+      throw new BadArgumentException("escape sequence not complete", input, input.length());
+    }
+    if (tokenLength > 0) {
+      tokens.add(new String(token, 0, tokenLength, Shell.CHARSET));
+    }
+  }
+  
+  @Override
+  public Iterator<String> iterator() {
+    return tokens.iterator();
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/RenameNamespaceCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/RenameNamespaceCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/RenameNamespaceCommand.java
new file mode 100644
index 0000000..d7ff7c3
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/RenameNamespaceCommand.java
@@ -0,0 +1,79 @@
+/*
+ * 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.accumulo.core.util.shell.commands;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.NamespaceExistsException;
+import org.apache.accumulo.core.client.NamespaceNotFoundException;
+import org.apache.accumulo.core.client.TableExistsException;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.core.client.impl.Namespaces;
+import org.apache.accumulo.core.client.impl.Tables;
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.core.util.shell.Shell.Command;
+import org.apache.accumulo.core.util.shell.Token;
+import org.apache.commons.cli.CommandLine;
+
+public class RenameNamespaceCommand extends Command {
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException,
+      TableNotFoundException, TableExistsException, NamespaceNotFoundException, NamespaceExistsException {
+    String old = cl.getArgs()[0];
+    String newer = cl.getArgs()[1];
+    boolean resetContext = false;
+    String currentTableId = "";
+    if (!(shellState.getTableName() == null) && !shellState.getTableName().isEmpty()) {
+      String namespaceId = Namespaces.getNamespaceId(shellState.getInstance(), old);
+      List<String> tableIds = Namespaces.getTableIds(shellState.getInstance(), namespaceId);
+      currentTableId = Tables.getTableId(shellState.getInstance(), shellState.getTableName());
+      resetContext = tableIds.contains(currentTableId);
+    }
+
+    shellState.getConnector().namespaceOperations().rename(old, newer);
+
+    if (resetContext) {
+      shellState.setTableName(Tables.getTableName(shellState.getInstance(), currentTableId));
+    }
+
+    return 0;
+  }
+
+  @Override
+  public String usage() {
+    return getName() + " <current namespace> <new namespace>";
+  }
+
+  @Override
+  public String description() {
+    return "renames a namespace";
+  }
+
+  @Override
+  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> special) {
+    registerCompletionForNamespaces(root, special);
+  }
+
+  @Override
+  public int numArgs() {
+    return 2;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/RenameTableCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/RenameTableCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/RenameTableCommand.java
new file mode 100644
index 0000000..38d8158
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/RenameTableCommand.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.accumulo.core.util.shell.commands;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.TableExistsException;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.core.client.impl.Tables;
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.core.util.shell.Shell.Command;
+import org.apache.accumulo.core.util.shell.Token;
+import org.apache.commons.cli.CommandLine;
+
+public class RenameTableCommand extends Command {
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException,
+      TableNotFoundException, TableExistsException {
+    shellState.getConnector().tableOperations().rename(cl.getArgs()[0], cl.getArgs()[1]);
+    if (shellState.getTableName().equals(Tables.qualified(cl.getArgs()[0]))) {
+      shellState.setTableName(cl.getArgs()[1]);
+    }
+    return 0;
+  }
+
+  @Override
+  public String usage() {
+    return getName() + " <current table name> <new table name>";
+  }
+
+  @Override
+  public String description() {
+    return "renames a table";
+  }
+
+  @Override
+  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> completionSet) {
+    registerCompletionForTables(root, completionSet);
+  }
+
+  @Override
+  public int numArgs() {
+    return 2;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/RevokeCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/RevokeCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/RevokeCommand.java
new file mode 100644
index 0000000..dac864d
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/RevokeCommand.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.accumulo.core.util.shell.commands;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.accumulo.core.security.NamespacePermission;
+import org.apache.accumulo.core.security.SystemPermission;
+import org.apache.accumulo.core.security.TablePermission;
+import org.apache.accumulo.core.util.BadArgumentException;
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.core.util.shell.Shell.Command;
+import org.apache.accumulo.core.util.shell.Token;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.OptionGroup;
+import org.apache.commons.cli.Options;
+
+public class RevokeCommand extends TableOperation {
+  {
+    disableUnflaggedTableOptions();
+  }
+
+  private Option systemOpt, userOpt;
+  private String user;
+  private String[] permission;
+
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    user = cl.hasOption(userOpt.getOpt()) ? cl.getOptionValue(userOpt.getOpt()) : shellState.getConnector().whoami();
+
+    permission = cl.getArgs()[0].split("\\.", 2);
+    if (cl.hasOption(systemOpt.getOpt()) && permission[0].equalsIgnoreCase("System")) {
+      try {
+        shellState.getConnector().securityOperations().revokeSystemPermission(user, SystemPermission.valueOf(permission[1]));
+        Shell.log.debug("Revoked from " + user + " the " + permission[1] + " permission");
+      } catch (IllegalArgumentException e) {
+        throw new BadArgumentException("No such system permission", fullCommand, fullCommand.indexOf(cl.getArgs()[0]));
+      }
+    } else if (permission[0].equalsIgnoreCase("Table")) {
+      super.execute(fullCommand, cl, shellState);
+    } else if (permission[0].equalsIgnoreCase("Namespace")) {
+      if (cl.hasOption(optNamespace.getOpt())) {
+        try {
+          shellState.getConnector().securityOperations()
+              .revokeNamespacePermission(user, cl.getOptionValue(optNamespace.getOpt()), NamespacePermission.valueOf(permission[1]));
+        } catch (IllegalArgumentException e) {
+          throw new BadArgumentException("No such namespace permission", fullCommand, fullCommand.indexOf(cl.getArgs()[0]));
+        }
+      } else {
+        throw new BadArgumentException("No namespace specified to apply permission to", fullCommand, fullCommand.indexOf(cl.getArgs()[0]));
+      }
+    } else {
+      throw new BadArgumentException("Unrecognized permission", fullCommand, fullCommand.indexOf(cl.getArgs()[0]));
+    }
+    return 0;
+  }
+
+  @Override
+  protected void doTableOp(final Shell shellState, final String tableName) throws Exception {
+    try {
+      shellState.getConnector().securityOperations().revokeTablePermission(user, tableName, TablePermission.valueOf(permission[1]));
+      Shell.log.debug("Revoked from " + user + " the " + permission[1] + " permission on table " + tableName);
+    } catch (IllegalArgumentException e) {
+      throw new IllegalArgumentException("No such table permission", e);
+    }
+  }
+
+  @Override
+  public String description() {
+    return "revokes system or table permissions from a user";
+  }
+
+  @Override
+  public String usage() {
+    return getName() + " <permission>";
+  }
+
+  @Override
+  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> completionSet) {
+    final Token cmd = new Token(getName());
+    cmd.addSubcommand(new Token(TablePermission.printableValues()));
+    cmd.addSubcommand(new Token(SystemPermission.printableValues()));
+    cmd.addSubcommand(new Token(NamespacePermission.printableValues()));
+    root.addSubcommand(cmd);
+  }
+
+  @Override
+  public Options getOptions() {
+    super.getOptions();
+    final Options o = new Options();
+
+    final OptionGroup group = new OptionGroup();
+
+    systemOpt = new Option("s", "system", false, "revoke a system permission");
+
+    optNamespace = new Option(Shell.namespaceOption, "namespace", true, "name of a namespace to operate on");
+    optNamespace.setArgName("namespace");
+
+    group.addOption(systemOpt);
+    group.addOption(optTableName);
+    group.addOption(optTablePattern);
+    group.addOption(optNamespace);
+
+    o.addOptionGroup(group);
+    userOpt = new Option(Shell.userOption, "user", true, "user to operate on");
+    userOpt.setArgName("username");
+    userOpt.setRequired(true);
+    o.addOption(userOpt);
+
+    return o;
+  }
+
+  @Override
+  public int numArgs() {
+    return 1;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ScanCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ScanCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ScanCommand.java
new file mode 100644
index 0000000..f3a0663
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ScanCommand.java
@@ -0,0 +1,334 @@
+/*
+ * 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.accumulo.core.util.shell.commands;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.util.List;
+import java.util.Map.Entry;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.IteratorSetting;
+import org.apache.accumulo.core.client.Scanner;
+import org.apache.accumulo.core.client.ScannerBase;
+import org.apache.accumulo.core.conf.AccumuloConfiguration;
+import org.apache.accumulo.core.data.Key;
+import org.apache.accumulo.core.data.Range;
+import org.apache.accumulo.core.data.Value;
+import org.apache.accumulo.core.security.Authorizations;
+import org.apache.accumulo.core.util.format.BinaryFormatter;
+import org.apache.accumulo.core.util.format.Formatter;
+import org.apache.accumulo.core.util.interpret.DefaultScanInterpreter;
+import org.apache.accumulo.core.util.interpret.ScanInterpreter;
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.core.util.shell.Shell.Command;
+import org.apache.accumulo.core.util.shell.Shell.PrintFile;
+import org.apache.accumulo.start.classloader.vfs.AccumuloVFSClassLoader;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+import org.apache.hadoop.io.Text;
+
+public class ScanCommand extends Command {
+  
+  private Option scanOptAuths, scanOptRow, scanOptColumns, disablePaginationOpt, showFewOpt, formatterOpt, interpreterOpt, formatterInterpeterOpt,
+      outputFileOpt;
+  
+  protected Option timestampOpt;
+  private Option optStartRowExclusive;
+  private Option optEndRowExclusive;
+  private Option timeoutOption;
+  private Option profileOpt;
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    final PrintFile printFile = getOutputFile(cl);
+    final String tableName = OptUtil.getTableOpt(cl, shellState);
+    
+    final Class<? extends Formatter> formatter = getFormatter(cl, tableName, shellState);
+    final ScanInterpreter interpeter = getInterpreter(cl, tableName, shellState);
+    
+    // handle first argument, if present, the authorizations list to
+    // scan with
+    final Authorizations auths = getAuths(cl, shellState);
+    final Scanner scanner = shellState.getConnector().createScanner(tableName, auths);
+    
+    // handle session-specific scan iterators
+    addScanIterators(shellState, cl, scanner, tableName);
+    
+    // handle remaining optional arguments
+    scanner.setRange(getRange(cl, interpeter));
+    
+    // handle columns
+    fetchColumns(cl, scanner, interpeter);
+    
+    // set timeout
+    scanner.setTimeout(getTimeout(cl), TimeUnit.MILLISECONDS);
+    
+    // output the records
+    if (cl.hasOption(showFewOpt.getOpt())) {
+      final String showLength = cl.getOptionValue(showFewOpt.getOpt());
+      try {
+        final int length = Integer.parseInt(showLength);
+        if (length < 1) {
+          throw new IllegalArgumentException();
+        }
+        BinaryFormatter.getlength(length);
+        printBinaryRecords(cl, shellState, scanner, printFile);
+      } catch (NumberFormatException nfe) {
+        shellState.getReader().println("Arg must be an integer.");
+      } catch (IllegalArgumentException iae) {
+        shellState.getReader().println("Arg must be greater than one.");
+      }
+      
+    } else {
+      printRecords(cl, shellState, scanner, formatter, printFile);
+    }
+    if (printFile != null) {
+      printFile.close();
+    }
+    
+    return 0;
+  }
+  
+  protected long getTimeout(final CommandLine cl) {
+    if (cl.hasOption(timeoutOption.getLongOpt())) {
+      return AccumuloConfiguration.getTimeInMillis(cl.getOptionValue(timeoutOption.getLongOpt()));
+    }
+    
+    return Long.MAX_VALUE;
+  }
+  
+  protected void addScanIterators(final Shell shellState, CommandLine cl, final Scanner scanner, final String tableName) {
+    
+    List<IteratorSetting> tableScanIterators;
+    if (cl.hasOption(profileOpt.getOpt())) {
+      String profile = cl.getOptionValue(profileOpt.getOpt());
+      tableScanIterators = shellState.iteratorProfiles.get(profile);
+      
+      if (tableScanIterators == null) {
+        throw new IllegalArgumentException("Profile " + profile + " does not exist");
+      }
+    } else {
+      tableScanIterators = shellState.scanIteratorOptions.get(tableName);
+      if (tableScanIterators == null) {
+        Shell.log.debug("Found no scan iterators to set");
+        return;
+      }
+    }
+    
+    Shell.log.debug("Found " + tableScanIterators.size() + " scan iterators to set");
+    
+    for (IteratorSetting setting : tableScanIterators) {
+      Shell.log.debug("Setting scan iterator " + setting.getName() + " at priority " + setting.getPriority() + " using class name "
+          + setting.getIteratorClass());
+      for (Entry<String,String> option : setting.getOptions().entrySet()) {
+        Shell.log.debug("Setting option for " + setting.getName() + ": " + option.getKey() + "=" + option.getValue());
+      }
+      scanner.addScanIterator(setting);
+    }
+  }
+  
+  protected void printRecords(final CommandLine cl, final Shell shellState, final Iterable<Entry<Key,Value>> scanner, final Class<? extends Formatter> formatter)
+      throws IOException {
+    printRecords(cl, shellState, scanner, formatter, null);
+  }
+  
+  protected void printRecords(final CommandLine cl, final Shell shellState, final Iterable<Entry<Key,Value>> scanner,
+      final Class<? extends Formatter> formatter, PrintFile outFile) throws IOException {
+    if (outFile == null) {
+      shellState.printRecords(scanner, cl.hasOption(timestampOpt.getOpt()), !cl.hasOption(disablePaginationOpt.getOpt()), formatter);
+    } else {
+      shellState.printRecords(scanner, cl.hasOption(timestampOpt.getOpt()), !cl.hasOption(disablePaginationOpt.getOpt()), formatter, outFile);
+    }
+  }
+  
+  protected void printBinaryRecords(final CommandLine cl, final Shell shellState, final Iterable<Entry<Key,Value>> scanner) throws IOException {
+    printBinaryRecords(cl, shellState, scanner, null);
+  }
+  
+  protected void printBinaryRecords(final CommandLine cl, final Shell shellState, final Iterable<Entry<Key,Value>> scanner, PrintFile outFile)
+      throws IOException {
+    if (outFile == null) {
+      shellState.printBinaryRecords(scanner, cl.hasOption(timestampOpt.getOpt()), !cl.hasOption(disablePaginationOpt.getOpt()));
+    } else {
+      shellState.printBinaryRecords(scanner, cl.hasOption(timestampOpt.getOpt()), !cl.hasOption(disablePaginationOpt.getOpt()), outFile);
+    }
+  }
+  
+  protected ScanInterpreter getInterpreter(final CommandLine cl, final String tableName, final Shell shellState) throws Exception {
+    
+    Class<? extends ScanInterpreter> clazz = null;
+    try {
+      if (cl.hasOption(interpreterOpt.getOpt())) {
+        clazz = AccumuloVFSClassLoader.loadClass(cl.getOptionValue(interpreterOpt.getOpt()), ScanInterpreter.class);
+      } else if (cl.hasOption(formatterInterpeterOpt.getOpt())) {
+        clazz = AccumuloVFSClassLoader.loadClass(cl.getOptionValue(formatterInterpeterOpt.getOpt()), ScanInterpreter.class);
+      }
+    } catch (ClassNotFoundException e) {
+      shellState.getReader().println("Interpreter class could not be loaded.\n" + e.getMessage());
+    }
+    
+    if (clazz == null)
+      clazz = InterpreterCommand.getCurrentInterpreter(tableName, shellState);
+    
+    if (clazz == null)
+      clazz = DefaultScanInterpreter.class;
+    
+    return clazz.newInstance();
+  }
+  
+  protected Class<? extends Formatter> getFormatter(final CommandLine cl, final String tableName, final Shell shellState) throws IOException {
+    
+    try {
+      if (cl.hasOption(formatterOpt.getOpt())) {
+        return AccumuloVFSClassLoader.loadClass(cl.getOptionValue(formatterOpt.getOpt()), Formatter.class);
+        
+      } else if (cl.hasOption(formatterInterpeterOpt.getOpt())) {
+        return AccumuloVFSClassLoader.loadClass(cl.getOptionValue(formatterInterpeterOpt.getOpt()), Formatter.class);
+      }
+    } catch (ClassNotFoundException e) {
+      shellState.getReader().println("Formatter class could not be loaded.\n" + e.getMessage());
+    }
+    
+    return shellState.getFormatter(tableName);
+  }
+  
+  protected void fetchColumns(final CommandLine cl, final ScannerBase scanner, final ScanInterpreter formatter) throws UnsupportedEncodingException {
+    if (cl.hasOption(scanOptColumns.getOpt())) {
+      for (String a : cl.getOptionValue(scanOptColumns.getOpt()).split(",")) {
+        final String sa[] = a.split(":", 2);
+        if (sa.length == 1) {
+          scanner.fetchColumnFamily(formatter.interpretColumnFamily(new Text(a.getBytes(Shell.CHARSET))));
+        } else {
+          scanner.fetchColumn(formatter.interpretColumnFamily(new Text(sa[0].getBytes(Shell.CHARSET))),
+              formatter.interpretColumnQualifier(new Text(sa[1].getBytes(Shell.CHARSET))));
+        }
+      }
+    }
+  }
+  
+  protected Range getRange(final CommandLine cl, final ScanInterpreter formatter) throws UnsupportedEncodingException {
+    if ((cl.hasOption(OptUtil.START_ROW_OPT) || cl.hasOption(OptUtil.END_ROW_OPT)) && cl.hasOption(scanOptRow.getOpt())) {
+      // did not see a way to make commons cli do this check... it has mutually exclusive options but does not support the or
+      throw new IllegalArgumentException("Options -" + scanOptRow.getOpt() + " AND (-" + OptUtil.START_ROW_OPT + " OR -" + OptUtil.END_ROW_OPT
+          + ") are mutally exclusive ");
+    }
+    
+    if (cl.hasOption(scanOptRow.getOpt())) {
+      return new Range(formatter.interpretRow(new Text(cl.getOptionValue(scanOptRow.getOpt()).getBytes(Shell.CHARSET))));
+    } else {
+      Text startRow = OptUtil.getStartRow(cl);
+      if (startRow != null)
+        startRow = formatter.interpretBeginRow(startRow);
+      Text endRow = OptUtil.getEndRow(cl);
+      if (endRow != null)
+        endRow = formatter.interpretEndRow(endRow);
+      final boolean startInclusive = !cl.hasOption(optStartRowExclusive.getOpt());
+      final boolean endInclusive = !cl.hasOption(optEndRowExclusive.getOpt());
+      return new Range(startRow, startInclusive, endRow, endInclusive);
+    }
+  }
+  
+  protected Authorizations getAuths(final CommandLine cl, final Shell shellState) throws AccumuloSecurityException, AccumuloException {
+    final String user = shellState.getConnector().whoami();
+    Authorizations auths = shellState.getConnector().securityOperations().getUserAuthorizations(user);
+    if (cl.hasOption(scanOptAuths.getOpt())) {
+      auths = ScanCommand.parseAuthorizations(cl.getOptionValue(scanOptAuths.getOpt()));
+    }
+    return auths;
+  }
+  
+  static Authorizations parseAuthorizations(final String field) {
+    if (field == null || field.isEmpty()) {
+      return Authorizations.EMPTY;
+    }
+    return new Authorizations(field.split(","));
+  }
+  
+  @Override
+  public String description() {
+    return "scans the table, and displays the resulting records";
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+    
+    scanOptAuths = new Option("s", "scan-authorizations", true, "scan authorizations (all user auths are used if this argument is not specified)");
+    optStartRowExclusive = new Option("be", "begin-exclusive", false, "make start row exclusive (by default it's inclusive)");
+    optStartRowExclusive.setArgName("begin-exclusive");
+    optEndRowExclusive = new Option("ee", "end-exclusive", false, "make end row exclusive (by default it's inclusive)");
+    optEndRowExclusive.setArgName("end-exclusive");
+    scanOptRow = new Option("r", "row", true, "row to scan");
+    scanOptColumns = new Option("c", "columns", true, "comma-separated columns");
+    timestampOpt = new Option("st", "show-timestamps", false, "display timestamps");
+    disablePaginationOpt = new Option("np", "no-pagination", false, "disable pagination of output");
+    showFewOpt = new Option("f", "show few", true, "show only a specified number of characters");
+    formatterOpt = new Option("fm", "formatter", true, "fully qualified name of the formatter class to use");
+    interpreterOpt = new Option("i", "interpreter", true, "fully qualified name of the interpreter class to use");
+    formatterInterpeterOpt = new Option("fi", "fmt-interpreter", true, "fully qualified name of a class that is a formatter and interpreter");
+    timeoutOption = new Option(null, "timeout", true,
+        "time before scan should fail if no data is returned. If no unit is given assumes seconds.  Units d,h,m,s,and ms are supported.  e.g. 30s or 100ms");
+    outputFileOpt = new Option("o", "output", true, "local file to write the scan output to");
+    
+    scanOptAuths.setArgName("comma-separated-authorizations");
+    scanOptRow.setArgName("row");
+    scanOptColumns.setArgName("<columnfamily>[:<columnqualifier>]{,<columnfamily>[:<columnqualifier>]}");
+    showFewOpt.setRequired(false);
+    showFewOpt.setArgName("int");
+    formatterOpt.setArgName("className");
+    timeoutOption.setArgName("timeout");
+    outputFileOpt.setArgName("file");
+    
+    profileOpt = new Option("pn", "profile", true, "iterator profile name");
+    profileOpt.setArgName("profile");
+    
+    o.addOption(scanOptAuths);
+    o.addOption(scanOptRow);
+    o.addOption(OptUtil.startRowOpt());
+    o.addOption(OptUtil.endRowOpt());
+    o.addOption(optStartRowExclusive);
+    o.addOption(optEndRowExclusive);
+    o.addOption(scanOptColumns);
+    o.addOption(timestampOpt);
+    o.addOption(disablePaginationOpt);
+    o.addOption(OptUtil.tableOpt("table to be scanned"));
+    o.addOption(showFewOpt);
+    o.addOption(formatterOpt);
+    o.addOption(interpreterOpt);
+    o.addOption(formatterInterpeterOpt);
+    o.addOption(timeoutOption);
+    o.addOption(outputFileOpt);
+    o.addOption(profileOpt);
+    
+    return o;
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+  
+  protected PrintFile getOutputFile(final CommandLine cl) throws FileNotFoundException {
+    final String outputFile = cl.getOptionValue(outputFileOpt.getOpt());
+    return (outputFile == null ? null : new PrintFile(outputFile));
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ScriptCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ScriptCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ScriptCommand.java
new file mode 100644
index 0000000..5a0eee0
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ScriptCommand.java
@@ -0,0 +1,290 @@
+/*
+ * 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.accumulo.core.util.shell.commands;
+
+import java.io.File;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.Reader;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+
+import javax.script.Bindings;
+import javax.script.Compilable;
+import javax.script.CompiledScript;
+import javax.script.Invocable;
+import javax.script.ScriptContext;
+import javax.script.ScriptEngine;
+import javax.script.ScriptEngineFactory;
+import javax.script.ScriptEngineManager;
+import javax.script.ScriptException;
+import javax.script.SimpleScriptContext;
+
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.core.util.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.OptionGroup;
+import org.apache.commons.cli.Options;
+
+public class ScriptCommand extends Command {
+  
+  // Command to allow user to run scripts, see JSR-223
+  // http://www.oracle.com/technetwork/articles/javase/scripting-140262.html
+  
+  protected Option list, engine, script, file, args, out, function, object;
+  private static final String DEFAULT_ENGINE = "rhino";
+  
+  public int execute(String fullCommand, CommandLine cl, Shell shellState) throws Exception {
+
+    boolean invoke = false;
+    ScriptEngineManager mgr = new ScriptEngineManager();
+    
+    if (cl.hasOption(list.getOpt())) {
+      listJSREngineInfo(mgr, shellState);
+    } else if (cl.hasOption(file.getOpt()) || cl.hasOption(script.getOpt())) {
+      String engineName = DEFAULT_ENGINE;
+      if (cl.hasOption(engine.getOpt())) {
+        engineName = cl.getOptionValue(engine.getOpt());
+      }
+      ScriptEngine engine = mgr.getEngineByName(engineName);
+      if (null == engine) {
+        shellState.printException(new Exception(engineName + " not found"));
+        return 1;
+      }
+      
+      if (cl.hasOption(object.getOpt()) || cl.hasOption(function.getOpt())) {
+        if (!(engine instanceof Invocable)) {
+          shellState.printException(new Exception(engineName + " does not support invoking functions or methods"));
+          return 1;
+        }
+        invoke = true;
+      }
+      
+      ScriptContext ctx = new SimpleScriptContext();
+      
+      // Put the following objects into the context so that they
+      // are available to the scripts
+      // TODO: What else should go in here?
+      Bindings b = engine.getBindings(ScriptContext.ENGINE_SCOPE);
+      b.put("connection", shellState.getConnector());
+      
+      List<Object> argValues = new ArrayList<Object>();
+      if (cl.hasOption(args.getOpt())) {
+        String[] argList = cl.getOptionValue(args.getOpt()).split(",");
+        for (String arg : argList) {
+          String[] parts = arg.split("=");
+          if (parts.length == 0) {
+            continue;
+          } else if (parts.length == 1) {
+            b.put(parts[0], null);
+            argValues.add(null);
+          } else if (parts.length == 2) {
+            b.put(parts[0], parts[1]);
+            argValues.add(parts[1]);
+          }
+        }
+      }
+      ctx.setBindings(b, ScriptContext.ENGINE_SCOPE);
+      Object[] argArray = argValues.toArray(new Object[argValues.size()]);
+      
+      Writer writer = null;
+      if (cl.hasOption(out.getOpt())) {
+        File f = new File(cl.getOptionValue(out.getOpt()));
+        writer = new FileWriter(f);
+        ctx.setWriter(writer);
+      }
+      
+      if (cl.hasOption(file.getOpt())) {
+        File f = new File(cl.getOptionValue(file.getOpt()));
+        if (!f.exists()) {
+          if (null != writer) {
+            writer.close();
+          }
+          shellState.printException(new Exception(f.getAbsolutePath() + " not found"));
+          return 1;
+        }
+        Reader reader = new FileReader(f);
+        try {
+          engine.eval(reader, ctx);
+          if (invoke) {
+            this.invokeFunctionOrMethod(shellState, engine, cl, argArray);
+          }
+        } catch (ScriptException ex) {
+          shellState.printException(ex);
+          return 1;
+        } finally {
+          reader.close();
+          if (null != writer) {
+            writer.close();
+          }
+        }
+      } else if (cl.hasOption(script.getOpt())) {
+        String inlineScript = cl.getOptionValue(script.getOpt());
+        try {
+          if (engine instanceof Compilable) {
+            Compilable compiledEng = (Compilable) engine;
+            CompiledScript script = compiledEng.compile(inlineScript);
+            script.eval(ctx);
+            if (invoke) {
+              this.invokeFunctionOrMethod(shellState, engine, cl, argArray);
+            }
+          } else {
+            engine.eval(inlineScript, ctx);
+            if (invoke) {
+              this.invokeFunctionOrMethod(shellState, engine, cl, argArray);
+            }
+          }
+        } catch (ScriptException ex) {
+          shellState.printException(ex);
+          return 1;
+        } finally {
+          if (null != writer) {
+            writer.close();
+          }
+        }
+      }
+      if (null != writer) {
+        writer.close();
+      }
+      
+    } else {
+      printHelp(shellState);
+    }
+    return 0;
+  }
+  
+  public String description() {
+    return "execute JSR-223 scripts";
+  }
+  
+  public int numArgs() {
+    return 0;
+  }
+  
+  @Override
+  public String getName() {
+    return "script";
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+    
+    engine = new Option("e", "engine", false, "engine name, defaults to JDK default (Rhino)");
+    engine.setArgName("engineName");
+    engine.setArgs(1);
+    engine.setRequired(false);
+    o.addOption(engine);
+    
+    OptionGroup inputGroup = new OptionGroup();
+    list = new Option("l", "list", false, "list available script engines");
+    inputGroup.addOption(list);
+
+    script = new Option("s", "script", true, "use inline script");
+    script.setArgName("script text");
+    script.setArgs(1);
+    script.setRequired(false);
+    inputGroup.addOption(script);
+    
+    file = new Option("f", "file", true, "use script file");
+    file.setArgName("fileName");
+    file.setArgs(1);
+    file.setRequired(false);
+    
+    inputGroup.addOption(file);
+    inputGroup.setRequired(true);
+    o.addOptionGroup(inputGroup);
+    
+    OptionGroup invokeGroup = new OptionGroup();
+    object = new Option("obj", "object", true, "name of object");
+    object.setArgs(1);
+    object.setArgName("objectName:methodName");
+    object.setRequired(false);
+    invokeGroup.addOption(object);
+    
+    function = new Option("fx", "function", true, "invoke a script function");
+    function.setArgName("functionName");
+    function.setArgs(1);
+    function.setRequired(false);
+    invokeGroup.addOption(function);
+    invokeGroup.setRequired(false);
+    o.addOptionGroup(invokeGroup);
+    
+    args = new Option("a", "args", true, "comma separated list of key=value arguments");
+    args.setArgName("property1=value1,propert2=value2,...");
+    args.setArgs(Option.UNLIMITED_VALUES);
+    args.setRequired(false);
+    o.addOption(args);
+    
+    out = new Option("o", "output", true, "output file");
+    out.setArgName("fileName");
+    out.setArgs(1);
+    out.setRequired(false);
+    o.addOption(out);
+    
+    return o;
+  }
+  
+  private void listJSREngineInfo(ScriptEngineManager mgr, Shell shellState) throws IOException {
+    List<ScriptEngineFactory> factories = mgr.getEngineFactories();
+    Set<String> lines = new TreeSet<String>();
+    for (ScriptEngineFactory factory : factories) {
+      lines.add("ScriptEngineFactory Info");
+      String engName = factory.getEngineName();
+      String engVersion = factory.getEngineVersion();
+      String langName = factory.getLanguageName();
+      String langVersion = factory.getLanguageVersion();
+      lines.add("\tScript Engine: " + engName + " (" + engVersion + ")");
+      List<String> engNames = factory.getNames();
+      for (String name : engNames) {
+        lines.add("\tEngine Alias: " + name);
+      }
+      lines.add("\tLanguage: " + langName + " (" + langVersion + ")");
+    }
+    shellState.printLines(lines.iterator(), true);
+    
+  }
+  
+  private void invokeFunctionOrMethod(Shell shellState, ScriptEngine engine, CommandLine cl, Object[] args) {
+    try {
+      Invocable inv = (Invocable) engine;
+      if (cl.hasOption(function.getOpt())) {
+        inv.invokeFunction(cl.getOptionValue(function.getOpt()), args);
+      } else if (cl.hasOption(object.getOpt())) {
+        String objectMethod = cl.getOptionValue(object.getOpt());
+        String[] parts = objectMethod.split(":");
+        if (!(parts.length == 2)) {
+          shellState.printException(new Exception("Object and Method must be supplied"));
+          return;
+        }
+        String objectName = parts[0];
+        String methodName = parts[1];
+        Object obj = engine.get(objectName);
+        inv.invokeMethod(obj, methodName, args);
+        
+      }
+    } catch (Exception e) {
+      shellState.printException(e);
+    }
+  }
+  
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SetAuthsCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SetAuthsCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SetAuthsCommand.java
new file mode 100644
index 0000000..256720c
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SetAuthsCommand.java
@@ -0,0 +1,77 @@
+/*
+ * 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.accumulo.core.util.shell.commands;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.core.util.shell.Shell.Command;
+import org.apache.accumulo.core.util.shell.Token;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.OptionGroup;
+import org.apache.commons.cli.Options;
+
+public class SetAuthsCommand extends Command {
+  private Option userOpt;
+  private Option scanOptAuths;
+  private Option clearOptAuths;
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException {
+    final String user = cl.getOptionValue(userOpt.getOpt(), shellState.getConnector().whoami());
+    final String scanOpts = cl.hasOption(clearOptAuths.getOpt()) ? null : cl.getOptionValue(scanOptAuths.getOpt());
+    shellState.getConnector().securityOperations().changeUserAuthorizations(user, ScanCommand.parseAuthorizations(scanOpts));
+    Shell.log.debug("Changed record-level authorizations for user " + user);
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "sets the maximum scan authorizations for a user";
+  }
+  
+  @Override
+  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> completionSet) {
+    registerCompletionForUsers(root, completionSet);
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+    final OptionGroup setOrClear = new OptionGroup();
+    scanOptAuths = new Option("s", "scan-authorizations", true, "scan authorizations to set");
+    scanOptAuths.setArgName("comma-separated-authorizations");
+    setOrClear.addOption(scanOptAuths);
+    clearOptAuths = new Option("c", "clear-authorizations", false, "clear the scan authorizations");
+    setOrClear.addOption(clearOptAuths);
+    setOrClear.setRequired(true);
+    o.addOptionGroup(setOrClear);
+    userOpt = new Option(Shell.userOption, "user", true, "user to operate on");
+    userOpt.setArgName("user");
+    o.addOption(userOpt);
+    return o;
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SetGroupsCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SetGroupsCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SetGroupsCommand.java
new file mode 100644
index 0000000..157dbd2
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SetGroupsCommand.java
@@ -0,0 +1,78 @@
+/*
+ * 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.accumulo.core.util.shell.commands;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.core.util.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Options;
+import org.apache.hadoop.io.Text;
+
+public class SetGroupsCommand extends Command {
+  @Override
+  public String description() {
+    return "sets the locality groups for a given table (for binary or commas, use Java API)";
+  }
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    final String tableName = OptUtil.getTableOpt(cl, shellState);
+    
+    final HashMap<String,Set<Text>> groups = new HashMap<String,Set<Text>>();
+    
+    for (String arg : cl.getArgs()) {
+      final String sa[] = arg.split("=", 2);
+      if (sa.length < 2) {
+        throw new IllegalArgumentException("Missing '='");
+      }
+      final String group = sa[0];
+      final HashSet<Text> colFams = new HashSet<Text>();
+      
+      for (String family : sa[1].split(",")) {
+        colFams.add(new Text(family.getBytes(Shell.CHARSET)));
+      }
+      
+      groups.put(group, colFams);
+    }
+    
+    shellState.getConnector().tableOperations().setLocalityGroups(tableName, groups);
+    
+    return 0;
+  }
+  
+  @Override
+  public int numArgs() {
+    return Shell.NO_FIXED_ARG_LENGTH_CHECK;
+  }
+  
+  @Override
+  public String usage() {
+    return getName() + " <group>=<col fam>{,<col fam>}{ <group>=<col fam>{,<col fam>}}";
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options opts = new Options();
+    opts.addOption(OptUtil.tableOpt("table to fetch locality groups for"));
+    return opts;
+  }
+  
+}


[27/53] [abbrv] Revert "ACCUMULO-1897 Move shell into new package and module"

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/test/java/org/apache/accumulo/core/util/shell/ShellConfigTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/accumulo/core/util/shell/ShellConfigTest.java b/core/src/test/java/org/apache/accumulo/core/util/shell/ShellConfigTest.java
new file mode 100644
index 0000000..43d2e12
--- /dev/null
+++ b/core/src/test/java/org/apache/accumulo/core/util/shell/ShellConfigTest.java
@@ -0,0 +1,90 @@
+/*
+ * 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.accumulo.core.util.shell;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.io.FileDescriptor;
+import java.io.FileInputStream;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+
+import jline.console.ConsoleReader;
+
+import org.apache.accumulo.core.client.security.tokens.PasswordToken;
+import org.apache.accumulo.core.util.shell.ShellTest.TestOutputStream;
+import org.apache.log4j.Level;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.beust.jcommander.ParameterException;
+
+public class ShellConfigTest {
+  TestOutputStream output;
+  Shell shell;
+  PrintStream out;
+  
+  @Before
+  public void setUp() throws Exception {
+    Shell.log.setLevel(Level.ERROR);
+    
+    out = System.out;
+    output = new TestOutputStream();
+    System.setOut(new PrintStream(output));
+
+    shell = new Shell(new ConsoleReader(new FileInputStream(FileDescriptor.in), output), new PrintWriter(output));
+    shell.setLogErrorsToConsole();
+  }
+  
+  @After
+  public void teardown() throws Exception {
+    shell.shutdown();
+    output.clear();
+    System.setOut(out);
+  }
+  
+  @Test
+  public void testHelp() {
+    assertTrue(shell.config("--help"));
+    assertTrue("Did not print usage", output.get().startsWith("Usage"));
+  }
+  
+  @Test
+  public void testBadArg() {
+    assertTrue(shell.config("--bogus"));
+    assertTrue("Did not print usage", output.get().startsWith("Usage"));
+  }
+  
+  @Test
+  public void testToken() {
+    assertTrue(shell.config("--fake", "-tc", PasswordToken.class.getCanonicalName()));
+    assertTrue(output.get().contains(ParameterException.class.getCanonicalName()));
+  }
+  
+  @Test
+  public void testTokenAndOption() {
+    assertFalse(shell.config("--fake", "-tc", PasswordToken.class.getCanonicalName(), "-u", "foo", "-l", "password=foo"));
+  }
+  
+  @Test
+  public void testTokenAndOptionAndPassword() {
+    assertTrue(shell.config("--fake", "-tc", PasswordToken.class.getCanonicalName(), "-l", "password=foo", "-p", "bar"));
+    assertTrue(output.get().contains(ParameterException.class.getCanonicalName()));
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/test/java/org/apache/accumulo/core/util/shell/ShellSetInstanceTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/accumulo/core/util/shell/ShellSetInstanceTest.java b/core/src/test/java/org/apache/accumulo/core/util/shell/ShellSetInstanceTest.java
new file mode 100644
index 0000000..d4c0aea
--- /dev/null
+++ b/core/src/test/java/org/apache/accumulo/core/util/shell/ShellSetInstanceTest.java
@@ -0,0 +1,242 @@
+/*
+ * 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.accumulo.core.util.shell;
+
+import static org.easymock.EasyMock.anyObject;
+import static org.easymock.EasyMock.expect;
+import static org.powermock.api.easymock.PowerMock.createMock;
+import static org.powermock.api.easymock.PowerMock.expectLastCall;
+import static org.powermock.api.easymock.PowerMock.expectNew;
+import static org.powermock.api.easymock.PowerMock.mockStatic;
+import static org.powermock.api.easymock.PowerMock.replay;
+import static org.powermock.api.easymock.PowerMock.verify;
+
+import java.io.FileDescriptor;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.util.Collections;
+import java.util.List;
+import java.util.UUID;
+
+import jline.console.ConsoleReader;
+
+import org.apache.accumulo.core.client.ClientConfiguration;
+import org.apache.accumulo.core.client.ClientConfiguration.ClientProperty;
+import org.apache.accumulo.core.client.ZooKeeperInstance;
+import org.apache.accumulo.core.client.mock.MockInstance;
+import org.apache.accumulo.core.conf.AccumuloConfiguration;
+import org.apache.accumulo.core.conf.ConfigSanityCheck;
+import org.apache.accumulo.core.conf.Property;
+import org.apache.accumulo.core.conf.SiteConfiguration;
+import org.apache.accumulo.core.zookeeper.ZooUtil;
+import org.apache.hadoop.fs.Path;
+import org.apache.log4j.Level;
+import org.easymock.EasyMock;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+@RunWith(PowerMockRunner.class)
+@PrepareForTest({Shell.class, ZooUtil.class, ConfigSanityCheck.class})
+public class ShellSetInstanceTest {
+  public static class TestOutputStream extends OutputStream {
+    StringBuilder sb = new StringBuilder();
+
+    @Override
+    public void write(int b) throws IOException {
+      sb.append((char) (0xff & b));
+    }
+
+    public String get() {
+      return sb.toString();
+    }
+
+    public void clear() {
+      sb.setLength(0);
+    }
+  }
+
+  @BeforeClass
+  public static void setupClass() {
+    // This is necessary because PowerMock messes with Hadoop's ability to
+    // determine the current user (see security.UserGroupInformation).
+    System.setProperty("HADOOP_USER_NAME", "test");
+  }
+  @AfterClass
+  public static void teardownClass() {
+    System.clearProperty("HADOOP_USER_NAME");
+  }
+
+  private TestOutputStream output;
+  private Shell shell;
+
+  @Before
+  public void setup() throws IOException {
+    Shell.log.setLevel(Level.OFF);
+    output = new TestOutputStream();
+    shell = new Shell(new ConsoleReader(new FileInputStream(FileDescriptor.in), output), new PrintWriter(output));
+    shell.setLogErrorsToConsole();
+  }
+  @After
+  public void tearDown() {
+    shell.shutdown();
+    SiteConfiguration.clearInstance();
+  }
+
+  @Test
+  public void testSetInstance_Fake() throws Exception {
+    ShellOptionsJC opts = createMock(ShellOptionsJC.class);
+    expect(opts.isFake()).andReturn(true);
+    replay(opts);
+    MockInstance theInstance = createMock(MockInstance.class);
+    expectNew(MockInstance.class, "fake").andReturn(theInstance);
+    replay(theInstance, MockInstance.class);
+
+    shell.setInstance(opts);
+    verify(theInstance, MockInstance.class);
+  }
+  @Test
+  public void testSetInstance_HdfsZooInstance_Explicit() throws Exception {
+    testSetInstance_HdfsZooInstance(true, false, false);
+  }
+  @Test
+  public void testSetInstance_HdfsZooInstance_InstanceGiven() throws Exception {
+    testSetInstance_HdfsZooInstance(false, true, false);
+  }
+  @Test
+  public void testSetInstance_HdfsZooInstance_HostsGiven() throws Exception {
+    testSetInstance_HdfsZooInstance(false, false, true);
+  }
+  @Test
+  public void testSetInstance_HdfsZooInstance_Implicit() throws Exception {
+    testSetInstance_HdfsZooInstance(false, false, false);
+  }
+  
+  @SuppressWarnings("deprecation")
+  private void testSetInstance_HdfsZooInstance(boolean explicitHdfs, boolean onlyInstance, boolean onlyHosts)
+    throws Exception {
+    ClientConfiguration clientConf = createMock(ClientConfiguration.class);
+    ShellOptionsJC opts = createMock(ShellOptionsJC.class);
+    expect(opts.isFake()).andReturn(false);
+    expect(opts.getClientConfiguration()).andReturn(clientConf);
+    expect(opts.isHdfsZooInstance()).andReturn(explicitHdfs);
+    if (!explicitHdfs) {
+      expect(opts.getZooKeeperInstance())
+        .andReturn(Collections.<String>emptyList());
+      if (onlyInstance) {
+        expect(opts.getZooKeeperInstanceName()).andReturn("instance");
+        expect(clientConf.withInstance("instance")).andReturn(clientConf);
+      } else {
+        expect(opts.getZooKeeperInstanceName()).andReturn(null);
+      }
+      if (onlyHosts) {
+        expect(opts.getZooKeeperHosts()).andReturn("host3,host4");
+        expect(clientConf.withZkHosts("host3,host4")).andReturn(clientConf);
+      } else {
+        expect(opts.getZooKeeperHosts()).andReturn(null);
+      }
+    }
+    replay(opts);
+
+    if (!onlyInstance) {
+      expect(clientConf.get(ClientProperty.INSTANCE_NAME)).andReturn(null);
+    }
+
+    mockStatic(ConfigSanityCheck.class);
+    ConfigSanityCheck.validate(EasyMock.<AccumuloConfiguration>anyObject());
+    expectLastCall().atLeastOnce();
+    replay(ConfigSanityCheck.class);
+
+    if (!onlyHosts) {
+      expect(clientConf.containsKey(Property.INSTANCE_ZK_HOST.getKey())).andReturn(true).atLeastOnce();
+      expect(clientConf.getString(Property.INSTANCE_ZK_HOST.getKey())).andReturn("host1,host2").atLeastOnce();
+      expect(clientConf.withZkHosts("host1,host2")).andReturn(clientConf);
+    }
+    if (!onlyInstance) {
+      expect(clientConf.containsKey(Property.INSTANCE_VOLUMES.getKey())).andReturn(false).atLeastOnce();
+      expect(clientConf.containsKey(Property.INSTANCE_DFS_DIR.getKey())).andReturn(true).atLeastOnce();
+      expect(clientConf.containsKey(Property.INSTANCE_DFS_URI.getKey())).andReturn(true).atLeastOnce();
+      expect(clientConf.getString(Property.INSTANCE_DFS_URI.getKey())).andReturn("hdfs://nn1").atLeastOnce();
+      expect(clientConf.getString(Property.INSTANCE_DFS_DIR.getKey())).andReturn("/dfs").atLeastOnce();
+    }
+
+    UUID randomUUID = null;
+    if (!onlyInstance) {
+      mockStatic(ZooUtil.class);
+      randomUUID = UUID.randomUUID();
+      expect(ZooUtil.getInstanceIDFromHdfs(anyObject(Path.class), anyObject(AccumuloConfiguration.class)))
+        .andReturn(randomUUID.toString());
+      replay(ZooUtil.class);
+      expect(clientConf.withInstance(randomUUID)).andReturn(clientConf);
+    }
+    replay(clientConf);
+
+    ZooKeeperInstance theInstance = createMock(ZooKeeperInstance.class);
+    
+    expectNew(ZooKeeperInstance.class, clientConf).andReturn(theInstance);
+    replay(theInstance, ZooKeeperInstance.class);
+
+    shell.setInstance(opts);
+    verify(theInstance, ZooKeeperInstance.class);
+  }
+  @Test
+  public void testSetInstance_ZKInstance_DashZ() throws Exception {
+    testSetInstance_ZKInstance(true);
+  }
+  @Test
+  public void testSetInstance_ZKInstance_DashZIandZH() throws Exception {
+    testSetInstance_ZKInstance(false);
+  }
+  private void testSetInstance_ZKInstance(boolean dashZ) throws Exception {
+    ClientConfiguration clientConf = createMock(ClientConfiguration.class);
+    ShellOptionsJC opts = createMock(ShellOptionsJC.class);
+    expect(opts.isFake()).andReturn(false);
+    expect(opts.getClientConfiguration()).andReturn(clientConf);
+    expect(opts.isHdfsZooInstance()).andReturn(false);
+    if (dashZ) {
+      expect(clientConf.withInstance("foo")).andReturn(clientConf);
+      expect(clientConf.withZkHosts("host1,host2")).andReturn(clientConf);
+      List<String> zl = new java.util.ArrayList<String>();
+      zl.add("foo");
+      zl.add("host1,host2");
+      expect(opts.getZooKeeperInstance()).andReturn(zl);
+      expectLastCall().anyTimes();
+    } else {
+      expect(clientConf.withInstance("bar")).andReturn(clientConf);
+      expect(clientConf.withZkHosts("host3,host4")).andReturn(clientConf);
+      expect(opts.getZooKeeperInstance()).andReturn(Collections.<String>emptyList());
+      expect(opts.getZooKeeperInstanceName()).andReturn("bar");
+      expect(opts.getZooKeeperHosts()).andReturn("host3,host4");
+    }
+    replay(clientConf);
+    replay(opts);
+
+    ZooKeeperInstance theInstance = createMock(ZooKeeperInstance.class);
+    expectNew(ZooKeeperInstance.class, clientConf).andReturn(theInstance);
+    replay(theInstance, ZooKeeperInstance.class);
+
+    shell.setInstance(opts);
+    verify(theInstance, ZooKeeperInstance.class);
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/test/java/org/apache/accumulo/core/util/shell/ShellTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/accumulo/core/util/shell/ShellTest.java b/core/src/test/java/org/apache/accumulo/core/util/shell/ShellTest.java
new file mode 100644
index 0000000..3d9b89e
--- /dev/null
+++ b/core/src/test/java/org/apache/accumulo/core/util/shell/ShellTest.java
@@ -0,0 +1,281 @@
+/*
+ * 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.accumulo.core.util.shell;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.TimeZone;
+
+import jline.console.ConsoleReader;
+
+import org.apache.accumulo.core.util.format.DateStringFormatter;
+import org.apache.log4j.Level;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class ShellTest {
+  public static class TestOutputStream extends OutputStream {
+    StringBuilder sb = new StringBuilder();
+
+    @Override
+    public void write(int b) throws IOException {
+      sb.append((char) (0xff & b));
+    }
+
+    public String get() {
+      return sb.toString();
+    }
+
+    public void clear() {
+      sb.setLength(0);
+    }
+  }
+
+  public static class StringInputStream extends InputStream {
+    private String source = "";
+    private int offset = 0;
+
+    @Override
+    public int read() throws IOException {
+      if (offset == source.length())
+        return '\n';
+      else
+        return source.charAt(offset++);
+    }
+
+    public void set(String other) {
+      source = other;
+      offset = 0;
+    }
+  }
+
+  private StringInputStream input;
+  private TestOutputStream output;
+  private Shell shell;
+
+  void exec(String cmd) throws IOException {
+    output.clear();
+    shell.execCommand(cmd, true, true);
+  }
+
+  void exec(String cmd, boolean expectGoodExit) throws IOException {
+    exec(cmd);
+    if (expectGoodExit)
+      assertGoodExit("", true);
+    else
+      assertBadExit("", true);
+  }
+
+  void exec(String cmd, boolean expectGoodExit, String expectString) throws IOException {
+    exec(cmd, expectGoodExit, expectString, true);
+  }
+
+  void exec(String cmd, boolean expectGoodExit, String expectString, boolean stringPresent) throws IOException {
+    exec(cmd);
+    if (expectGoodExit)
+      assertGoodExit(expectString, stringPresent);
+    else
+      assertBadExit(expectString, stringPresent);
+  }
+
+  @Before
+  public void setup() throws IOException {
+    TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
+    Shell.log.setLevel(Level.OFF);
+    output = new TestOutputStream();
+    input = new StringInputStream();
+    PrintWriter pw = new PrintWriter(new OutputStreamWriter(output));
+    shell = new Shell(new ConsoleReader(input, output), pw);
+    shell.setLogErrorsToConsole();
+    shell.config("--fake", "-u", "test", "-p", "secret");
+  }
+
+  @After
+  public void teardown() {
+    shell.shutdown();
+  }
+
+  void assertGoodExit(String s, boolean stringPresent) {
+    Shell.log.debug(output.get());
+    assertEquals(shell.getExitCode(), 0);
+    if (s.length() > 0)
+      assertEquals(s + " present in " + output.get() + " was not " + stringPresent, stringPresent, output.get().contains(s));
+  }
+
+  void assertBadExit(String s, boolean stringPresent) {
+    Shell.log.debug(output.get());
+    assertTrue(shell.getExitCode() > 0);
+    if (s.length() > 0)
+      assertEquals(s + " present in " + output.get() + " was not " + stringPresent, stringPresent, output.get().contains(s));
+    shell.resetExitCode();
+  }
+
+  @Test
+  public void aboutTest() throws IOException {
+    Shell.log.debug("Starting about test -----------------------------------");
+    exec("about", true, "Shell - Apache Accumulo Interactive Shell");
+    exec("about -v", true, "Current user:");
+    exec("about arg", false, "java.lang.IllegalArgumentException: Expected 0 arguments");
+  }
+
+  @Test
+  public void addGetSplitsTest() throws IOException {
+    Shell.log.debug("Starting addGetSplits test ----------------------------");
+    exec("addsplits arg", false, "java.lang.IllegalStateException: Not in a table context");
+    exec("createtable test", true);
+    exec("addsplits 1 \\x80", true);
+    exec("getsplits", true, "1\n\\x80");
+    exec("deletetable test -f", true, "Table: [test] has been deleted");
+  }
+
+  @Test
+  public void insertDeleteScanTest() throws IOException {
+    Shell.log.debug("Starting insertDeleteScan test ------------------------");
+    exec("insert r f q v", false, "java.lang.IllegalStateException: Not in a table context");
+    exec("delete r f q", false, "java.lang.IllegalStateException: Not in a table context");
+    exec("createtable test", true);
+    exec("insert r f q v", true);
+    exec("scan", true, "r f:q []    v");
+    exec("delete r f q", true);
+    exec("scan", true, "r f:q []    v", false);
+    exec("insert \\x90 \\xa0 \\xb0 \\xc0\\xd0\\xe0\\xf0", true);
+    exec("scan", true, "\\x90 \\xA0:\\xB0 []    \\xC0\\xD0");
+    exec("scan -f 2", true, "\\x90 \\xA0:\\xB0 []    \\xC0\\xD0");
+    exec("scan -f 2", true, "\\x90 \\xA0:\\xB0 []    \\xC0\\xD0\\xE0", false);
+    exec("scan -b \\x90 -e \\x90 -c \\xA0", true, "\\x90 \\xA0:\\xB0 []    \\xC0");
+    exec("scan -b \\x90 -e \\x90 -c \\xA0:\\xB0", true, "\\x90 \\xA0:\\xB0 []    \\xC0");
+    exec("scan -b \\x90 -be", true, "\\x90 \\xA0:\\xB0 []    \\xC0", false);
+    exec("scan -e \\x90 -ee", true, "\\x90 \\xA0:\\xB0 []    \\xC0", false);
+    exec("scan -b \\x90\\x00", true, "\\x90 \\xA0:\\xB0 []    \\xC0", false);
+    exec("scan -e \\x8f", true, "\\x90 \\xA0:\\xB0 []    \\xC0", false);
+    exec("delete \\x90 \\xa0 \\xb0", true);
+    exec("scan", true, "\\x90 \\xA0:\\xB0 []    \\xC0", false);
+    exec("deletetable test -f", true, "Table: [test] has been deleted");
+  }
+
+  @Test
+  public void authsTest() throws Exception {
+    Shell.log.debug("Starting auths test --------------------------");
+    exec("setauths x,y,z", false, "Missing required option");
+    exec("setauths -s x,y,z -u notauser", false, "user does not exist");
+    exec("setauths -s y,z,x", true);
+    exec("getauths -u notauser", false, "user does not exist");
+    exec("getauths", true, "x,y,z");
+    exec("addauths -u notauser", false, "Missing required option");
+    exec("addauths -u notauser -s foo", false, "user does not exist");
+    exec("addauths -s a", true);
+    exec("getauths", true, "a,x,y,z");
+    exec("setauths -c", true);
+  }
+
+  @Test
+  public void userTest() throws Exception {
+    Shell.log.debug("Starting user test --------------------------");
+    // Test cannot be done via junit because createuser only prompts for password
+    // exec("createuser root", false, "user exists");
+  }
+
+  @Test
+  public void duContextTest() throws Exception {
+    Shell.log.debug("Starting du context test --------------------------");
+    exec("createtable t", true);
+    exec("du", true, "0 [t]");
+    exec("deletetable t -f", true, "Table: [t] has been deleted");
+  }
+
+  @Test
+  public void duTest() throws IOException {
+    Shell.log.debug("Starting DU test --------------------------");
+    exec("createtable t", true);
+    exec("du t", true, "0 [t]");
+    exec("deletetable t -f", true, "Table: [t] has been deleted");
+  }
+
+  @Test
+  public void duPatternTest() throws IOException {
+    Shell.log.debug("Starting DU with pattern test --------------------------");
+    exec("createtable t", true);
+    exec("createtable tt", true);
+    exec("du -p t.*", true, "0 [t, tt]");
+    exec("deletetable t -f", true, "Table: [t] has been deleted");
+    exec("deletetable tt -f", true, "Table: [tt] has been deleted");
+  }
+
+  @Test
+  public void scanDateStringFormatterTest() throws IOException {
+    Shell.log.debug("Starting scan dateStringFormatter test --------------------------");
+    exec("createtable t", true);
+    exec("insert r f q v -ts 0", true);
+    DateFormat dateFormat = new SimpleDateFormat(DateStringFormatter.DATE_FORMAT);
+    String expected = String.format("r f:q [] %s    v", dateFormat.format(new Date(0)));
+    exec("scan -fm org.apache.accumulo.core.util.format.DateStringFormatter -st", true, expected);
+    exec("deletetable t -f", true, "Table: [t] has been deleted");
+  }
+
+  @Test
+  public void commentTest() throws IOException {
+    Shell.log.debug("Starting comment test --------------------------");
+    exec("#", true, "Unknown command", false);
+    exec("# foo", true, "Unknown command", false);
+    exec("- foo", true, "Unknown command", true);
+  }
+
+  @Test
+  public void execFileTest() throws IOException {
+    Shell.log.debug("Starting exec file test --------------------------");
+    shell.config("--fake", "-u", "test", "-p", "secret", "-f", "src/test/resources/shelltest.txt");
+    assertEquals(0, shell.start());
+    assertGoodExit("Unknown command", false);
+  }
+
+  @Test
+  public void setIterTest() throws IOException {
+    Shell.log.debug("Starting setiter test --------------------------");
+    exec("createtable t", true);
+
+    String cmdJustClass = "setiter -class VersioningIterator -p 1";
+    exec(cmdJustClass, false, "java.lang.IllegalArgumentException", false);
+    exec(cmdJustClass, false, "fully qualified package name", true);
+
+    String cmdFullPackage = "setiter -class o.a.a.foo -p 1";
+    exec(cmdFullPackage, false, "java.lang.IllegalArgumentException", false);
+    exec(cmdFullPackage, false, "class not found", true);
+
+    String cmdNoOption = "setiter -class java.lang.String -p 1";
+    exec(cmdNoOption, false, "loaded successfully but does not implement SortedKeyValueIterator", true);
+
+    input.set("\n\n");
+    exec("setiter -scan -class org.apache.accumulo.core.iterators.ColumnFamilyCounter -p 30 -name foo", true);
+    
+    input.set("bar\nname value\n");
+    exec("setiter -scan -class org.apache.accumulo.core.iterators.ColumnFamilyCounter -p 31", true);
+    
+    //TODO can't verify this as config -t fails, functionality verified in ShellServerIT
+    
+    exec("deletetable t -f", true, "Table: [t] has been deleted");
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/test/java/org/apache/accumulo/core/util/shell/ShellUtilTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/accumulo/core/util/shell/ShellUtilTest.java b/core/src/test/java/org/apache/accumulo/core/util/shell/ShellUtilTest.java
new file mode 100644
index 0000000..a5fd179
--- /dev/null
+++ b/core/src/test/java/org/apache/accumulo/core/util/shell/ShellUtilTest.java
@@ -0,0 +1,66 @@
+/*
+ * 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.accumulo.core.util.shell;
+
+import static org.junit.Assert.*;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.util.List;
+
+import org.apache.commons.codec.binary.Base64;
+import org.apache.commons.io.FileUtils;
+import org.apache.hadoop.io.Text;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+
+import com.google.common.collect.ImmutableList;
+
+public class ShellUtilTest {
+
+  @Rule
+  public TemporaryFolder folder = new TemporaryFolder(new File(System.getProperty("user.dir") + "/target"));
+
+  // String with 3 lines, with one empty line
+  private static final String FILEDATA = "line1\n\nline2";
+
+  @Test
+  public void testWithoutDecode() throws IOException {
+    File testFile = new File(folder.getRoot(), "testFileNoDecode.txt");
+    FileUtils.writeStringToFile(testFile, FILEDATA);
+    List<Text> output = ShellUtil.scanFile(testFile.getAbsolutePath(), false);
+    assertEquals(ImmutableList.of(new Text("line1"), new Text("line2")), output);
+  }
+
+  @Test
+  public void testWithDecode() throws IOException {
+    File testFile = new File(folder.getRoot(), "testFileWithDecode.txt");
+    FileUtils.writeStringToFile(testFile, FILEDATA);
+    List<Text> output = ShellUtil.scanFile(testFile.getAbsolutePath(), true);
+    assertEquals(
+        ImmutableList.of(new Text(Base64.decodeBase64("line1".getBytes(StandardCharsets.UTF_8))), new Text(Base64.decodeBase64("line2".getBytes(StandardCharsets.UTF_8)))),
+        output);
+  }
+
+  @Test(expected = FileNotFoundException.class)
+  public void testWithMissingFile() throws FileNotFoundException {
+    ShellUtil.scanFile("missingFile.txt", false);
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/test/java/org/apache/accumulo/core/util/shell/command/FormatterCommandTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/accumulo/core/util/shell/command/FormatterCommandTest.java b/core/src/test/java/org/apache/accumulo/core/util/shell/command/FormatterCommandTest.java
new file mode 100644
index 0000000..091ef75
--- /dev/null
+++ b/core/src/test/java/org/apache/accumulo/core/util/shell/command/FormatterCommandTest.java
@@ -0,0 +1,184 @@
+/*
+ * 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.accumulo.core.util.shell.command;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Iterator;
+import java.util.Map.Entry;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.TableExistsException;
+import org.apache.accumulo.core.client.mock.MockShell;
+import org.apache.accumulo.core.data.Key;
+import org.apache.accumulo.core.data.Value;
+import org.apache.accumulo.core.util.format.Formatter;
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.log4j.Level;
+import org.apache.log4j.Logger;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * Uses the MockShell to test the shell output with Formatters
+ */
+public class FormatterCommandTest {
+  ByteArrayOutputStream out = null;
+  InputStream in = null;
+  
+  @Test
+  public void test() throws IOException, AccumuloException, AccumuloSecurityException, TableExistsException, ClassNotFoundException {
+    // Keep the Shell AUDIT log off the test output
+    Logger.getLogger(Shell.class).setLevel(Level.WARN);
+    
+    final String[] args = new String[] {"--fake", "-u", "root", "-p", ""};
+    
+    final String[] commands = createCommands();
+    
+    in = MockShell.makeCommands(commands);
+    out = new ByteArrayOutputStream();
+    
+    final MockShell shell = new MockShell(in, out);
+    shell.config(args);
+    
+    // Can't call createtable in the shell with MockAccumulo
+    shell.getConnector().tableOperations().create("test");
+    
+    try {
+      shell.start();
+    } catch (Exception e) {
+      Assert.fail("Exception while running commands: " + e.getMessage());
+    }
+    
+    shell.getReader().flush();
+    
+    final String[] output = new String(out.toByteArray()).split("\n\r");
+    
+    boolean formatterOn = false;
+    
+    final String[] expectedDefault = new String[] {"row cf:cq []    1234abcd", "row cf1:cq1 []    9876fedc", "row2 cf:cq []    13579bdf",
+        "row2 cf1:cq []    2468ace"};
+    
+    final String[] expectedFormatted = new String[] {"row cf:cq []    0x31 0x32 0x33 0x34 0x61 0x62 0x63 0x64",
+        "row cf1:cq1 []    0x39 0x38 0x37 0x36 0x66 0x65 0x64 0x63", "row2 cf:cq []    0x31 0x33 0x35 0x37 0x39 0x62 0x64 0x66",
+        "row2 cf1:cq []    0x32 0x34 0x36 0x38 0x61 0x63 0x65"};
+    
+    int outputIndex = 0;
+    while (outputIndex < output.length) {
+      final String line = output[outputIndex];
+      
+      if (line.startsWith("root@mock-instance")) {
+        if (line.contains("formatter")) {
+          formatterOn = true;
+        }
+        
+        outputIndex++;
+      } else if (line.startsWith("row")) {
+        int expectedIndex = 0;
+        String[] comparisonData;
+        
+        // Pick the type of data we expect (formatted or default)
+        if (formatterOn) {
+          comparisonData = expectedFormatted;
+        } else {
+          comparisonData = expectedDefault;
+        }
+        
+        // Ensure each output is what we expected
+        while (expectedIndex + outputIndex < output.length && expectedIndex < expectedFormatted.length) {
+          Assert.assertEquals(comparisonData[expectedIndex].trim(), output[expectedIndex + outputIndex].trim());
+          expectedIndex++;
+        }
+        
+        outputIndex += expectedIndex;
+      }
+    }
+  }
+  
+  private String[] createCommands() {
+    return new String[] {"table test", "insert row cf cq 1234abcd", "insert row cf1 cq1 9876fedc", "insert row2 cf cq 13579bdf", "insert row2 cf1 cq 2468ace",
+        "scan", "formatter -t test -f org.apache.accumulo.core.util.shell.command.FormatterCommandTest$HexFormatter", "scan"};
+  }
+  
+  /**
+   * <p>
+   * Simple <code>Formatter</code> that will convert each character in the Value from decimal to hexadecimal. Will automatically skip over characters in the
+   * value which do not fall within the [0-9,a-f] range.
+   * </p>
+   * 
+   * <p>
+   * Example: <code>'0'</code> will be displayed as <code>'0x30'</code>
+   * </p>
+   */
+  public static class HexFormatter implements Formatter {
+    private Iterator<Entry<Key,Value>> iter = null;
+    private boolean printTs = false;
+    
+    private final static String tab = "\t";
+    private final static String newline = "\n";
+    
+    public HexFormatter() {}
+    
+    @Override
+    public boolean hasNext() {
+      return this.iter.hasNext();
+    }
+    
+    @Override
+    public String next() {
+      final Entry<Key,Value> entry = iter.next();
+      
+      String key;
+      
+      // Observe the timestamps
+      if (printTs) {
+        key = entry.getKey().toString();
+      } else {
+        key = entry.getKey().toStringNoTime();
+      }
+      
+      final Value v = entry.getValue();
+      
+      // Approximate how much space we'll need
+      final StringBuilder sb = new StringBuilder(key.length() + v.getSize() * 5);
+      
+      sb.append(key).append(tab);
+      
+      for (byte b : v.get()) {
+        if ((b >= 48 && b <= 57) || (b >= 97 || b <= 102)) {
+          sb.append(String.format("0x%x ", Integer.valueOf(b)));
+        }
+      }
+      
+      sb.append(newline);
+      
+      return sb.toString();
+    }
+    
+    @Override
+    public void remove() {}
+    
+    @Override
+    public void initialize(final Iterable<Entry<Key,Value>> scanner, final boolean printTimestamps) {
+      this.iter = scanner.iterator();
+      this.printTs = printTimestamps;
+    }
+  }
+  
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/test/resources/shelltest.txt
----------------------------------------------------------------------
diff --git a/core/src/test/resources/shelltest.txt b/core/src/test/resources/shelltest.txt
new file mode 100644
index 0000000..19b6f61
--- /dev/null
+++ b/core/src/test/resources/shelltest.txt
@@ -0,0 +1,16 @@
+# 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.
+exit
+foo

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/examples/simple/pom.xml
----------------------------------------------------------------------
diff --git a/examples/simple/pom.xml b/examples/simple/pom.xml
index 8390d01..752d952 100644
--- a/examples/simple/pom.xml
+++ b/examples/simple/pom.xml
@@ -61,10 +61,6 @@
     </dependency>
     <dependency>
       <groupId>org.apache.accumulo</groupId>
-      <artifactId>accumulo-shell</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.accumulo</groupId>
       <artifactId>accumulo-trace</artifactId>
     </dependency>
     <dependency>

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/examples/simple/src/main/java/org/apache/accumulo/examples/simple/shell/DebugCommand.java
----------------------------------------------------------------------
diff --git a/examples/simple/src/main/java/org/apache/accumulo/examples/simple/shell/DebugCommand.java b/examples/simple/src/main/java/org/apache/accumulo/examples/simple/shell/DebugCommand.java
index 6960898..cab78bd 100644
--- a/examples/simple/src/main/java/org/apache/accumulo/examples/simple/shell/DebugCommand.java
+++ b/examples/simple/src/main/java/org/apache/accumulo/examples/simple/shell/DebugCommand.java
@@ -19,8 +19,8 @@ package org.apache.accumulo.examples.simple.shell;
 import java.util.Set;
 import java.util.TreeSet;
 
-import org.apache.accumulo.shell.Shell;
-import org.apache.accumulo.shell.Shell.Command;
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.core.util.shell.Shell.Command;
 import org.apache.commons.cli.CommandLine;
 
 public class DebugCommand extends Command {

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/examples/simple/src/main/java/org/apache/accumulo/examples/simple/shell/MyAppShellExtension.java
----------------------------------------------------------------------
diff --git a/examples/simple/src/main/java/org/apache/accumulo/examples/simple/shell/MyAppShellExtension.java b/examples/simple/src/main/java/org/apache/accumulo/examples/simple/shell/MyAppShellExtension.java
index 1ba5ad3..3a22f7b 100644
--- a/examples/simple/src/main/java/org/apache/accumulo/examples/simple/shell/MyAppShellExtension.java
+++ b/examples/simple/src/main/java/org/apache/accumulo/examples/simple/shell/MyAppShellExtension.java
@@ -16,8 +16,8 @@
  */
 package org.apache.accumulo.examples.simple.shell;
 
-import org.apache.accumulo.shell.ShellExtension;
-import org.apache.accumulo.shell.Shell.Command;
+import org.apache.accumulo.core.util.shell.Shell.Command;
+import org.apache.accumulo.core.util.shell.ShellExtension;
 
 public class MyAppShellExtension extends ShellExtension {
   

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index d6a552d..a829ba3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -74,7 +74,6 @@
   <modules>
     <module>trace</module>
     <module>core</module>
-    <module>shell</module>
     <module>fate</module>
     <module>start</module>
     <module>examples/simple</module>
@@ -284,11 +283,6 @@
       </dependency>
       <dependency>
         <groupId>org.apache.accumulo</groupId>
-        <artifactId>accumulo-shell</artifactId>
-        <version>${project.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apache.accumulo</groupId>
         <artifactId>accumulo-start</artifactId>
         <version>${project.version}</version>
       </dependency>

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/server/monitor/pom.xml
----------------------------------------------------------------------
diff --git a/server/monitor/pom.xml b/server/monitor/pom.xml
index 411812c..10586f1 100644
--- a/server/monitor/pom.xml
+++ b/server/monitor/pom.xml
@@ -65,10 +65,6 @@
     </dependency>
     <dependency>
       <groupId>org.apache.accumulo</groupId>
-      <artifactId>accumulo-shell</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.accumulo</groupId>
       <artifactId>accumulo-trace</artifactId>
     </dependency>
     <dependency>

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/server/monitor/src/main/java/org/apache/accumulo/monitor/servlets/ShellServlet.java
----------------------------------------------------------------------
diff --git a/server/monitor/src/main/java/org/apache/accumulo/monitor/servlets/ShellServlet.java b/server/monitor/src/main/java/org/apache/accumulo/monitor/servlets/ShellServlet.java
index 25e9e33..1824840 100644
--- a/server/monitor/src/main/java/org/apache/accumulo/monitor/servlets/ShellServlet.java
+++ b/server/monitor/src/main/java/org/apache/accumulo/monitor/servlets/ShellServlet.java
@@ -34,7 +34,7 @@ import javax.servlet.http.HttpSession;
 
 import jline.console.ConsoleReader;
 
-import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.core.util.shell.Shell;
 
 public class ShellServlet extends BasicServlet {
   private static final long serialVersionUID = 1L;

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/pom.xml
----------------------------------------------------------------------
diff --git a/shell/pom.xml b/shell/pom.xml
deleted file mode 100644
index a5af4b8..0000000
--- a/shell/pom.xml
+++ /dev/null
@@ -1,123 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-  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.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.apache.accumulo</groupId>
-    <artifactId>accumulo-project</artifactId>
-    <version>1.7.0-SNAPSHOT</version>
-  </parent>
-  <artifactId>accumulo-shell</artifactId>
-  <name>Shell</name>
-  <description>An interactive shell for accessing Apache Accumulo via a command line interface.</description>
-  <dependencies>
-    <dependency>
-      <groupId>com.beust</groupId>
-      <artifactId>jcommander</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>com.google.guava</groupId>
-      <artifactId>guava</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>commons-cli</groupId>
-      <artifactId>commons-cli</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>commons-codec</groupId>
-      <artifactId>commons-codec</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>commons-collections</groupId>
-      <artifactId>commons-collections</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>commons-configuration</groupId>
-      <artifactId>commons-configuration</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>commons-io</groupId>
-      <artifactId>commons-io</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>commons-lang</groupId>
-      <artifactId>commons-lang</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>jline</groupId>
-      <artifactId>jline</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>log4j</groupId>
-      <artifactId>log4j</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.accumulo</groupId>
-      <artifactId>accumulo-core</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.accumulo</groupId>
-      <artifactId>accumulo-fate</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.accumulo</groupId>
-      <artifactId>accumulo-start</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.accumulo</groupId>
-      <artifactId>accumulo-trace</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.commons</groupId>
-      <artifactId>commons-vfs2</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.hadoop</groupId>
-      <artifactId>hadoop-client</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.thrift</groupId>
-      <artifactId>libthrift</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>junit</groupId>
-      <artifactId>junit</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.easymock</groupId>
-      <artifactId>easymock</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.powermock</groupId>
-      <artifactId>powermock-api-easymock</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.powermock</groupId>
-      <artifactId>powermock-core</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.powermock</groupId>
-      <artifactId>powermock-module-junit4</artifactId>
-      <scope>test</scope>
-    </dependency>
-  </dependencies>
-</project>


[05/53] [abbrv] ACCUMULO-1897 Move shell into new package and module

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteNamespaceCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteNamespaceCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteNamespaceCommand.java
new file mode 100644
index 0000000..faf1147
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteNamespaceCommand.java
@@ -0,0 +1,100 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.accumulo.core.client.NamespaceNotFoundException;
+import org.apache.accumulo.core.client.impl.Namespaces;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Token;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+
+public class DeleteNamespaceCommand extends Command {
+  private Option forceOpt;
+
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    boolean force = false;
+    boolean operate = true;
+    if (cl.hasOption(forceOpt.getOpt())) {
+      force = true;
+    }
+    String namespace = cl.getArgs()[0];
+
+    if (!force) {
+      shellState.getReader().flush();
+      String line = shellState.getReader().readLine(getName() + " { " + namespace + " } (yes|no)? ");
+      operate = line != null && (line.equalsIgnoreCase("y") || line.equalsIgnoreCase("yes"));
+    }
+    if (operate) {
+      doTableOp(shellState, namespace, force);
+    }
+    return 0;
+  }
+
+  @Override
+  public String description() {
+    return "deletes a namespace";
+  }
+
+  protected void doTableOp(final Shell shellState, final String namespace, boolean force) throws Exception {
+    boolean resetContext = false;
+    String currentTable = shellState.getTableName();
+    if (!Namespaces.getNameToIdMap(shellState.getInstance()).containsKey(namespace)) {
+      throw new NamespaceNotFoundException(null, namespace, null);
+    }
+
+    String namespaceId = Namespaces.getNamespaceId(shellState.getInstance(), namespace);
+    List<String> tables = Namespaces.getTableNames(shellState.getInstance(), namespaceId);
+    resetContext = tables.contains(currentTable);
+
+    if (force)
+      for (String table : shellState.getConnector().tableOperations().list())
+        if (table.startsWith(namespace + "."))
+          shellState.getConnector().tableOperations().delete(table);
+
+    shellState.getConnector().namespaceOperations().delete(namespace);
+    if (resetContext) {
+      shellState.setTableName("");
+    }
+  }
+
+  @Override
+  public Options getOptions() {
+    forceOpt = new Option("f", "force", false, "force deletion without prompting");
+    final Options opts = super.getOptions();
+
+    opts.addOption(forceOpt);
+    return opts;
+  }
+
+  @Override
+  public int numArgs() {
+    return 1;
+  }
+
+  @Override
+  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> special) {
+    registerCompletionForNamespaces(root, special);
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteRowsCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteRowsCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteRowsCommand.java
new file mode 100644
index 0000000..09f2938
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteRowsCommand.java
@@ -0,0 +1,65 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+import org.apache.hadoop.io.Text;
+
+public class DeleteRowsCommand extends Command {
+  private Option forceOpt;
+  private Option startRowOptExclusive;
+ 
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    final String tableName = OptUtil.getTableOpt(cl, shellState);
+    final Text startRow = OptUtil.getStartRow(cl);
+    final Text endRow = OptUtil.getEndRow(cl);
+    if (!cl.hasOption(forceOpt.getOpt()) && (startRow == null || endRow == null)) {
+      shellState.getReader().println("Not deleting unbounded range. Specify both ends, or use --force");
+      return 1;
+    }
+    shellState.getConnector().tableOperations().deleteRows(tableName, startRow, endRow);
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "deletes a range of rows in a table.  Note that rows matching the start row ARE NOT deleted, but rows matching the end row ARE deleted.";
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+    forceOpt = new Option("f", "force", false, "delete data even if start or end are not specified");
+    startRowOptExclusive = new Option(OptUtil.START_ROW_OPT, "begin-row", true, "begin row (exclusive)");
+    startRowOptExclusive.setArgName("begin-row");
+    o.addOption(startRowOptExclusive);
+    o.addOption(OptUtil.endRowOpt());
+    o.addOption(OptUtil.tableOpt("table to delete a row range from"));
+    o.addOption(forceOpt);
+    return o;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteScanIterCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteScanIterCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteScanIterCommand.java
new file mode 100644
index 0000000..f3c9823
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteScanIterCommand.java
@@ -0,0 +1,102 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.accumulo.core.client.IteratorSetting;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.OptionGroup;
+import org.apache.commons.cli.Options;
+
+public class DeleteScanIterCommand extends Command {
+  private Option nameOpt, allOpt;
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    final String tableName = OptUtil.getTableOpt(cl, shellState);
+    
+    if (cl.hasOption(allOpt.getOpt())) {
+      final List<IteratorSetting> tableScanIterators = shellState.scanIteratorOptions.remove(tableName);
+      if (tableScanIterators == null) {
+        Shell.log.info("No scan iterators set on table " + tableName);
+      } else {
+        Shell.log.info("Removed the following scan iterators from table " + tableName + ":" + tableScanIterators);
+      }
+    } else if (cl.hasOption(nameOpt.getOpt())) {
+      final String name = cl.getOptionValue(nameOpt.getOpt());
+      final List<IteratorSetting> tableScanIterators = shellState.scanIteratorOptions.get(tableName);
+      if (tableScanIterators != null) {
+        boolean found = false;
+        for (Iterator<IteratorSetting> iter = tableScanIterators.iterator(); iter.hasNext();) {
+          if (iter.next().getName().equals(name)) {
+            iter.remove();
+            found = true;
+            break;
+          }
+        }
+        if (!found) {
+          Shell.log.info("No iterator named " + name + " found for table " + tableName);
+        } else {
+          Shell.log.info("Removed scan iterator " + name + " from table " + tableName + " (" + shellState.scanIteratorOptions.get(tableName).size() + " left)");
+          if (shellState.scanIteratorOptions.get(tableName).size() == 0) {
+            shellState.scanIteratorOptions.remove(tableName);
+          }
+        }
+      } else {
+        Shell.log.info("No iterator named " + name + " found for table " + tableName);
+      }
+    }
+    
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "deletes a table-specific scan iterator so it is no longer used during this shell session";
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+    
+    OptionGroup nameGroup = new OptionGroup();
+    
+    nameOpt = new Option("n", "name", true, "iterator to delete");
+    nameOpt.setArgName("itername");
+    
+    allOpt = new Option("a", "all", false, "delete all scan iterators");
+    allOpt.setArgName("all");
+    
+    nameGroup.addOption(nameOpt);
+    nameGroup.addOption(allOpt);
+    nameGroup.setRequired(true);
+    o.addOptionGroup(nameGroup);
+    o.addOption(OptUtil.tableOpt("table to delete scan iterators from"));
+    
+    return o;
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteShellIterCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteShellIterCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteShellIterCommand.java
new file mode 100644
index 0000000..3010f0b
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteShellIterCommand.java
@@ -0,0 +1,100 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.accumulo.core.client.IteratorSetting;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.OptionGroup;
+import org.apache.commons.cli.Options;
+
+public class DeleteShellIterCommand extends Command {
+  private Option nameOpt, allOpt, profileOpt;
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+
+    String profile = cl.getOptionValue(profileOpt.getOpt());
+    if (shellState.iteratorProfiles.containsKey(profile)) {
+      if (cl.hasOption(allOpt.getOpt())) {
+        shellState.iteratorProfiles.remove(profile);
+        Shell.log.info("Removed profile " + profile);
+      } else {
+        List<IteratorSetting> iterSettings = shellState.iteratorProfiles.get(profile);
+        String name = cl.getOptionValue(nameOpt.getOpt());
+        boolean found = false;
+        for (Iterator<IteratorSetting> iter = iterSettings.iterator(); iter.hasNext();) {
+          if (iter.next().getName().equals(name)) {
+            iter.remove();
+            found = true;
+            break;
+          }
+        }
+        if (!found) {
+          Shell.log.info("No iterator named " + name + " found");
+        } else {
+          Shell.log.info("Removed iterator " + name + " from profile " + profile + " (" + iterSettings.size() + " left)");
+        }
+      }
+      
+    } else {
+      Shell.log.info("No profile named " + profile);
+    }
+    
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "deletes iterators profiles configured in this shell session";
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+    
+    OptionGroup nameGroup = new OptionGroup();
+    
+    nameOpt = new Option("n", "name", true, "iterator to delete");
+    nameOpt.setArgName("itername");
+    
+    allOpt = new Option("a", "all", false, "delete all scan iterators");
+    allOpt.setArgName("all");
+    
+    nameGroup.addOption(nameOpt);
+    nameGroup.addOption(allOpt);
+    nameGroup.setRequired(true);
+    o.addOptionGroup(nameGroup);
+    
+    profileOpt = new Option("pn", "profile", true, "iterator profile name");
+    profileOpt.setRequired(true);
+    profileOpt.setArgName("profile");
+    o.addOption(profileOpt);
+
+    return o;
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteTableCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteTableCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteTableCommand.java
new file mode 100644
index 0000000..827a8ec
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteTableCommand.java
@@ -0,0 +1,60 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import org.apache.accumulo.shell.Shell;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+
+public class DeleteTableCommand extends TableOperation {
+  private Option forceOpt;
+
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    if (cl.hasOption(forceOpt.getOpt())) {
+      super.force();
+    } else {
+      super.noForce();
+    }
+    return super.execute(fullCommand, cl, shellState);
+  }
+
+  @Override
+  public String description() {
+    return "deletes a table";
+  }
+
+  @Override
+  protected void doTableOp(final Shell shellState, final String tableName) throws Exception {
+    shellState.getConnector().tableOperations().delete(tableName);
+    shellState.getReader().println("Table: [" + tableName + "] has been deleted.");
+
+    if (shellState.getTableName().equals(tableName)) {
+      shellState.setTableName("");
+    }
+  }
+
+  @Override
+  public Options getOptions() {
+    forceOpt = new Option("f", "force", false, "force deletion without prompting");
+    final Options opts = super.getOptions();
+
+    opts.addOption(forceOpt);
+    return opts;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteUserCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteUserCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteUserCommand.java
new file mode 100644
index 0000000..22d072a
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteUserCommand.java
@@ -0,0 +1,19 @@
+/*
+ * 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.accumulo.shell.commands;
+
+public class DeleteUserCommand extends DropUserCommand {}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/DropTableCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/DropTableCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/DropTableCommand.java
new file mode 100644
index 0000000..45b40dd
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/DropTableCommand.java
@@ -0,0 +1,19 @@
+/*
+ * 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.accumulo.shell.commands;
+
+public class DropTableCommand extends DeleteTableCommand {}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/DropUserCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/DropUserCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/DropUserCommand.java
new file mode 100644
index 0000000..7de216d
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/DropUserCommand.java
@@ -0,0 +1,61 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.util.BadArgumentException;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Token;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+
+public class DropUserCommand extends Command {
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException {
+    final String user = cl.getArgs()[0];
+    if (shellState.getConnector().whoami().equals(user)) {
+      throw new BadArgumentException("You cannot delete yourself", fullCommand, fullCommand.indexOf(user));
+    }
+    shellState.getConnector().securityOperations().dropLocalUser(user);
+    Shell.log.debug("Deleted user " + user);
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "deletes a user";
+  }
+  
+  @Override
+  public String usage() {
+    return getName() + " <username>";
+  }
+  
+  @Override
+  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> completionSet) {
+    registerCompletionForUsers(root, completionSet);
+  }
+  
+  @Override
+  public int numArgs() {
+    return 1;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/EGrepCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/EGrepCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/EGrepCommand.java
new file mode 100644
index 0000000..958f5eb
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/EGrepCommand.java
@@ -0,0 +1,59 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.io.IOException;
+
+import org.apache.accumulo.core.client.BatchScanner;
+import org.apache.accumulo.core.client.IteratorSetting;
+import org.apache.accumulo.core.iterators.user.RegExFilter;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+
+public class EGrepCommand extends GrepCommand {
+  
+  private Option matchSubstringOption;
+  
+  @Override
+  protected void setUpIterator(final int prio, final String name, final String term, final BatchScanner scanner, CommandLine cl) throws IOException {
+    if (prio < 0) {
+      throw new IllegalArgumentException("Priority < 0 " + prio);
+    }
+    final IteratorSetting si = new IteratorSetting(prio, name, RegExFilter.class);
+    RegExFilter.setRegexs(si, term, term, term, term, true, cl.hasOption(matchSubstringOption.getOpt()));
+    scanner.addScanIterator(si);
+  }
+  
+  @Override
+  public String description() {
+    return "searches each row, column family, column qualifier and value, in parallel, on the server side (using a java Matcher, so put .* before and after your term if you're not matching the whole element)";
+  }
+  
+  @Override
+  public String usage() {
+    return getName() + " <regex>{ <regex>}";
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options opts = super.getOptions();
+    matchSubstringOption = new Option("g", "global", false, "forces the use of the find() expression matcher, causing substring matches to return true");
+    opts.addOption(matchSubstringOption);
+    return opts;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/ExecfileCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/ExecfileCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/ExecfileCommand.java
new file mode 100644
index 0000000..b384d5c
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/ExecfileCommand.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.accumulo.shell.commands;
+
+import java.io.File;
+import java.nio.charset.StandardCharsets;
+import java.util.Scanner;
+
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+
+public class ExecfileCommand extends Command {
+  private Option verboseOption;
+  
+  @Override
+  public String description() {
+    return "specifies a file containing accumulo commands to execute";
+  }
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    Scanner scanner = new Scanner(new File(cl.getArgs()[0]), StandardCharsets.UTF_8.name());
+    try {
+      while (scanner.hasNextLine()) {
+        shellState.execCommand(scanner.nextLine(), true, cl.hasOption(verboseOption.getOpt()));
+      }
+    } finally {
+      scanner.close();
+    }
+    return 0;
+  }
+  
+  @Override
+  public String usage() {
+    return getName() + " <fileName>";
+  }
+  
+  @Override
+  public int numArgs() {
+    return 1;
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options opts = new Options();
+    verboseOption = new Option("v", "verbose", false, "display command prompt as commands are executed");
+    opts.addOption(verboseOption);
+    return opts;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/ExitCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/ExitCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/ExitCommand.java
new file mode 100644
index 0000000..1d44409
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/ExitCommand.java
@@ -0,0 +1,39 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+
+public class ExitCommand extends Command {
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) {
+    shellState.setExit(true);
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "exits the shell";
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/ExportTableCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/ExportTableCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/ExportTableCommand.java
new file mode 100644
index 0000000..d8d358c
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/ExportTableCommand.java
@@ -0,0 +1,78 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.TableExistsException;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Token;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+
+public class ExportTableCommand extends Command {
+  
+  private Option tableOpt;
+
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException, TableNotFoundException,
+      TableExistsException {
+    
+    final String tableName = OptUtil.getTableOpt(cl, shellState);
+
+    shellState.getConnector().tableOperations().exportTable(tableName, cl.getArgs()[0]);
+    return 0;
+  }
+  
+  @Override
+  public String usage() {
+    return getName() + " <export dir>";
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+    
+    tableOpt = new Option(Shell.tableOption, "table", true, "table to export");
+    
+    tableOpt.setArgName("table");
+    
+    o.addOption(tableOpt);
+
+    return o;
+  }
+  
+  @Override
+  public String description() {
+    return "exports a table";
+  }
+  
+  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> completionSet) {
+    registerCompletionForTables(root, completionSet);
+  }
+  
+  @Override
+  public int numArgs() {
+    return 1;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/ExtensionCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/ExtensionCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/ExtensionCommand.java
new file mode 100644
index 0000000..fbc1833
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/ExtensionCommand.java
@@ -0,0 +1,102 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.util.HashSet;
+import java.util.ServiceLoader;
+import java.util.Set;
+import java.util.TreeSet;
+
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.ShellExtension;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+
+public class ExtensionCommand extends Command {
+  
+  protected Option enable, disable, list;
+  
+  private static ServiceLoader<ShellExtension> extensions = null;
+  
+  private Set<String> loadedHeaders = new HashSet<String>();
+  private Set<String> loadedCommands = new HashSet<String>();
+  private Set<String> loadedExtensions = new TreeSet<String>();
+  
+  public int execute(String fullCommand, CommandLine cl, Shell shellState) throws Exception {
+    if (cl.hasOption(enable.getOpt())) {
+      extensions = ServiceLoader.load(ShellExtension.class);
+      for (ShellExtension se : extensions) {
+        
+        loadedExtensions.add(se.getExtensionName());
+        String header = "-- " + se.getExtensionName() + " Extension Commands ---------";
+        loadedHeaders.add(header);
+        shellState.commandGrouping.put(header, se.getCommands());
+        
+        for (Command cmd : se.getCommands()) {
+          String name = se.getExtensionName() + "::" + cmd.getName();
+          loadedCommands.add(name);
+          shellState.commandFactory.put(name, cmd);
+        }
+      }
+    } else if (cl.hasOption(disable.getOpt())) {
+      //Remove the headers
+      for (String header : loadedHeaders) {
+        shellState.commandGrouping.remove(header);
+      }
+      //remove the commands
+      for (String name : loadedCommands) {
+        shellState.commandFactory.remove(name);
+      }
+      //Reset state
+      loadedExtensions.clear();
+      extensions.reload();
+    } else if (cl.hasOption(list.getOpt())) {
+      shellState.printLines(loadedExtensions.iterator(), true);
+    } else {
+      printHelp(shellState);
+    }
+    return 0;
+  }
+  
+  public String description() {
+    return "Enable, disable, or list shell extensions";
+  }
+  
+  public int numArgs() {
+    return 0;
+  }
+  
+  @Override
+  public String getName() {
+    return "extensions";
+  }
+
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+    enable = new Option("e", "enable", false, "enable shell extensions");
+    disable = new Option("d", "disable", false, "disable shell extensions");
+    list = new Option("l", "list", false, "list shell extensions");
+    o.addOption(enable);
+    o.addOption(disable);
+    o.addOption(list);
+    return o;
+  }
+    
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/FateCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/FateCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/FateCommand.java
new file mode 100644
index 0000000..eae1ec8
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/FateCommand.java
@@ -0,0 +1,180 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.Formatter;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.accumulo.core.Constants;
+import org.apache.accumulo.core.client.Instance;
+import org.apache.accumulo.core.conf.AccumuloConfiguration;
+import org.apache.accumulo.core.conf.Property;
+import org.apache.accumulo.core.zookeeper.ZooUtil;
+import org.apache.accumulo.fate.AdminUtil;
+import org.apache.accumulo.fate.ReadOnlyTStore.TStatus;
+import org.apache.accumulo.fate.ZooStore;
+import org.apache.accumulo.fate.zookeeper.IZooReaderWriter;
+import org.apache.accumulo.fate.zookeeper.ZooReaderWriter;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+import org.apache.commons.cli.ParseException;
+import org.apache.zookeeper.KeeperException;
+
+/**
+ * Manage FATE transactions
+ * 
+ */
+public class FateCommand extends Command {
+  
+  private static final String SCHEME = "digest";
+  
+  private static final String USER = "accumulo";
+  
+  private Option secretOption;
+  private Option statusOption;
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws ParseException, KeeperException, InterruptedException,
+      IOException {
+    Instance instance = shellState.getInstance();
+    String[] args = cl.getArgs();
+    if (args.length <= 0) {
+      throw new ParseException("Must provide a command to execute");
+    }
+    String cmd = args[0];
+    boolean failedCommand = false;
+    
+    AdminUtil<FateCommand> admin = new AdminUtil<FateCommand>(false);
+    
+    String path = ZooUtil.getRoot(instance) + Constants.ZFATE;
+    String masterPath = ZooUtil.getRoot(instance) + Constants.ZMASTER_LOCK;
+    IZooReaderWriter zk = getZooReaderWriter(shellState.getInstance(), cl.getOptionValue(secretOption.getOpt()));
+    ZooStore<FateCommand> zs = new ZooStore<FateCommand>(path, zk);
+    
+    if ("fail".equals(cmd)) {
+      if (args.length <= 1) {
+        throw new ParseException("Must provide transaction ID");
+      }
+      for (int i = 1; i < args.length; i++) {
+        if (!admin.prepFail(zs, zk, masterPath, args[i])) {
+          System.out.printf("Could not fail transaction: %s%n", args[i]);
+          failedCommand = true;
+        }
+      }
+    } else if ("delete".equals(cmd)) {
+      if (args.length <= 1) {
+        throw new ParseException("Must provide transaction ID");
+      }
+      for (int i = 1; i < args.length; i++) {
+        if (admin.prepDelete(zs, zk, masterPath, args[i])) {
+          admin.deleteLocks(zs, zk, ZooUtil.getRoot(instance) + Constants.ZTABLE_LOCKS, args[i]);
+        } else {
+          System.out.printf("Could not delete transaction: %s%n", args[i]);
+          failedCommand = true;
+        }
+      }
+    } else if ("list".equals(cmd) || "print".equals(cmd)) {
+      // Parse transaction ID filters for print display
+      Set<Long> filterTxid = null;
+      if (args.length >= 2) {
+        filterTxid = new HashSet<Long>(args.length);
+        for (int i = 1; i < args.length; i++) {
+          try {
+            Long val = Long.parseLong(args[i], 16);
+            filterTxid.add(val);
+          } catch (NumberFormatException nfe) {
+            // Failed to parse, will exit instead of displaying everything since the intention was to potentially filter some data
+            System.out.printf("Invalid transaction ID format: %s%n", args[i]);
+            return 1;
+          }
+        }
+      }
+      
+      // Parse TStatus filters for print display
+      EnumSet<TStatus> filterStatus = null;
+      if (cl.hasOption(statusOption.getOpt())) {
+        filterStatus = EnumSet.noneOf(TStatus.class);
+        String[] tstat = cl.getOptionValues(statusOption.getOpt());
+        for (int i = 0; i < tstat.length; i++) {
+          try {
+            filterStatus.add(TStatus.valueOf(tstat[i]));
+          } catch (IllegalArgumentException iae) {
+            System.out.printf("Invalid transaction status name: %s%n", tstat[i]);
+            return 1;
+          }
+        }
+      }
+      
+      StringBuilder buf = new StringBuilder(8096);
+      Formatter fmt = new Formatter(buf);
+      admin.print(zs, zk, ZooUtil.getRoot(instance) + Constants.ZTABLE_LOCKS, fmt, filterTxid, filterStatus);
+      shellState.printLines(Collections.singletonList(buf.toString()).iterator(), true);
+    } else {
+      throw new ParseException("Invalid command option");
+    }
+    
+    return failedCommand ? 1 : 0;
+  }
+  
+  protected synchronized IZooReaderWriter getZooReaderWriter(Instance instance, String secret) {
+    
+    if (secret == null) {
+      @SuppressWarnings("deprecation")
+      AccumuloConfiguration conf = AccumuloConfiguration.getSiteConfiguration();
+      secret = conf.get(Property.INSTANCE_SECRET);
+    }
+    
+    return new ZooReaderWriter(instance.getZooKeepers(), instance.getZooKeepersSessionTimeOut(), SCHEME, (USER + ":" + secret).getBytes());
+  }
+  
+  @Override
+  public String description() {
+    return "manage FATE transactions";
+  }
+  
+  @Override
+  public String usage() {
+    return getName() + " fail <txid>... | delete <txid>... | print [<txid>...]";
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+    secretOption = new Option("s", "secret", true, "specify the instance secret to use");
+    secretOption.setOptionalArg(false);
+    o.addOption(secretOption);
+    statusOption = new Option("t", "status-type", true,
+        "filter 'print' on the transaction status type(s) {NEW, IN_PROGRESS, FAILED_IN_PROGRESS, FAILED, SUCCESSFUL}");
+    statusOption.setArgs(Option.UNLIMITED_VALUES);
+    statusOption.setOptionalArg(false);
+    o.addOption(statusOption);
+    return o;
+  }
+  
+  @Override
+  public int numArgs() {
+    // Arg length varies between 1 to n
+    return -1;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/FlushCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/FlushCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/FlushCommand.java
new file mode 100644
index 0000000..34e22a5
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/FlushCommand.java
@@ -0,0 +1,63 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.shell.Shell;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+import org.apache.hadoop.io.Text;
+
+public class FlushCommand extends TableOperation {
+  private Text startRow;
+  private Text endRow;
+  
+  private boolean wait;
+  private Option waitOpt;
+  
+  @Override
+  public String description() {
+    return "flushes a tables data that is currently in memory to disk";
+  }
+  
+  protected void doTableOp(final Shell shellState, final String tableName) throws AccumuloException, AccumuloSecurityException, TableNotFoundException {
+    shellState.getConnector().tableOperations().flush(tableName, startRow, endRow, wait);
+    Shell.log.info("Flush of table " + tableName + (wait ? " completed." : " initiated..."));
+  }
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    wait = cl.hasOption(waitOpt.getLongOpt());
+    startRow = OptUtil.getStartRow(cl);
+    endRow = OptUtil.getEndRow(cl);
+    return super.execute(fullCommand, cl, shellState);
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options opts = super.getOptions();
+    waitOpt = new Option("w", "wait", false, "wait for flush to finish");
+    opts.addOption(waitOpt);
+    opts.addOption(OptUtil.startRowOpt());
+    opts.addOption(OptUtil.endRowOpt());
+    
+    return opts;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/FormatterCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/FormatterCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/FormatterCommand.java
new file mode 100644
index 0000000..e416699
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/FormatterCommand.java
@@ -0,0 +1,69 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.conf.Property;
+import org.apache.accumulo.core.util.format.Formatter;
+import org.apache.accumulo.shell.Shell;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+
+public class FormatterCommand extends ShellPluginConfigurationCommand {
+  
+  private Option interpeterOption;
+
+  public FormatterCommand() {
+    super("formatter", Property.TABLE_FORMATTER_CLASS, "f");
+  }
+
+  @Override
+  public String description() {
+    return "specifies a formatter to use for displaying table entries";
+  }
+
+  public static Class<? extends Formatter> getCurrentFormatter(final String tableName, final Shell shellState) {
+    return ShellPluginConfigurationCommand.getPluginClass(tableName, shellState, Formatter.class, Property.TABLE_FORMATTER_CLASS);
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options options = super.getOptions();
+    
+    interpeterOption = new Option("i", "interpeter", false, "configure class as interpreter also");
+    
+    options.addOption(interpeterOption);
+    
+    return options;
+  }
+  
+  protected void setPlugin(final CommandLine cl, final Shell shellState, final String tableName, final String className) throws AccumuloException, AccumuloSecurityException {
+    super.setPlugin(cl, shellState, tableName, className);
+    if (cl.hasOption(interpeterOption.getOpt())) {
+      shellState.getConnector().tableOperations().setProperty(tableName, Property.TABLE_INTERPRETER_CLASS.toString(), className);
+    }
+  }
+  
+  protected void removePlugin(final CommandLine cl, final Shell shellState, final String tableName) throws AccumuloException, AccumuloSecurityException {
+    super.removePlugin(cl, shellState, tableName);
+    if (cl.hasOption(interpeterOption.getOpt())) {
+      shellState.getConnector().tableOperations().removeProperty(tableName, Property.TABLE_INTERPRETER_CLASS.toString());
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/GetAuthsCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/GetAuthsCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/GetAuthsCommand.java
new file mode 100644
index 0000000..0156d44
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/GetAuthsCommand.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.accumulo.shell.commands;
+
+import java.io.IOException;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.security.Authorizations;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+import org.apache.commons.lang.StringUtils;
+
+public class GetAuthsCommand extends Command {
+  private Option userOpt;
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException, IOException {
+    final String user = cl.getOptionValue(userOpt.getOpt(), shellState.getConnector().whoami());
+    // Sort authorizations
+    Authorizations auths = shellState.getConnector().securityOperations().getUserAuthorizations(user);
+    SortedSet<String> set = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
+    for (byte[] auth : auths) {
+      set.add(new String(auth));
+    }
+    shellState.getReader().println(StringUtils.join(set, ','));
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "displays the maximum scan authorizations for a user";
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+    userOpt = new Option(Shell.userOption, "user", true, "user to operate on");
+    userOpt.setArgName("user");
+    o.addOption(userOpt);
+    return o;
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/GetGroupsCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/GetGroupsCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/GetGroupsCommand.java
new file mode 100644
index 0000000..6cae7e0
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/GetGroupsCommand.java
@@ -0,0 +1,60 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import org.apache.accumulo.core.util.LocalityGroupUtil;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Options;
+import org.apache.hadoop.io.Text;
+
+public class GetGroupsCommand extends Command {
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    final String tableName = OptUtil.getTableOpt(cl, shellState);
+    
+    final Map<String,Set<Text>> groups = shellState.getConnector().tableOperations().getLocalityGroups(tableName);
+    
+    for (Entry<String,Set<Text>> entry : groups.entrySet()) {
+      shellState.getReader().println(entry.getKey() + "=" + LocalityGroupUtil.encodeColumnFamilies(entry.getValue()));
+    }
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "gets the locality groups for a given table";
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options opts = new Options();
+    opts.addOption(OptUtil.tableOpt("table to fetch locality groups from"));
+    return opts;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/GetSplitsCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/GetSplitsCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/GetSplitsCommand.java
new file mode 100644
index 0000000..f275c39
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/GetSplitsCommand.java
@@ -0,0 +1,155 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.accumulo.shell.commands;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.Iterator;
+import java.util.Map.Entry;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.Scanner;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.core.data.Key;
+import org.apache.accumulo.core.data.KeyExtent;
+import org.apache.accumulo.core.data.Range;
+import org.apache.accumulo.core.data.Value;
+import org.apache.accumulo.core.metadata.MetadataTable;
+import org.apache.accumulo.core.metadata.RootTable;
+import org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection;
+import org.apache.accumulo.core.security.Authorizations;
+import org.apache.accumulo.core.util.TextUtil;
+import org.apache.accumulo.core.util.format.BinaryFormatter;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.accumulo.shell.Shell.PrintFile;
+import org.apache.accumulo.shell.Shell.PrintLine;
+import org.apache.accumulo.shell.Shell.PrintShell;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+import org.apache.commons.codec.binary.Base64;
+import org.apache.hadoop.io.Text;
+
+public class GetSplitsCommand extends Command {
+  
+  private Option outputFileOpt, maxSplitsOpt, base64Opt, verboseOpt;
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws IOException, AccumuloException, AccumuloSecurityException,
+      TableNotFoundException {
+    final String tableName = OptUtil.getTableOpt(cl, shellState);
+    
+    final String outputFile = cl.getOptionValue(outputFileOpt.getOpt());
+    final String m = cl.getOptionValue(maxSplitsOpt.getOpt());
+    final int maxSplits = m == null ? 0 : Integer.parseInt(m);
+    final boolean encode = cl.hasOption(base64Opt.getOpt());
+    final boolean verbose = cl.hasOption(verboseOpt.getOpt());
+    
+    final PrintLine p = outputFile == null ? new PrintShell(shellState.getReader()) : new PrintFile(outputFile);
+    
+    try {
+      if (!verbose) {
+        for (Text row : maxSplits > 0 ? shellState.getConnector().tableOperations().listSplits(tableName, maxSplits) : shellState.getConnector()
+            .tableOperations().listSplits(tableName)) {
+          p.print(encode(encode, row));
+        }
+      } else {
+        String systemTableToCheck = MetadataTable.NAME.equals(tableName) ? RootTable.NAME : MetadataTable.NAME;
+        final Scanner scanner = shellState.getConnector().createScanner(systemTableToCheck, Authorizations.EMPTY);
+        TabletsSection.TabletColumnFamily.PREV_ROW_COLUMN.fetch(scanner);
+        final Text start = new Text(shellState.getConnector().tableOperations().tableIdMap().get(tableName));
+        final Text end = new Text(start);
+        end.append(new byte[] {'<'}, 0, 1);
+        scanner.setRange(new Range(start, end));
+        for (Iterator<Entry<Key,Value>> iterator = scanner.iterator(); iterator.hasNext();) {
+          final Entry<Key,Value> next = iterator.next();
+          if (TabletsSection.TabletColumnFamily.PREV_ROW_COLUMN.hasColumns(next.getKey())) {
+            KeyExtent extent = new KeyExtent(next.getKey().getRow(), next.getValue());
+            final String pr = encode(encode, extent.getPrevEndRow());
+            final String er = encode(encode, extent.getEndRow());
+            final String line = String.format("%-26s (%s, %s%s", obscuredTabletName(extent), pr == null ? "-inf" : pr, er == null ? "+inf" : er,
+                er == null ? ") Default Tablet " : "]");
+            p.print(line);
+          }
+        }
+      }
+      
+    } finally {
+      p.close();
+    }
+    
+    return 0;
+  }
+  
+  private static String encode(final boolean encode, final Text text) {
+    if (text == null) {
+      return null;
+    }
+    BinaryFormatter.getlength(text.getLength());
+    return encode ? new String(Base64.encodeBase64(TextUtil.getBytes(text)), StandardCharsets.UTF_8) : BinaryFormatter.appendText(new StringBuilder(), text).toString();
+  }
+  
+  private static String obscuredTabletName(final KeyExtent extent) {
+    MessageDigest digester;
+    try {
+      digester = MessageDigest.getInstance("MD5");
+    } catch (NoSuchAlgorithmException e) {
+      throw new RuntimeException(e);
+    }
+    if (extent.getEndRow() != null && extent.getEndRow().getLength() > 0) {
+      digester.update(extent.getEndRow().getBytes(), 0, extent.getEndRow().getLength());
+    }
+    return new String(Base64.encodeBase64(digester.digest()), StandardCharsets.UTF_8);
+  }
+  
+  @Override
+  public String description() {
+    return "retrieves the current split points for tablets in the current table";
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options opts = new Options();
+    
+    outputFileOpt = new Option("o", "output", true, "local file to write the splits to");
+    outputFileOpt.setArgName("file");
+    
+    maxSplitsOpt = new Option("m", "max", true, "maximum number of splits to return (evenly spaced)");
+    maxSplitsOpt.setArgName("num");
+    
+    base64Opt = new Option("b64", "base64encoded", false, "encode the split points");
+    
+    verboseOpt = new Option("v", "verbose", false, "print out the tablet information with start/end rows");
+    
+    opts.addOption(outputFileOpt);
+    opts.addOption(maxSplitsOpt);
+    opts.addOption(base64Opt);
+    opts.addOption(verboseOpt);
+    opts.addOption(OptUtil.tableOpt("table to get splits for"));
+    
+    return opts;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/GrantCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/GrantCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/GrantCommand.java
new file mode 100644
index 0000000..8f4448f
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/GrantCommand.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.accumulo.shell.commands;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.accumulo.core.security.NamespacePermission;
+import org.apache.accumulo.core.security.SystemPermission;
+import org.apache.accumulo.core.security.TablePermission;
+import org.apache.accumulo.core.util.BadArgumentException;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Token;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.OptionGroup;
+import org.apache.commons.cli.Options;
+
+public class GrantCommand extends TableOperation {
+  {
+    disableUnflaggedTableOptions();
+  }
+
+  private Option systemOpt, userOpt;
+  private String user;
+  private String[] permission;
+
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    user = cl.hasOption(userOpt.getOpt()) ? cl.getOptionValue(userOpt.getOpt()) : shellState.getConnector().whoami();
+
+    permission = cl.getArgs()[0].split("\\.", 2);
+    if (cl.hasOption(systemOpt.getOpt()) && permission[0].equalsIgnoreCase("System")) {
+      try {
+        shellState.getConnector().securityOperations().grantSystemPermission(user, SystemPermission.valueOf(permission[1]));
+        Shell.log.debug("Granted " + user + " the " + permission[1] + " permission");
+      } catch (IllegalArgumentException e) {
+        throw new BadArgumentException("No such system permission", fullCommand, fullCommand.indexOf(cl.getArgs()[0]));
+      }
+    } else if (permission[0].equalsIgnoreCase("Table")) {
+      super.execute(fullCommand, cl, shellState);
+    } else if (permission[0].equalsIgnoreCase("Namespace")) {
+      if (cl.hasOption(optNamespace.getOpt())) {
+        try {
+          shellState.getConnector().securityOperations()
+              .grantNamespacePermission(user, cl.getOptionValue(optNamespace.getOpt()), NamespacePermission.valueOf(permission[1]));
+        } catch (IllegalArgumentException e) {
+          throw new BadArgumentException("No such namespace permission", fullCommand, fullCommand.indexOf(cl.getArgs()[0]));
+        }
+      } else {
+        throw new BadArgumentException("No namespace specified to apply permission to", fullCommand, fullCommand.indexOf(cl.getArgs()[0]));
+      }
+    } else {
+      throw new BadArgumentException("Unrecognized permission", fullCommand, fullCommand.indexOf(cl.getArgs()[0]));
+    }
+    return 0;
+  }
+
+  @Override
+  protected void doTableOp(final Shell shellState, final String tableName) throws Exception {
+    try {
+      shellState.getConnector().securityOperations().grantTablePermission(user, tableName, TablePermission.valueOf(permission[1]));
+      Shell.log.debug("Granted " + user + " the " + permission[1] + " permission on table " + tableName);
+    } catch (IllegalArgumentException e) {
+      throw new IllegalArgumentException("No such table permission", e);
+    }
+  }
+
+  @Override
+  public String description() {
+    return "grants system, table, or namespace permissions for a user";
+  }
+
+  @Override
+  public String usage() {
+    return getName() + " <permission>";
+  }
+
+  @Override
+  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> completionSet) {
+    final Token cmd = new Token(getName());
+    cmd.addSubcommand(new Token(TablePermission.printableValues()));
+    cmd.addSubcommand(new Token(SystemPermission.printableValues()));
+    cmd.addSubcommand(new Token(NamespacePermission.printableValues()));
+    root.addSubcommand(cmd);
+  }
+
+  @Override
+  public Options getOptions() {
+    super.getOptions();
+    final Options o = new Options();
+
+    final OptionGroup group = new OptionGroup();
+
+    systemOpt = new Option("s", "system", false, "grant a system permission");
+
+    optNamespace = new Option(Shell.namespaceOption, "namespace", true, "name of a namespace to operate on");
+    optNamespace.setArgName("namespace");
+
+    group.addOption(systemOpt);
+    group.addOption(optTableName);
+    group.addOption(optTablePattern);
+    group.addOption(optNamespace);
+
+    o.addOptionGroup(group);
+    userOpt = new Option(Shell.userOption, "user", true, "user to operate on");
+    userOpt.setArgName("username");
+    userOpt.setRequired(true);
+    o.addOption(userOpt);
+
+    return o;
+  }
+
+  @Override
+  public int numArgs() {
+    return 1;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/GrepCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/GrepCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/GrepCommand.java
new file mode 100644
index 0000000..1a3c484
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/GrepCommand.java
@@ -0,0 +1,111 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.accumulo.core.client.BatchScanner;
+import org.apache.accumulo.core.client.IteratorSetting;
+import org.apache.accumulo.core.iterators.user.GrepIterator;
+import org.apache.accumulo.core.security.Authorizations;
+import org.apache.accumulo.core.util.format.Formatter;
+import org.apache.accumulo.core.util.interpret.ScanInterpreter;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.PrintFile;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.MissingArgumentException;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+
+public class GrepCommand extends ScanCommand {
+  
+  private Option numThreadsOpt;
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    final PrintFile printFile = getOutputFile(cl);
+    
+    final String tableName = OptUtil.getTableOpt(cl, shellState);
+    
+    if (cl.getArgList().isEmpty()) {
+      throw new MissingArgumentException("No terms specified");
+    }
+    final Class<? extends Formatter> formatter = getFormatter(cl, tableName, shellState);
+    final ScanInterpreter interpeter = getInterpreter(cl, tableName, shellState);
+    
+    // handle first argument, if present, the authorizations list to
+    // scan with
+    int numThreads = 20;
+    if (cl.hasOption(numThreadsOpt.getOpt())) {
+      numThreads = Integer.parseInt(cl.getOptionValue(numThreadsOpt.getOpt()));
+    }
+    final Authorizations auths = getAuths(cl, shellState);
+    final BatchScanner scanner = shellState.getConnector().createBatchScanner(tableName, auths, numThreads);
+    scanner.setRanges(Collections.singletonList(getRange(cl, interpeter)));
+    
+    scanner.setTimeout(getTimeout(cl), TimeUnit.MILLISECONDS);
+    
+    for (int i = 0; i < cl.getArgs().length; i++) {
+      setUpIterator(Integer.MAX_VALUE - cl.getArgs().length + i, "grep" + i, cl.getArgs()[i], scanner, cl);
+    }
+    try {
+      // handle columns
+      fetchColumns(cl, scanner, interpeter);
+      
+      // output the records
+      printRecords(cl, shellState, scanner, formatter, printFile);
+    } finally {
+      scanner.close();
+    }
+    
+    return 0;
+  }
+  
+  protected void setUpIterator(final int prio, final String name, final String term, final BatchScanner scanner, CommandLine cl) throws IOException {
+    if (prio < 0) {
+      throw new IllegalArgumentException("Priority < 0 " + prio);
+    }
+    final IteratorSetting grep = new IteratorSetting(prio, name, GrepIterator.class);
+    GrepIterator.setTerm(grep, term);
+    scanner.addScanIterator(grep);
+  }
+  
+  @Override
+  public String description() {
+    return "searches each row, column family, column qualifier and value in a table for a substring (not a regular expression), in parallel, on the server side";
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options opts = super.getOptions();
+    numThreadsOpt = new Option("nt", "num-threads", true, "number of threads to use");
+    opts.addOption(numThreadsOpt);
+    return opts;
+  }
+  
+  @Override
+  public String usage() {
+    return getName() + " <term>{ <term>}";
+  }
+  
+  @Override
+  public int numArgs() {
+    return Shell.NO_FIXED_ARG_LENGTH_CHECK;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/HelpCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/HelpCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/HelpCommand.java
new file mode 100644
index 0000000..90e8c4f
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/HelpCommand.java
@@ -0,0 +1,129 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.ShellCommandException;
+import org.apache.accumulo.shell.Token;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+
+public class HelpCommand extends Command {
+  private Option disablePaginationOpt;
+  private Option noWrapOpt;
+  
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws ShellCommandException, IOException {
+    int numColumns = shellState.getReader().getTerminal().getWidth();
+    if (cl.hasOption(noWrapOpt.getOpt())) {
+      numColumns = Integer.MAX_VALUE;
+    }
+    // print help summary
+    if (cl.getArgs().length == 0) {
+      int i = 0;
+      for (String cmd : shellState.commandFactory.keySet()) {
+        i = Math.max(i, cmd.length());
+      }
+      if (numColumns < 40) {
+        throw new IllegalArgumentException("numColumns must be at least 40 (was " + numColumns + ")");
+      }
+      final ArrayList<String> output = new ArrayList<String>();
+      for (Entry<String,Command[]> cmdGroup : shellState.commandGrouping.entrySet()) {
+        output.add(cmdGroup.getKey());
+        for (Command c : cmdGroup.getValue()) {
+          String n = c.getName();
+          String s = c.description();
+          if (s == null) {
+            s = "";
+          }
+          int beginIndex = 0;
+          int endIndex = s.length();
+          while (beginIndex < endIndex && s.charAt(beginIndex) == ' ')
+            beginIndex++;
+          String dash = "-";
+          while (endIndex > beginIndex && endIndex - beginIndex + i + 5 > numColumns) {
+            endIndex = s.lastIndexOf(" ", numColumns + beginIndex - i - 5);
+            if (endIndex == -1 || endIndex < beginIndex) {
+              endIndex = numColumns + beginIndex - i - 5 - 1;
+              output.add(String.format("%-" + i + "s  %s  %s-", n, dash, s.substring(beginIndex, endIndex)));
+              dash = " ";
+              beginIndex = endIndex;
+            } else {
+              output.add(String.format("%-" + i + "s  %s  %s", n, dash, s.substring(beginIndex, endIndex)));
+              dash = " ";
+              beginIndex = endIndex + 1;
+            }
+            n = "";
+            endIndex = s.length();
+            while (beginIndex < endIndex && s.charAt(beginIndex) == ' ') {
+              beginIndex++;
+            }
+          }
+          output.add(String.format("%-" + i + "s  %s  %s", n, dash, s.substring(beginIndex, endIndex)));
+        }
+        output.add("");
+      }
+      shellState.printLines(output.iterator(), !cl.hasOption(disablePaginationOpt.getOpt()));
+    }
+    
+    // print help for every command on command line
+    for (String cmd : cl.getArgs()) {
+      final Command c = shellState.commandFactory.get(cmd);
+      if (c == null) {
+        shellState.getReader().println(String.format("Unknown command \"%s\".  Enter \"help\" for a list possible commands.", cmd));
+      } else {
+        c.printHelp(shellState, numColumns);
+      }
+    }
+    return 0;
+  }
+  
+  public String description() {
+    return "provides information about the available commands";
+  }
+  
+  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> special) {
+    registerCompletionForCommands(root, special);
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+    disablePaginationOpt = new Option("np", "no-pagination", false, "disable pagination of output");
+    o.addOption(disablePaginationOpt);
+    noWrapOpt = new Option("nw", "no-wrap", false, "disable wrapping of output");
+    o.addOption(noWrapOpt);
+    return o;
+  }
+  
+  @Override
+  public String usage() {
+    return getName() + " [ <command>{ <command>} ]";
+  }
+  
+  @Override
+  public int numArgs() {
+    return Shell.NO_FIXED_ARG_LENGTH_CHECK;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/HiddenCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/HiddenCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/HiddenCommand.java
new file mode 100644
index 0000000..824517d
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/HiddenCommand.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.accumulo.shell.commands;
+
+import java.nio.charset.StandardCharsets;
+import java.security.SecureRandom;
+import java.util.Random;
+
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.ShellCommandException;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.accumulo.shell.ShellCommandException.ErrorCode;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.codec.binary.Base64;
+
+public class HiddenCommand extends Command {
+  private static Random rand = new SecureRandom();
+  
+  @Override
+  public String description() {
+    return "The first rule of Accumulo is: \"You don't talk about Accumulo.\"";
+  }
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    if (rand.nextInt(10) == 0) {
+      shellState.getReader().beep();
+      shellState.getReader().println();
+      shellState.getReader().println(
+          new String(Base64.decodeBase64(("ICAgICAgIC4tLS4KICAgICAgLyAvXCBcCiAgICAgKCAvLS1cICkKICAgICAuPl8gIF88LgogICAgLyB8ICd8ICcgXAog"
+              + "ICAvICB8Xy58Xy4gIFwKICAvIC98ICAgICAgfFwgXAogfCB8IHwgfFwvfCB8IHwgfAogfF98IHwgfCAgfCB8IHxffAogICAgIC8gIF9fICBcCiAgICAvICAv"
+              + "ICBcICBcCiAgIC8gIC8gICAgXCAgXF8KIHwvICAvICAgICAgXCB8IHwKIHxfXy8gICAgICAgIFx8X3wK").getBytes(StandardCharsets.UTF_8)), StandardCharsets.UTF_8));
+    } else {
+      throw new ShellCommandException(ErrorCode.UNRECOGNIZED_COMMAND, getName());
+    }
+    return 0;
+  }
+  
+  @Override
+  public int numArgs() {
+    return Shell.NO_FIXED_ARG_LENGTH_CHECK;
+  }
+  
+  @Override
+  public String getName() {
+    return "accvmvlo";
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/HistoryCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/HistoryCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/HistoryCommand.java
new file mode 100644
index 0000000..1c1314a
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/HistoryCommand.java
@@ -0,0 +1,82 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.ListIterator;
+
+import jline.console.history.History.Entry;
+
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+import org.apache.commons.collections.iterators.AbstractIteratorDecorator;
+
+public class HistoryCommand extends Command {
+  private Option clearHist;
+  private Option disablePaginationOpt;
+  
+  @SuppressWarnings("unchecked")
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws IOException {
+    if (cl.hasOption(clearHist.getOpt())) {
+      shellState.getReader().getHistory().clear();
+    } else {
+      ListIterator<Entry> it = shellState.getReader().getHistory().entries();
+      shellState.printLines(new HistoryLineIterator(it), !cl.hasOption(disablePaginationOpt.getOpt()));
+    }
+    
+    return 0;
+  }
+  
+  /**
+   * Decorator that converts an Iterator<History.Entry> to an Iterator<String>.
+   */
+  private static class HistoryLineIterator extends AbstractIteratorDecorator {
+    public HistoryLineIterator(Iterator<Entry> iterator) {
+      super(iterator);
+    }
+    
+    @Override
+    public String next() {
+      return super.next().toString();
+    }
+  }
+  
+  @Override
+  public String description() {
+    return ("generates a list of commands previously executed");
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+    clearHist = new Option("c", "clear", false, "clear history file");
+    o.addOption(clearHist);
+    disablePaginationOpt = new Option("np", "no-pagination", false, "disable pagination of output");
+    o.addOption(disablePaginationOpt);
+    return o;
+  }
+}


[12/53] [abbrv] ACCUMULO-1897 Move shell into new package and module

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/CreateTableCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/CreateTableCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/CreateTableCommand.java
deleted file mode 100644
index bc5f1d1..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/CreateTableCommand.java
+++ /dev/null
@@ -1,203 +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.accumulo.core.util.shell.commands;
-
-import java.io.IOException;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.SortedSet;
-import java.util.TreeSet;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.TableExistsException;
-import org.apache.accumulo.core.client.TableNotFoundException;
-import org.apache.accumulo.core.client.admin.TimeType;
-import org.apache.accumulo.core.client.impl.Tables;
-import org.apache.accumulo.core.conf.Property;
-import org.apache.accumulo.core.iterators.IteratorUtil;
-import org.apache.accumulo.core.security.VisibilityConstraint;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.accumulo.core.util.shell.ShellUtil;
-import org.apache.accumulo.core.util.shell.Token;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.OptionGroup;
-import org.apache.commons.cli.Options;
-import org.apache.hadoop.io.Text;
-
-public class CreateTableCommand extends Command {
-  private Option createTableOptCopySplits;
-  private Option createTableOptCopyConfig;
-  private Option createTableOptSplit;
-  private Option createTableOptTimeLogical;
-  private Option createTableOptTimeMillis;
-  private Option createTableNoDefaultIters;
-  private Option createTableOptEVC;
-  private Option base64Opt;
-  private Option createTableOptFormatter;
-
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException,
-      TableExistsException, TableNotFoundException, IOException, ClassNotFoundException {
-
-    final String testTableName = cl.getArgs()[0];
-
-    if (!testTableName.matches(Tables.VALID_NAME_REGEX)) {
-      shellState.getReader().println("Only letters, numbers and underscores are allowed for use in table names.");
-      throw new IllegalArgumentException();
-    }
-
-    final String tableName = cl.getArgs()[0];
-    if (shellState.getConnector().tableOperations().exists(tableName)) {
-      throw new TableExistsException(null, tableName, null);
-    }
-    final SortedSet<Text> partitions = new TreeSet<Text>();
-    final boolean decode = cl.hasOption(base64Opt.getOpt());
-
-    if (cl.hasOption(createTableOptSplit.getOpt())) {
-      partitions.addAll(ShellUtil.scanFile(cl.getOptionValue(createTableOptSplit.getOpt()), decode));
-    } else if (cl.hasOption(createTableOptCopySplits.getOpt())) {
-      final String oldTable = cl.getOptionValue(createTableOptCopySplits.getOpt());
-      if (!shellState.getConnector().tableOperations().exists(oldTable)) {
-        throw new TableNotFoundException(null, oldTable, null);
-      }
-      partitions.addAll(shellState.getConnector().tableOperations().listSplits(oldTable));
-    }
-
-    if (cl.hasOption(createTableOptCopyConfig.getOpt())) {
-      final String oldTable = cl.getOptionValue(createTableOptCopyConfig.getOpt());
-      if (!shellState.getConnector().tableOperations().exists(oldTable)) {
-        throw new TableNotFoundException(null, oldTable, null);
-      }
-    }
-
-    TimeType timeType = TimeType.MILLIS;
-    if (cl.hasOption(createTableOptTimeLogical.getOpt())) {
-      timeType = TimeType.LOGICAL;
-    }
-
-    // create table
-    shellState.getConnector().tableOperations().create(tableName, true, timeType);
-    if (partitions.size() > 0) {
-      shellState.getConnector().tableOperations().addSplits(tableName, partitions);
-    }
-
-    shellState.setTableName(tableName); // switch shell to new table context
-
-    if (cl.hasOption(createTableNoDefaultIters.getOpt())) {
-      for (String key : IteratorUtil.generateInitialTableProperties(true).keySet()) {
-        shellState.getConnector().tableOperations().removeProperty(tableName, key);
-      }
-    }
-
-    // Copy options if flag was set
-    if (cl.hasOption(createTableOptCopyConfig.getOpt())) {
-      if (shellState.getConnector().tableOperations().exists(tableName)) {
-        final Iterable<Entry<String,String>> configuration = shellState.getConnector().tableOperations()
-            .getProperties(cl.getOptionValue(createTableOptCopyConfig.getOpt()));
-        for (Entry<String,String> entry : configuration) {
-          if (Property.isValidTablePropertyKey(entry.getKey())) {
-            shellState.getConnector().tableOperations().setProperty(tableName, entry.getKey(), entry.getValue());
-          }
-        }
-      }
-    }
-
-    if (cl.hasOption(createTableOptEVC.getOpt())) {
-      try {
-        shellState.getConnector().tableOperations().addConstraint(tableName, VisibilityConstraint.class.getName());
-      } catch (AccumuloException e) {
-        Shell.log.warn(e.getMessage() + " while setting visibility constraint, but table was created");
-      }
-    }
-
-    // Load custom formatter if set
-    if (cl.hasOption(createTableOptFormatter.getOpt())) {
-      final String formatterClass = cl.getOptionValue(createTableOptFormatter.getOpt());
-
-      shellState.getConnector().tableOperations().setProperty(tableName, Property.TABLE_FORMATTER_CLASS.toString(), formatterClass);
-    }
-
-    return 0;
-  }
-
-  @Override
-  public String description() {
-    return "creates a new table, with optional aggregators and optionally pre-split";
-  }
-
-  @Override
-  public String usage() {
-    return getName() + " <tableName>";
-  }
-
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-
-    createTableOptCopyConfig = new Option("cc", "copy-config", true, "table to copy configuration from");
-    createTableOptCopySplits = new Option("cs", "copy-splits", true, "table to copy current splits from");
-    createTableOptSplit = new Option("sf", "splits-file", true, "file with a newline-separated list of rows to split the table with");
-    createTableOptTimeLogical = new Option("tl", "time-logical", false, "use logical time");
-    createTableOptTimeMillis = new Option("tm", "time-millis", false, "use time in milliseconds");
-    createTableNoDefaultIters = new Option("ndi", "no-default-iterators", false, "prevent creation of the normal default iterator set");
-    createTableOptEVC = new Option("evc", "enable-visibility-constraint", false,
-        "prevent users from writing data they cannot read.  When enabling this, consider disabling bulk import and alter table.");
-    createTableOptFormatter = new Option("f", "formatter", true, "default formatter to set");
-
-    createTableOptCopyConfig.setArgName("table");
-    createTableOptCopySplits.setArgName("table");
-    createTableOptSplit.setArgName("filename");
-    createTableOptFormatter.setArgName("className");
-
-    // Splits and CopySplits are put in an optionsgroup to make them
-    // mutually exclusive
-    final OptionGroup splitOrCopySplit = new OptionGroup();
-    splitOrCopySplit.addOption(createTableOptSplit);
-    splitOrCopySplit.addOption(createTableOptCopySplits);
-
-    final OptionGroup timeGroup = new OptionGroup();
-    timeGroup.addOption(createTableOptTimeLogical);
-    timeGroup.addOption(createTableOptTimeMillis);
-
-    base64Opt = new Option("b64", "base64encoded", false, "decode encoded split points");
-    o.addOption(base64Opt);
-
-    o.addOptionGroup(splitOrCopySplit);
-    o.addOptionGroup(timeGroup);
-    o.addOption(createTableOptSplit);
-    o.addOption(createTableOptCopyConfig);
-    o.addOption(createTableNoDefaultIters);
-    o.addOption(createTableOptEVC);
-    o.addOption(createTableOptFormatter);
-
-    return o;
-  }
-
-  @Override
-  public int numArgs() {
-    return 1;
-  }
-
-  @Override
-  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> special) {
-    registerCompletionForNamespaces(root, special);
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/CreateUserCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/CreateUserCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/CreateUserCommand.java
deleted file mode 100644
index aa3d7b9..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/CreateUserCommand.java
+++ /dev/null
@@ -1,76 +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.accumulo.core.util.shell.commands;
-
-import java.io.IOException;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.TableExistsException;
-import org.apache.accumulo.core.client.TableNotFoundException;
-import org.apache.accumulo.core.client.security.tokens.PasswordToken;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Options;
-
-public class CreateUserCommand extends Command {
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, TableNotFoundException,
-      AccumuloSecurityException, TableExistsException, IOException {
-    final String user = cl.getArgs()[0];
-    
-    final String password = shellState.readMaskedLine("Enter new password for '" + user + "': ", '*');
-    if (password == null) {
-      shellState.getReader().println();
-      return 0;
-    } // user canceled
-    String passwordConfirm = shellState.readMaskedLine("Please confirm new password for '" + user + "': ", '*');
-    if (passwordConfirm == null) {
-      shellState.getReader().println();
-      return 0;
-    } // user canceled
-    
-    if (!password.equals(passwordConfirm)) {
-      throw new IllegalArgumentException("Passwords do not match");
-    }
-    shellState.getConnector().securityOperations().createLocalUser(user, new PasswordToken(password));
-    Shell.log.debug("Created user " + user);
-    return 0;
-  }
-  
-  @Override
-  public String usage() {
-    return getName() + " <username>";
-  }
-  
-  @Override
-  public String description() {
-    return "creates a new user";
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-    return o;
-  }
-  
-  @Override
-  public int numArgs() {
-    return 1;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DUCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DUCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DUCommand.java
deleted file mode 100644
index 660ec6c..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DUCommand.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.accumulo.core.util.shell.commands;
-
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.SortedSet;
-import java.util.TreeSet;
-
-import org.apache.accumulo.core.client.Instance;
-import org.apache.accumulo.core.client.NamespaceNotFoundException;
-import org.apache.accumulo.core.client.TableNotFoundException;
-import org.apache.accumulo.core.client.admin.DiskUsage;
-import org.apache.accumulo.core.client.impl.Namespaces;
-import org.apache.accumulo.core.util.NumUtil;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-
-public class DUCommand extends Command {
-
-  private Option optTablePattern, optHumanReadble, optNamespace;
-
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws IOException, TableNotFoundException,
-      NamespaceNotFoundException {
-
-    final SortedSet<String> tables = new TreeSet<String>(Arrays.asList(cl.getArgs()));
-
-    if (cl.hasOption(Shell.tableOption)) {
-      String tableName = cl.getOptionValue(Shell.tableOption);
-      if (!shellState.getConnector().tableOperations().exists(tableName)) {
-        throw new TableNotFoundException(tableName, tableName, "specified table that doesn't exist");
-      }
-      tables.add(tableName);
-    }
-
-    if (cl.hasOption(optNamespace.getOpt())) {
-      Instance instance = shellState.getInstance();
-      String namespaceId = Namespaces.getNamespaceId(instance, cl.getOptionValue(optNamespace.getOpt()));
-      tables.addAll(Namespaces.getTableNames(instance, namespaceId));
-    }
-
-    boolean prettyPrint = cl.hasOption(optHumanReadble.getOpt()) ? true : false;
-
-    // Add any patterns
-    if (cl.hasOption(optTablePattern.getOpt())) {
-      for (String table : shellState.getConnector().tableOperations().list()) {
-        if (table.matches(cl.getOptionValue(optTablePattern.getOpt()))) {
-          tables.add(table);
-        }
-      }
-    }
-
-    // If we didn't get any tables, and we have a table selected, add the current table
-    if (tables.isEmpty() && !shellState.getTableName().isEmpty()) {
-      tables.add(shellState.getTableName());
-    }
-
-    try {
-      String valueFormat = prettyPrint ? "%9s" : "%,24d";
-      for (DiskUsage usage : shellState.getConnector().tableOperations().getDiskUsage(tables)) {
-        Object value = prettyPrint ? NumUtil.bigNumberForSize(usage.getUsage()) : usage.getUsage();
-        shellState.getReader().println(String.format(valueFormat + " %s", value, usage.getTables()));
-      }
-    } catch (Exception ex) {
-      throw new RuntimeException(ex);
-    }
-    return 0;
-  }
-
-  @Override
-  public String description() {
-    return "prints how much space, in bytes, is used by files referenced by a table.  When multiple tables are specified it prints how much space, in bytes, is used by files shared between tables, if any.";
-  }
-
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-
-    optTablePattern = new Option("p", "pattern", true, "regex pattern of table names");
-    optTablePattern.setArgName("pattern");
-
-    optHumanReadble = new Option("h", "human-readable", false, "format large sizes to human readable units");
-    optHumanReadble.setArgName("human readable output");
-
-    optNamespace = new Option(Shell.namespaceOption, "namespace", true, "name of a namespace");
-    optNamespace.setArgName("namespace");
-
-    o.addOption(OptUtil.tableOpt("table to examine"));
-
-    o.addOption(optTablePattern);
-    o.addOption(optHumanReadble);
-    o.addOption(optNamespace);
-
-    return o;
-  }
-
-  @Override
-  public String usage() {
-    return getName() + " <table>{ <table>}";
-  }
-
-  @Override
-  public int numArgs() {
-    return Shell.NO_FIXED_ARG_LENGTH_CHECK;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DebugCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DebugCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DebugCommand.java
deleted file mode 100644
index 206b5901..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DebugCommand.java
+++ /dev/null
@@ -1,71 +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.accumulo.core.util.shell.commands;
-
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.accumulo.core.util.BadArgumentException;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.accumulo.core.util.shell.Token;
-import org.apache.commons.cli.CommandLine;
-
-public class DebugCommand extends Command {
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws IOException {
-    if (cl.getArgs().length == 1) {
-      if (cl.getArgs()[0].equalsIgnoreCase("on")) {
-        Shell.setDebugging(true);
-      } else if (cl.getArgs()[0].equalsIgnoreCase("off")) {
-        Shell.setDebugging(false);
-      } else {
-        throw new BadArgumentException("Argument must be 'on' or 'off'", fullCommand, fullCommand.indexOf(cl.getArgs()[0]));
-      }
-    } else if (cl.getArgs().length == 0) {
-      shellState.getReader().println(Shell.isDebuggingEnabled() ? "on" : "off");
-    } else {
-      shellState.printException(new IllegalArgumentException("Expected 0 or 1 argument. There were " + cl.getArgs().length + "."));
-      printHelp(shellState);
-      return 1;
-    }
-    return 0;
-  }
-  
-  @Override
-  public String description() {
-    return "turns debug logging on or off";
-  }
-  
-  @Override
-  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> special) {
-    final Token debug_command = new Token(getName());
-    debug_command.addSubcommand(Arrays.asList(new String[] {"on", "off"}));
-    root.addSubcommand(debug_command);
-  }
-  
-  @Override
-  public String usage() {
-    return getName() + " [ on | off ]";
-  }
-  
-  @Override
-  public int numArgs() {
-    return Shell.NO_FIXED_ARG_LENGTH_CHECK;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteCommand.java
deleted file mode 100644
index b409ccc..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteCommand.java
+++ /dev/null
@@ -1,112 +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.accumulo.core.util.shell.commands;
-
-import java.io.IOException;
-import java.util.concurrent.TimeUnit;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.BatchWriter;
-import org.apache.accumulo.core.client.BatchWriterConfig;
-import org.apache.accumulo.core.client.TableNotFoundException;
-import org.apache.accumulo.core.conf.AccumuloConfiguration;
-import org.apache.accumulo.core.data.Mutation;
-import org.apache.accumulo.core.security.ColumnVisibility;
-import org.apache.accumulo.core.tabletserver.thrift.ConstraintViolationException;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-import org.apache.hadoop.io.Text;
-
-public class DeleteCommand extends Command {
-  private Option deleteOptAuths, timestampOpt;
-  private Option timeoutOption;
-  
-  protected long getTimeout(final CommandLine cl) {
-    if (cl.hasOption(timeoutOption.getLongOpt())) {
-      return AccumuloConfiguration.getTimeInMillis(cl.getOptionValue(timeoutOption.getLongOpt()));
-    }
-    
-    return Long.MAX_VALUE;
-  }
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException,
-      TableNotFoundException, IOException, ConstraintViolationException {
-    shellState.checkTableState();
-    
-    final Mutation m = new Mutation(new Text(cl.getArgs()[0].getBytes(Shell.CHARSET)));
-    final Text colf = new Text(cl.getArgs()[1].getBytes(Shell.CHARSET));
-    final Text colq = new Text(cl.getArgs()[2].getBytes(Shell.CHARSET));
-    
-    if (cl.hasOption(deleteOptAuths.getOpt())) {
-      final ColumnVisibility le = new ColumnVisibility(cl.getOptionValue(deleteOptAuths.getOpt()));
-      if (cl.hasOption(timestampOpt.getOpt())) {
-        m.putDelete(colf, colq, le, Long.parseLong(cl.getOptionValue(timestampOpt.getOpt())));
-      } else {
-        m.putDelete(colf, colq, le);
-      }
-    } else if (cl.hasOption(timestampOpt.getOpt())) {
-      m.putDelete(colf, colq, Long.parseLong(cl.getOptionValue(timestampOpt.getOpt())));
-    } else {
-      m.putDelete(colf, colq);
-    }
-    final BatchWriter bw = shellState.getConnector().createBatchWriter(shellState.getTableName(),
-        new BatchWriterConfig().setMaxMemory(Math.max(m.estimatedMemoryUsed(), 1024)).setMaxWriteThreads(1).setTimeout(getTimeout(cl), TimeUnit.MILLISECONDS));
-    bw.addMutation(m);
-    bw.close();
-    return 0;
-  }
-  
-  @Override
-  public String description() {
-    return "deletes a record from a table";
-  }
-  
-  @Override
-  public String usage() {
-    return getName() + " <row> <colfamily> <colqualifier>";
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-    
-    deleteOptAuths = new Option("l", "visibility-label", true, "formatted visibility");
-    deleteOptAuths.setArgName("expression");
-    o.addOption(deleteOptAuths);
-    
-    timestampOpt = new Option("ts", "timestamp", true, "timestamp to use for deletion");
-    timestampOpt.setArgName("timestamp");
-    o.addOption(timestampOpt);
-    
-    timeoutOption = new Option(null, "timeout", true,
-        "time before insert should fail if no data is written. If no unit is given assumes seconds.  Units d,h,m,s,and ms are supported.  e.g. 30s or 100ms");
-    timeoutOption.setArgName("timeout");
-    o.addOption(timeoutOption);
-    
-    return o;
-  }
-  
-  @Override
-  public int numArgs() {
-    return 3;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteIterCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteIterCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteIterCommand.java
deleted file mode 100644
index c100325..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteIterCommand.java
+++ /dev/null
@@ -1,114 +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.accumulo.core.util.shell.commands;
-
-import java.util.EnumSet;
-
-import org.apache.accumulo.core.iterators.IteratorUtil.IteratorScope;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.OptionGroup;
-import org.apache.commons.cli.Options;
-
-public class DeleteIterCommand extends Command {
-  private Option allScopeOpt, mincScopeOpt, majcScopeOpt, scanScopeOpt, nameOpt;
-
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-
-    boolean tables = cl.hasOption(OptUtil.tableOpt().getOpt()) || !shellState.getTableName().isEmpty();
-    boolean namespaces = cl.hasOption(OptUtil.namespaceOpt().getOpt());
-
-    final String name = cl.getOptionValue(nameOpt.getOpt());
-
-    if (namespaces) {
-      if (!shellState.getConnector().namespaceOperations().listIterators(OptUtil.getNamespaceOpt(cl, shellState)).containsKey(name)) {
-        Shell.log.warn("no iterators found that match your criteria");
-        return 0;
-      }
-    } else if (tables) {
-      if (!shellState.getConnector().tableOperations().listIterators(OptUtil.getTableOpt(cl, shellState)).containsKey(name)) {
-        Shell.log.warn("no iterators found that match your criteria");
-        return 0;
-      }
-    } else {
-      throw new IllegalArgumentException("No table or namespace specified");
-    }
-
-    final EnumSet<IteratorScope> scopes = EnumSet.noneOf(IteratorScope.class);
-    if (cl.hasOption(allScopeOpt.getOpt()) || cl.hasOption(mincScopeOpt.getOpt())) {
-      scopes.add(IteratorScope.minc);
-    }
-    if (cl.hasOption(allScopeOpt.getOpt()) || cl.hasOption(majcScopeOpt.getOpt())) {
-      scopes.add(IteratorScope.majc);
-    }
-    if (cl.hasOption(allScopeOpt.getOpt()) || cl.hasOption(scanScopeOpt.getOpt())) {
-      scopes.add(IteratorScope.scan);
-    }
-    if (scopes.isEmpty()) {
-      throw new IllegalArgumentException("You must select at least one scope to configure");
-    }
-
-    if (namespaces) {
-      shellState.getConnector().namespaceOperations().removeIterator(OptUtil.getNamespaceOpt(cl, shellState), name, scopes);
-    } else if (tables) {
-      shellState.getConnector().tableOperations().removeIterator(OptUtil.getTableOpt(cl, shellState), name, scopes);
-    } else {
-      throw new IllegalArgumentException("No table or namespace specified");
-    }
-    return 0;
-  }
-
-  @Override
-  public String description() {
-    return "deletes a table-specific or namespace-specific iterator";
-  }
-
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-
-    nameOpt = new Option("n", "name", true, "iterator to delete");
-    nameOpt.setArgName("itername");
-    nameOpt.setRequired(true);
-
-    allScopeOpt = new Option("all", "all-scopes", false, "remove from all scopes");
-    mincScopeOpt = new Option(IteratorScope.minc.name(), "minor-compaction", false, "remove from minor compaction scope");
-    majcScopeOpt = new Option(IteratorScope.majc.name(), "major-compaction", false, "remove from major compaction scope");
-    scanScopeOpt = new Option(IteratorScope.scan.name(), "scan-time", false, "remove from scan scope");
-
-    OptionGroup grp = new OptionGroup();
-    grp.addOption(OptUtil.tableOpt("table to delete the iterator from"));
-    grp.addOption(OptUtil.namespaceOpt("namespace to delete the iterator from"));
-    o.addOptionGroup(grp);
-    o.addOption(nameOpt);
-
-    o.addOption(allScopeOpt);
-    o.addOption(mincScopeOpt);
-    o.addOption(majcScopeOpt);
-    o.addOption(scanScopeOpt);
-
-    return o;
-  }
-
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteManyCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteManyCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteManyCommand.java
deleted file mode 100644
index 7518bf9..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteManyCommand.java
+++ /dev/null
@@ -1,82 +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.accumulo.core.util.shell.commands;
-
-import java.util.concurrent.TimeUnit;
-
-import org.apache.accumulo.core.client.BatchWriter;
-import org.apache.accumulo.core.client.BatchWriterConfig;
-import org.apache.accumulo.core.client.IteratorSetting;
-import org.apache.accumulo.core.client.Scanner;
-import org.apache.accumulo.core.iterators.SortedKeyIterator;
-import org.apache.accumulo.core.security.Authorizations;
-import org.apache.accumulo.core.util.format.DeleterFormatter;
-import org.apache.accumulo.core.util.interpret.ScanInterpreter;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-
-public class DeleteManyCommand extends ScanCommand {
-  private Option forceOpt;
-  
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    final String tableName = OptUtil.getTableOpt(cl, shellState);
-    
-    final ScanInterpreter interpeter = getInterpreter(cl, tableName, shellState);
-
-    // handle first argument, if present, the authorizations list to
-    // scan with
-    final Authorizations auths = getAuths(cl, shellState);
-    final Scanner scanner = shellState.getConnector().createScanner(tableName, auths);
-    
-    scanner.addScanIterator(new IteratorSetting(Integer.MAX_VALUE, "NOVALUE", SortedKeyIterator.class));
-    
-    // handle session-specific scan iterators
-    addScanIterators(shellState, cl, scanner, tableName);
-    
-    // handle remaining optional arguments
-    scanner.setRange(getRange(cl, interpeter));
-    
-    scanner.setTimeout(getTimeout(cl), TimeUnit.MILLISECONDS);
-
-    // handle columns
-    fetchColumns(cl, scanner, interpeter);
-    
-    // output / delete the records
-    final BatchWriter writer = shellState.getConnector()
-        .createBatchWriter(tableName, new BatchWriterConfig().setTimeout(getTimeout(cl), TimeUnit.MILLISECONDS));
-    shellState.printLines(new DeleterFormatter(writer, scanner, cl.hasOption(timestampOpt.getOpt()), shellState, cl.hasOption(forceOpt.getOpt())), false);
-    
-    return 0;
-  }
-  
-  @Override
-  public String description() {
-    return "scans a table and deletes the resulting records";
-  }
-  
-  @Override
-  public Options getOptions() {
-    forceOpt = new Option("f", "force", false, "force deletion without prompting");
-    final Options opts = super.getOptions();
-    opts.addOption(forceOpt);
-    opts.addOption(OptUtil.tableOpt("table to delete entries from"));
-    return opts;
-  }
-  
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteNamespaceCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteNamespaceCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteNamespaceCommand.java
deleted file mode 100644
index 01d7fc0..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteNamespaceCommand.java
+++ /dev/null
@@ -1,100 +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.accumulo.core.util.shell.commands;
-
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.accumulo.core.client.NamespaceNotFoundException;
-import org.apache.accumulo.core.client.impl.Namespaces;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.accumulo.core.util.shell.Token;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-
-public class DeleteNamespaceCommand extends Command {
-  private Option forceOpt;
-
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    boolean force = false;
-    boolean operate = true;
-    if (cl.hasOption(forceOpt.getOpt())) {
-      force = true;
-    }
-    String namespace = cl.getArgs()[0];
-
-    if (!force) {
-      shellState.getReader().flush();
-      String line = shellState.getReader().readLine(getName() + " { " + namespace + " } (yes|no)? ");
-      operate = line != null && (line.equalsIgnoreCase("y") || line.equalsIgnoreCase("yes"));
-    }
-    if (operate) {
-      doTableOp(shellState, namespace, force);
-    }
-    return 0;
-  }
-
-  @Override
-  public String description() {
-    return "deletes a namespace";
-  }
-
-  protected void doTableOp(final Shell shellState, final String namespace, boolean force) throws Exception {
-    boolean resetContext = false;
-    String currentTable = shellState.getTableName();
-    if (!Namespaces.getNameToIdMap(shellState.getInstance()).containsKey(namespace)) {
-      throw new NamespaceNotFoundException(null, namespace, null);
-    }
-
-    String namespaceId = Namespaces.getNamespaceId(shellState.getInstance(), namespace);
-    List<String> tables = Namespaces.getTableNames(shellState.getInstance(), namespaceId);
-    resetContext = tables.contains(currentTable);
-
-    if (force)
-      for (String table : shellState.getConnector().tableOperations().list())
-        if (table.startsWith(namespace + "."))
-          shellState.getConnector().tableOperations().delete(table);
-
-    shellState.getConnector().namespaceOperations().delete(namespace);
-    if (resetContext) {
-      shellState.setTableName("");
-    }
-  }
-
-  @Override
-  public Options getOptions() {
-    forceOpt = new Option("f", "force", false, "force deletion without prompting");
-    final Options opts = super.getOptions();
-
-    opts.addOption(forceOpt);
-    return opts;
-  }
-
-  @Override
-  public int numArgs() {
-    return 1;
-  }
-
-  @Override
-  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> special) {
-    registerCompletionForNamespaces(root, special);
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteRowsCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteRowsCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteRowsCommand.java
deleted file mode 100644
index 1414b4d..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteRowsCommand.java
+++ /dev/null
@@ -1,65 +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.accumulo.core.util.shell.commands;
-
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-import org.apache.hadoop.io.Text;
-
-public class DeleteRowsCommand extends Command {
-  private Option forceOpt;
-  private Option startRowOptExclusive;
- 
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    final String tableName = OptUtil.getTableOpt(cl, shellState);
-    final Text startRow = OptUtil.getStartRow(cl);
-    final Text endRow = OptUtil.getEndRow(cl);
-    if (!cl.hasOption(forceOpt.getOpt()) && (startRow == null || endRow == null)) {
-      shellState.getReader().println("Not deleting unbounded range. Specify both ends, or use --force");
-      return 1;
-    }
-    shellState.getConnector().tableOperations().deleteRows(tableName, startRow, endRow);
-    return 0;
-  }
-  
-  @Override
-  public String description() {
-    return "deletes a range of rows in a table.  Note that rows matching the start row ARE NOT deleted, but rows matching the end row ARE deleted.";
-  }
-  
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-    forceOpt = new Option("f", "force", false, "delete data even if start or end are not specified");
-    startRowOptExclusive = new Option(OptUtil.START_ROW_OPT, "begin-row", true, "begin row (exclusive)");
-    startRowOptExclusive.setArgName("begin-row");
-    o.addOption(startRowOptExclusive);
-    o.addOption(OptUtil.endRowOpt());
-    o.addOption(OptUtil.tableOpt("table to delete a row range from"));
-    o.addOption(forceOpt);
-    return o;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteScanIterCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteScanIterCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteScanIterCommand.java
deleted file mode 100644
index 9b8699b..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteScanIterCommand.java
+++ /dev/null
@@ -1,102 +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.accumulo.core.util.shell.commands;
-
-import java.util.Iterator;
-import java.util.List;
-
-import org.apache.accumulo.core.client.IteratorSetting;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.OptionGroup;
-import org.apache.commons.cli.Options;
-
-public class DeleteScanIterCommand extends Command {
-  private Option nameOpt, allOpt;
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    final String tableName = OptUtil.getTableOpt(cl, shellState);
-    
-    if (cl.hasOption(allOpt.getOpt())) {
-      final List<IteratorSetting> tableScanIterators = shellState.scanIteratorOptions.remove(tableName);
-      if (tableScanIterators == null) {
-        Shell.log.info("No scan iterators set on table " + tableName);
-      } else {
-        Shell.log.info("Removed the following scan iterators from table " + tableName + ":" + tableScanIterators);
-      }
-    } else if (cl.hasOption(nameOpt.getOpt())) {
-      final String name = cl.getOptionValue(nameOpt.getOpt());
-      final List<IteratorSetting> tableScanIterators = shellState.scanIteratorOptions.get(tableName);
-      if (tableScanIterators != null) {
-        boolean found = false;
-        for (Iterator<IteratorSetting> iter = tableScanIterators.iterator(); iter.hasNext();) {
-          if (iter.next().getName().equals(name)) {
-            iter.remove();
-            found = true;
-            break;
-          }
-        }
-        if (!found) {
-          Shell.log.info("No iterator named " + name + " found for table " + tableName);
-        } else {
-          Shell.log.info("Removed scan iterator " + name + " from table " + tableName + " (" + shellState.scanIteratorOptions.get(tableName).size() + " left)");
-          if (shellState.scanIteratorOptions.get(tableName).size() == 0) {
-            shellState.scanIteratorOptions.remove(tableName);
-          }
-        }
-      } else {
-        Shell.log.info("No iterator named " + name + " found for table " + tableName);
-      }
-    }
-    
-    return 0;
-  }
-  
-  @Override
-  public String description() {
-    return "deletes a table-specific scan iterator so it is no longer used during this shell session";
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-    
-    OptionGroup nameGroup = new OptionGroup();
-    
-    nameOpt = new Option("n", "name", true, "iterator to delete");
-    nameOpt.setArgName("itername");
-    
-    allOpt = new Option("a", "all", false, "delete all scan iterators");
-    allOpt.setArgName("all");
-    
-    nameGroup.addOption(nameOpt);
-    nameGroup.addOption(allOpt);
-    nameGroup.setRequired(true);
-    o.addOptionGroup(nameGroup);
-    o.addOption(OptUtil.tableOpt("table to delete scan iterators from"));
-    
-    return o;
-  }
-  
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteShellIterCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteShellIterCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteShellIterCommand.java
deleted file mode 100644
index 89060c1..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteShellIterCommand.java
+++ /dev/null
@@ -1,100 +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.accumulo.core.util.shell.commands;
-
-import java.util.Iterator;
-import java.util.List;
-
-import org.apache.accumulo.core.client.IteratorSetting;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.OptionGroup;
-import org.apache.commons.cli.Options;
-
-public class DeleteShellIterCommand extends Command {
-  private Option nameOpt, allOpt, profileOpt;
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-
-    String profile = cl.getOptionValue(profileOpt.getOpt());
-    if (shellState.iteratorProfiles.containsKey(profile)) {
-      if (cl.hasOption(allOpt.getOpt())) {
-        shellState.iteratorProfiles.remove(profile);
-        Shell.log.info("Removed profile " + profile);
-      } else {
-        List<IteratorSetting> iterSettings = shellState.iteratorProfiles.get(profile);
-        String name = cl.getOptionValue(nameOpt.getOpt());
-        boolean found = false;
-        for (Iterator<IteratorSetting> iter = iterSettings.iterator(); iter.hasNext();) {
-          if (iter.next().getName().equals(name)) {
-            iter.remove();
-            found = true;
-            break;
-          }
-        }
-        if (!found) {
-          Shell.log.info("No iterator named " + name + " found");
-        } else {
-          Shell.log.info("Removed iterator " + name + " from profile " + profile + " (" + iterSettings.size() + " left)");
-        }
-      }
-      
-    } else {
-      Shell.log.info("No profile named " + profile);
-    }
-    
-    return 0;
-  }
-  
-  @Override
-  public String description() {
-    return "deletes iterators profiles configured in this shell session";
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-    
-    OptionGroup nameGroup = new OptionGroup();
-    
-    nameOpt = new Option("n", "name", true, "iterator to delete");
-    nameOpt.setArgName("itername");
-    
-    allOpt = new Option("a", "all", false, "delete all scan iterators");
-    allOpt.setArgName("all");
-    
-    nameGroup.addOption(nameOpt);
-    nameGroup.addOption(allOpt);
-    nameGroup.setRequired(true);
-    o.addOptionGroup(nameGroup);
-    
-    profileOpt = new Option("pn", "profile", true, "iterator profile name");
-    profileOpt.setRequired(true);
-    profileOpt.setArgName("profile");
-    o.addOption(profileOpt);
-
-    return o;
-  }
-  
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteTableCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteTableCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteTableCommand.java
deleted file mode 100644
index a5aa32a..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteTableCommand.java
+++ /dev/null
@@ -1,60 +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.accumulo.core.util.shell.commands;
-
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-
-public class DeleteTableCommand extends TableOperation {
-  private Option forceOpt;
-
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    if (cl.hasOption(forceOpt.getOpt())) {
-      super.force();
-    } else {
-      super.noForce();
-    }
-    return super.execute(fullCommand, cl, shellState);
-  }
-
-  @Override
-  public String description() {
-    return "deletes a table";
-  }
-
-  @Override
-  protected void doTableOp(final Shell shellState, final String tableName) throws Exception {
-    shellState.getConnector().tableOperations().delete(tableName);
-    shellState.getReader().println("Table: [" + tableName + "] has been deleted.");
-
-    if (shellState.getTableName().equals(tableName)) {
-      shellState.setTableName("");
-    }
-  }
-
-  @Override
-  public Options getOptions() {
-    forceOpt = new Option("f", "force", false, "force deletion without prompting");
-    final Options opts = super.getOptions();
-
-    opts.addOption(forceOpt);
-    return opts;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteUserCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteUserCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteUserCommand.java
deleted file mode 100644
index 4bc563e..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteUserCommand.java
+++ /dev/null
@@ -1,19 +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.accumulo.core.util.shell.commands;
-
-public class DeleteUserCommand extends DropUserCommand {}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DropTableCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DropTableCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DropTableCommand.java
deleted file mode 100644
index 3120d6b..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DropTableCommand.java
+++ /dev/null
@@ -1,19 +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.accumulo.core.util.shell.commands;
-
-public class DropTableCommand extends DeleteTableCommand {}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DropUserCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DropUserCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DropUserCommand.java
deleted file mode 100644
index 5aa0fb6..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DropUserCommand.java
+++ /dev/null
@@ -1,61 +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.accumulo.core.util.shell.commands;
-
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.util.BadArgumentException;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.accumulo.core.util.shell.Token;
-import org.apache.commons.cli.CommandLine;
-
-public class DropUserCommand extends Command {
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException {
-    final String user = cl.getArgs()[0];
-    if (shellState.getConnector().whoami().equals(user)) {
-      throw new BadArgumentException("You cannot delete yourself", fullCommand, fullCommand.indexOf(user));
-    }
-    shellState.getConnector().securityOperations().dropLocalUser(user);
-    Shell.log.debug("Deleted user " + user);
-    return 0;
-  }
-  
-  @Override
-  public String description() {
-    return "deletes a user";
-  }
-  
-  @Override
-  public String usage() {
-    return getName() + " <username>";
-  }
-  
-  @Override
-  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> completionSet) {
-    registerCompletionForUsers(root, completionSet);
-  }
-  
-  @Override
-  public int numArgs() {
-    return 1;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/EGrepCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/EGrepCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/EGrepCommand.java
deleted file mode 100644
index d63991a..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/EGrepCommand.java
+++ /dev/null
@@ -1,59 +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.accumulo.core.util.shell.commands;
-
-import java.io.IOException;
-
-import org.apache.accumulo.core.client.BatchScanner;
-import org.apache.accumulo.core.client.IteratorSetting;
-import org.apache.accumulo.core.iterators.user.RegExFilter;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-
-public class EGrepCommand extends GrepCommand {
-  
-  private Option matchSubstringOption;
-  
-  @Override
-  protected void setUpIterator(final int prio, final String name, final String term, final BatchScanner scanner, CommandLine cl) throws IOException {
-    if (prio < 0) {
-      throw new IllegalArgumentException("Priority < 0 " + prio);
-    }
-    final IteratorSetting si = new IteratorSetting(prio, name, RegExFilter.class);
-    RegExFilter.setRegexs(si, term, term, term, term, true, cl.hasOption(matchSubstringOption.getOpt()));
-    scanner.addScanIterator(si);
-  }
-  
-  @Override
-  public String description() {
-    return "searches each row, column family, column qualifier and value, in parallel, on the server side (using a java Matcher, so put .* before and after your term if you're not matching the whole element)";
-  }
-  
-  @Override
-  public String usage() {
-    return getName() + " <regex>{ <regex>}";
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options opts = super.getOptions();
-    matchSubstringOption = new Option("g", "global", false, "forces the use of the find() expression matcher, causing substring matches to return true");
-    opts.addOption(matchSubstringOption);
-    return opts;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ExecfileCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ExecfileCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ExecfileCommand.java
deleted file mode 100644
index f4a2632..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ExecfileCommand.java
+++ /dev/null
@@ -1,67 +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.accumulo.core.util.shell.commands;
-
-import java.io.File;
-import java.nio.charset.StandardCharsets;
-import java.util.Scanner;
-
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-
-public class ExecfileCommand extends Command {
-  private Option verboseOption;
-  
-  @Override
-  public String description() {
-    return "specifies a file containing accumulo commands to execute";
-  }
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    Scanner scanner = new Scanner(new File(cl.getArgs()[0]), StandardCharsets.UTF_8.name());
-    try {
-      while (scanner.hasNextLine()) {
-        shellState.execCommand(scanner.nextLine(), true, cl.hasOption(verboseOption.getOpt()));
-      }
-    } finally {
-      scanner.close();
-    }
-    return 0;
-  }
-  
-  @Override
-  public String usage() {
-    return getName() + " <fileName>";
-  }
-  
-  @Override
-  public int numArgs() {
-    return 1;
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options opts = new Options();
-    verboseOption = new Option("v", "verbose", false, "display command prompt as commands are executed");
-    opts.addOption(verboseOption);
-    return opts;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ExitCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ExitCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ExitCommand.java
deleted file mode 100644
index c78b020..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ExitCommand.java
+++ /dev/null
@@ -1,39 +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.accumulo.core.util.shell.commands;
-
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-
-public class ExitCommand extends Command {
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) {
-    shellState.setExit(true);
-    return 0;
-  }
-  
-  @Override
-  public String description() {
-    return "exits the shell";
-  }
-  
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ExportTableCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ExportTableCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ExportTableCommand.java
deleted file mode 100644
index 5fd5abb..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ExportTableCommand.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.accumulo.core.util.shell.commands;
-
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.TableExistsException;
-import org.apache.accumulo.core.client.TableNotFoundException;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.accumulo.core.util.shell.Token;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-
-public class ExportTableCommand extends Command {
-  
-  private Option tableOpt;
-
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException, TableNotFoundException,
-      TableExistsException {
-    
-    final String tableName = OptUtil.getTableOpt(cl, shellState);
-
-    shellState.getConnector().tableOperations().exportTable(tableName, cl.getArgs()[0]);
-    return 0;
-  }
-  
-  @Override
-  public String usage() {
-    return getName() + " <export dir>";
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-    
-    tableOpt = new Option(Shell.tableOption, "table", true, "table to export");
-    
-    tableOpt.setArgName("table");
-    
-    o.addOption(tableOpt);
-
-    return o;
-  }
-  
-  @Override
-  public String description() {
-    return "exports a table";
-  }
-  
-  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> completionSet) {
-    registerCompletionForTables(root, completionSet);
-  }
-  
-  @Override
-  public int numArgs() {
-    return 1;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ExtensionCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ExtensionCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ExtensionCommand.java
deleted file mode 100644
index ab29d19..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ExtensionCommand.java
+++ /dev/null
@@ -1,102 +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.accumulo.core.util.shell.commands;
-
-import java.util.HashSet;
-import java.util.ServiceLoader;
-import java.util.Set;
-import java.util.TreeSet;
-
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.accumulo.core.util.shell.ShellExtension;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-
-public class ExtensionCommand extends Command {
-  
-  protected Option enable, disable, list;
-  
-  private static ServiceLoader<ShellExtension> extensions = null;
-  
-  private Set<String> loadedHeaders = new HashSet<String>();
-  private Set<String> loadedCommands = new HashSet<String>();
-  private Set<String> loadedExtensions = new TreeSet<String>();
-  
-  public int execute(String fullCommand, CommandLine cl, Shell shellState) throws Exception {
-    if (cl.hasOption(enable.getOpt())) {
-      extensions = ServiceLoader.load(ShellExtension.class);
-      for (ShellExtension se : extensions) {
-        
-        loadedExtensions.add(se.getExtensionName());
-        String header = "-- " + se.getExtensionName() + " Extension Commands ---------";
-        loadedHeaders.add(header);
-        shellState.commandGrouping.put(header, se.getCommands());
-        
-        for (Command cmd : se.getCommands()) {
-          String name = se.getExtensionName() + "::" + cmd.getName();
-          loadedCommands.add(name);
-          shellState.commandFactory.put(name, cmd);
-        }
-      }
-    } else if (cl.hasOption(disable.getOpt())) {
-      //Remove the headers
-      for (String header : loadedHeaders) {
-        shellState.commandGrouping.remove(header);
-      }
-      //remove the commands
-      for (String name : loadedCommands) {
-        shellState.commandFactory.remove(name);
-      }
-      //Reset state
-      loadedExtensions.clear();
-      extensions.reload();
-    } else if (cl.hasOption(list.getOpt())) {
-      shellState.printLines(loadedExtensions.iterator(), true);
-    } else {
-      printHelp(shellState);
-    }
-    return 0;
-  }
-  
-  public String description() {
-    return "Enable, disable, or list shell extensions";
-  }
-  
-  public int numArgs() {
-    return 0;
-  }
-  
-  @Override
-  public String getName() {
-    return "extensions";
-  }
-
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-    enable = new Option("e", "enable", false, "enable shell extensions");
-    disable = new Option("d", "disable", false, "disable shell extensions");
-    list = new Option("l", "list", false, "list shell extensions");
-    o.addOption(enable);
-    o.addOption(disable);
-    o.addOption(list);
-    return o;
-  }
-    
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/FateCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/FateCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/FateCommand.java
deleted file mode 100644
index 0196baf..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/FateCommand.java
+++ /dev/null
@@ -1,180 +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.accumulo.core.util.shell.commands;
-
-import java.io.IOException;
-import java.util.Collections;
-import java.util.EnumSet;
-import java.util.Formatter;
-import java.util.HashSet;
-import java.util.Set;
-
-import org.apache.accumulo.core.Constants;
-import org.apache.accumulo.core.client.Instance;
-import org.apache.accumulo.core.conf.AccumuloConfiguration;
-import org.apache.accumulo.core.conf.Property;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.accumulo.core.zookeeper.ZooUtil;
-import org.apache.accumulo.fate.AdminUtil;
-import org.apache.accumulo.fate.ReadOnlyTStore.TStatus;
-import org.apache.accumulo.fate.ZooStore;
-import org.apache.accumulo.fate.zookeeper.IZooReaderWriter;
-import org.apache.accumulo.fate.zookeeper.ZooReaderWriter;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-import org.apache.commons.cli.ParseException;
-import org.apache.zookeeper.KeeperException;
-
-/**
- * Manage FATE transactions
- * 
- */
-public class FateCommand extends Command {
-  
-  private static final String SCHEME = "digest";
-  
-  private static final String USER = "accumulo";
-  
-  private Option secretOption;
-  private Option statusOption;
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws ParseException, KeeperException, InterruptedException,
-      IOException {
-    Instance instance = shellState.getInstance();
-    String[] args = cl.getArgs();
-    if (args.length <= 0) {
-      throw new ParseException("Must provide a command to execute");
-    }
-    String cmd = args[0];
-    boolean failedCommand = false;
-    
-    AdminUtil<FateCommand> admin = new AdminUtil<FateCommand>(false);
-    
-    String path = ZooUtil.getRoot(instance) + Constants.ZFATE;
-    String masterPath = ZooUtil.getRoot(instance) + Constants.ZMASTER_LOCK;
-    IZooReaderWriter zk = getZooReaderWriter(shellState.getInstance(), cl.getOptionValue(secretOption.getOpt()));
-    ZooStore<FateCommand> zs = new ZooStore<FateCommand>(path, zk);
-    
-    if ("fail".equals(cmd)) {
-      if (args.length <= 1) {
-        throw new ParseException("Must provide transaction ID");
-      }
-      for (int i = 1; i < args.length; i++) {
-        if (!admin.prepFail(zs, zk, masterPath, args[i])) {
-          System.out.printf("Could not fail transaction: %s%n", args[i]);
-          failedCommand = true;
-        }
-      }
-    } else if ("delete".equals(cmd)) {
-      if (args.length <= 1) {
-        throw new ParseException("Must provide transaction ID");
-      }
-      for (int i = 1; i < args.length; i++) {
-        if (admin.prepDelete(zs, zk, masterPath, args[i])) {
-          admin.deleteLocks(zs, zk, ZooUtil.getRoot(instance) + Constants.ZTABLE_LOCKS, args[i]);
-        } else {
-          System.out.printf("Could not delete transaction: %s%n", args[i]);
-          failedCommand = true;
-        }
-      }
-    } else if ("list".equals(cmd) || "print".equals(cmd)) {
-      // Parse transaction ID filters for print display
-      Set<Long> filterTxid = null;
-      if (args.length >= 2) {
-        filterTxid = new HashSet<Long>(args.length);
-        for (int i = 1; i < args.length; i++) {
-          try {
-            Long val = Long.parseLong(args[i], 16);
-            filterTxid.add(val);
-          } catch (NumberFormatException nfe) {
-            // Failed to parse, will exit instead of displaying everything since the intention was to potentially filter some data
-            System.out.printf("Invalid transaction ID format: %s%n", args[i]);
-            return 1;
-          }
-        }
-      }
-      
-      // Parse TStatus filters for print display
-      EnumSet<TStatus> filterStatus = null;
-      if (cl.hasOption(statusOption.getOpt())) {
-        filterStatus = EnumSet.noneOf(TStatus.class);
-        String[] tstat = cl.getOptionValues(statusOption.getOpt());
-        for (int i = 0; i < tstat.length; i++) {
-          try {
-            filterStatus.add(TStatus.valueOf(tstat[i]));
-          } catch (IllegalArgumentException iae) {
-            System.out.printf("Invalid transaction status name: %s%n", tstat[i]);
-            return 1;
-          }
-        }
-      }
-      
-      StringBuilder buf = new StringBuilder(8096);
-      Formatter fmt = new Formatter(buf);
-      admin.print(zs, zk, ZooUtil.getRoot(instance) + Constants.ZTABLE_LOCKS, fmt, filterTxid, filterStatus);
-      shellState.printLines(Collections.singletonList(buf.toString()).iterator(), true);
-    } else {
-      throw new ParseException("Invalid command option");
-    }
-    
-    return failedCommand ? 1 : 0;
-  }
-  
-  protected synchronized IZooReaderWriter getZooReaderWriter(Instance instance, String secret) {
-    
-    if (secret == null) {
-      @SuppressWarnings("deprecation")
-      AccumuloConfiguration conf = AccumuloConfiguration.getSiteConfiguration();
-      secret = conf.get(Property.INSTANCE_SECRET);
-    }
-    
-    return new ZooReaderWriter(instance.getZooKeepers(), instance.getZooKeepersSessionTimeOut(), SCHEME, (USER + ":" + secret).getBytes());
-  }
-  
-  @Override
-  public String description() {
-    return "manage FATE transactions";
-  }
-  
-  @Override
-  public String usage() {
-    return getName() + " fail <txid>... | delete <txid>... | print [<txid>...]";
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-    secretOption = new Option("s", "secret", true, "specify the instance secret to use");
-    secretOption.setOptionalArg(false);
-    o.addOption(secretOption);
-    statusOption = new Option("t", "status-type", true,
-        "filter 'print' on the transaction status type(s) {NEW, IN_PROGRESS, FAILED_IN_PROGRESS, FAILED, SUCCESSFUL}");
-    statusOption.setArgs(Option.UNLIMITED_VALUES);
-    statusOption.setOptionalArg(false);
-    o.addOption(statusOption);
-    return o;
-  }
-  
-  @Override
-  public int numArgs() {
-    // Arg length varies between 1 to n
-    return -1;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/FlushCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/FlushCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/FlushCommand.java
deleted file mode 100644
index de175eb..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/FlushCommand.java
+++ /dev/null
@@ -1,63 +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.accumulo.core.util.shell.commands;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.TableNotFoundException;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-import org.apache.hadoop.io.Text;
-
-public class FlushCommand extends TableOperation {
-  private Text startRow;
-  private Text endRow;
-  
-  private boolean wait;
-  private Option waitOpt;
-  
-  @Override
-  public String description() {
-    return "flushes a tables data that is currently in memory to disk";
-  }
-  
-  protected void doTableOp(final Shell shellState, final String tableName) throws AccumuloException, AccumuloSecurityException, TableNotFoundException {
-    shellState.getConnector().tableOperations().flush(tableName, startRow, endRow, wait);
-    Shell.log.info("Flush of table " + tableName + (wait ? " completed." : " initiated..."));
-  }
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    wait = cl.hasOption(waitOpt.getLongOpt());
-    startRow = OptUtil.getStartRow(cl);
-    endRow = OptUtil.getEndRow(cl);
-    return super.execute(fullCommand, cl, shellState);
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options opts = super.getOptions();
-    waitOpt = new Option("w", "wait", false, "wait for flush to finish");
-    opts.addOption(waitOpt);
-    opts.addOption(OptUtil.startRowOpt());
-    opts.addOption(OptUtil.endRowOpt());
-    
-    return opts;
-  }
-}


[25/53] [abbrv] Revert "ACCUMULO-1897 Move shell into new package and module"

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/AddAuthsCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/AddAuthsCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/AddAuthsCommand.java
deleted file mode 100644
index 27fea1e..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/AddAuthsCommand.java
+++ /dev/null
@@ -1,82 +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.accumulo.shell.commands;
-
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.security.Authorizations;
-import org.apache.accumulo.shell.Shell;
-import org.apache.accumulo.shell.Token;
-import org.apache.accumulo.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.OptionGroup;
-import org.apache.commons.cli.Options;
-
-public class AddAuthsCommand extends Command {
-  private Option userOpt;
-  private Option scanOptAuths;
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException {
-    final String user = cl.getOptionValue(userOpt.getOpt(), shellState.getConnector().whoami());
-    final String scanOpts = cl.getOptionValue(scanOptAuths.getOpt());
-    Authorizations auths = shellState.getConnector().securityOperations().getUserAuthorizations(user);
-    StringBuilder userAuths = new StringBuilder();
-    if (!auths.isEmpty()) {
-      userAuths.append(auths.toString());
-      userAuths.append(",");
-    }
-    userAuths.append(scanOpts);
-    shellState.getConnector().securityOperations().changeUserAuthorizations(user, ScanCommand.parseAuthorizations(userAuths.toString()));
-    Shell.log.debug("Changed record-level authorizations for user " + user);
-    return 0;
-  }
-  
-  @Override
-  public String description() {
-    return "adds authorizations to the maximum scan authorizations for a user";
-  }
-  
-  @Override
-  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> completionSet) {
-    registerCompletionForUsers(root, completionSet);
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-    final OptionGroup setOrClear = new OptionGroup();
-    scanOptAuths = new Option("s", "scan-authorizations", true, "scan authorizations to set");
-    scanOptAuths.setArgName("comma-separated-authorizations");
-    setOrClear.addOption(scanOptAuths);
-    setOrClear.setRequired(true);
-    o.addOptionGroup(setOrClear);
-    userOpt = new Option(Shell.userOption, "user", true, "user to operate on");
-    userOpt.setArgName("user");
-    o.addOption(userOpt);
-    return o;
-  }
-  
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/AddSplitsCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/AddSplitsCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/AddSplitsCommand.java
deleted file mode 100644
index b695d4d..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/AddSplitsCommand.java
+++ /dev/null
@@ -1,88 +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.accumulo.shell.commands;
-
-import java.util.TreeSet;
-
-import org.apache.accumulo.core.client.TableNotFoundException;
-import org.apache.accumulo.shell.Shell;
-import org.apache.accumulo.shell.ShellUtil;
-import org.apache.accumulo.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.MissingArgumentException;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-import org.apache.hadoop.io.Text;
-
-public class AddSplitsCommand extends Command {
-  private Option optSplitsFile, base64Opt;
-  
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    final String tableName = OptUtil.getTableOpt(cl, shellState);
-    final boolean decode = cl.hasOption(base64Opt.getOpt());
-    
-    final TreeSet<Text> splits = new TreeSet<Text>();
-    
-    if (cl.hasOption(optSplitsFile.getOpt())) {
-      splits.addAll(ShellUtil.scanFile(cl.getOptionValue(optSplitsFile.getOpt()), decode));
-    } else {
-      if (cl.getArgList().isEmpty()) {
-        throw new MissingArgumentException("No split points specified");
-      }
-      for (String s : cl.getArgs()) {
-        splits.add(new Text(s.getBytes(Shell.CHARSET)));
-      }
-    }
-    
-    if (!shellState.getConnector().tableOperations().exists(tableName)) {
-      throw new TableNotFoundException(null, tableName, null);
-    }
-    shellState.getConnector().tableOperations().addSplits(tableName, splits);
-    
-    return 0;
-  }
-  
-  @Override
-  public String description() {
-    return "adds split points to an existing table";
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-    
-    optSplitsFile = new Option("sf", "splits-file", true, "file with a newline-separated list of rows to split the table with");
-    optSplitsFile.setArgName("filename");
-    
-    base64Opt = new Option("b64", "base64encoded", false, "decode encoded split points (splits file only)");
-    
-    o.addOption(OptUtil.tableOpt("name of the table to add split points to"));
-    o.addOption(optSplitsFile);
-    o.addOption(base64Opt);
-    return o;
-  }
-  
-  @Override
-  public String usage() {
-    return getName() + " [<split>{ <split>} ]";
-  }
-  
-  @Override
-  public int numArgs() {
-    return Shell.NO_FIXED_ARG_LENGTH_CHECK;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/AuthenticateCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/AuthenticateCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/AuthenticateCommand.java
deleted file mode 100644
index 807de24..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/AuthenticateCommand.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.accumulo.shell.commands;
-
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.security.tokens.PasswordToken;
-import org.apache.accumulo.shell.Shell;
-import org.apache.accumulo.shell.Token;
-import org.apache.accumulo.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-
-public class AuthenticateCommand extends Command {
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException, IOException {
-    final String user = cl.getArgs()[0];
-    final String p = shellState.readMaskedLine("Enter current password for '" + user + "': ", '*');
-    if (p == null) {
-      shellState.getReader().println();
-      return 0;
-    } // user canceled
-    final byte[] password = p.getBytes(StandardCharsets.UTF_8);
-    final boolean valid = shellState.getConnector().securityOperations().authenticateUser(user, new PasswordToken(password));
-    shellState.getReader().println((valid ? "V" : "Not v") + "alid");
-    return 0;
-  }
-  
-  @Override
-  public String description() {
-    return "verifies a user's credentials";
-  }
-  
-  @Override
-  public String usage() {
-    return getName() + " <username>";
-  }
-  
-  @Override
-  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> completionSet) {
-    registerCompletionForUsers(root, completionSet);
-  }
-  
-  @Override
-  public int numArgs() {
-    return 1;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/ByeCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/ByeCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/ByeCommand.java
deleted file mode 100644
index 2f3baa9..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/ByeCommand.java
+++ /dev/null
@@ -1,19 +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.accumulo.shell.commands;
-
-public class ByeCommand extends ExitCommand {}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/ClasspathCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/ClasspathCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/ClasspathCommand.java
deleted file mode 100644
index c056581..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/ClasspathCommand.java
+++ /dev/null
@@ -1,55 +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.accumulo.shell.commands;
-
-import java.io.IOException;
-
-import jline.console.ConsoleReader;
-
-import org.apache.accumulo.shell.Shell;
-import org.apache.accumulo.shell.Shell.Command;
-import org.apache.accumulo.start.classloader.vfs.AccumuloVFSClassLoader;
-import org.apache.accumulo.start.classloader.vfs.AccumuloVFSClassLoader.Printer;
-import org.apache.commons.cli.CommandLine;
-
-public class ClasspathCommand extends Command {
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) {
-    final ConsoleReader reader = shellState.getReader();
-    AccumuloVFSClassLoader.printClassPath(new Printer() {
-      @Override
-      public void print(String s) {
-        try {
-          reader.println(s);
-        } catch (IOException ex) {
-          throw new RuntimeException(ex);
-        }
-      }
-    });
-    return 0;
-  }
-  
-  @Override
-  public String description() {
-    return "lists the current files on the classpath";
-  }
-  
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/ClearCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/ClearCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/ClearCommand.java
deleted file mode 100644
index 9340d4e..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/ClearCommand.java
+++ /dev/null
@@ -1,52 +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.accumulo.shell.commands;
-
-import java.io.IOException;
-
-import org.apache.accumulo.shell.Shell;
-import org.apache.accumulo.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-
-public class ClearCommand extends Command {
-  @Override
-  public String description() {
-    return "clears the screen";
-  }
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws IOException {
-    // custom clear screen, so I don't have to redraw the prompt twice
-    if (!shellState.getReader().getTerminal().isAnsiSupported()) {
-      throw new IOException("Terminal does not support ANSI commands");
-    }
-    // send the ANSI code to clear the screen
-    shellState.getReader().print(((char) 27) + "[2J");
-    shellState.getReader().flush();
-    
-    // then send the ANSI code to go to position 1,1
-    shellState.getReader().print(((char) 27) + "[1;1H");
-    shellState.getReader().flush();
-    
-    return 0;
-  }
-  
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/CloneTableCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/CloneTableCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/CloneTableCommand.java
deleted file mode 100644
index 37de39d..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/CloneTableCommand.java
+++ /dev/null
@@ -1,102 +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.accumulo.shell.commands;
-
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.TableExistsException;
-import org.apache.accumulo.core.client.TableNotFoundException;
-import org.apache.accumulo.shell.Shell;
-import org.apache.accumulo.shell.Token;
-import org.apache.accumulo.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-
-public class CloneTableCommand extends Command {
-  
-  private Option setPropsOption;
-  private Option excludePropsOption;
-  private Option noFlushOption;
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException, TableNotFoundException,
-      TableExistsException {
-    
-    final HashMap<String,String> props = new HashMap<String,String>();
-    final HashSet<String> exclude = new HashSet<String>();
-    boolean flush = true;
-    
-    if (cl.hasOption(setPropsOption.getOpt())) {
-      String[] keyVals = cl.getOptionValue(setPropsOption.getOpt()).split(",");
-      for (String keyVal : keyVals) {
-        String[] sa = keyVal.split("=");
-        props.put(sa[0], sa[1]);
-      }
-    }
-    
-    if (cl.hasOption(excludePropsOption.getOpt())) {
-      String[] keys = cl.getOptionValue(excludePropsOption.getOpt()).split(",");
-      for (String key : keys) {
-        exclude.add(key);
-      }
-    }
-    
-    if (cl.hasOption(noFlushOption.getOpt())) {
-      flush = false;
-    }
-    
-    shellState.getConnector().tableOperations().clone(cl.getArgs()[0], cl.getArgs()[1], flush, props, exclude);
-    return 0;
-  }
-  
-  @Override
-  public String usage() {
-    return getName() + " <current table name> <new table name>";
-  }
-  
-  @Override
-  public String description() {
-    return "clones a table";
-  }
-  
-  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> completionSet) {
-    registerCompletionForTables(root, completionSet);
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-    setPropsOption = new Option("s", "set", true, "set initial properties before the table comes online. Expects <prop>=<value>{,<prop>=<value>}");
-    o.addOption(setPropsOption);
-    excludePropsOption = new Option("e", "exclude", true, "exclude properties that should not be copied from source table. Expects <prop>{,<prop>}");
-    o.addOption(excludePropsOption);
-    noFlushOption = new Option("nf", "noFlush", false, "do not flush table data in memory before cloning.");
-    o.addOption(noFlushOption);
-    return o;
-  }
-  
-  @Override
-  public int numArgs() {
-    return 2;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/ClsCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/ClsCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/ClsCommand.java
deleted file mode 100644
index e1ba4fd..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/ClsCommand.java
+++ /dev/null
@@ -1,19 +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.accumulo.shell.commands;
-
-public class ClsCommand extends ClearCommand {}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/CompactCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/CompactCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/CompactCommand.java
deleted file mode 100644
index 80dd9ba..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/CompactCommand.java
+++ /dev/null
@@ -1,129 +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.accumulo.shell.commands;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.IteratorSetting;
-import org.apache.accumulo.core.client.TableNotFoundException;
-import org.apache.accumulo.shell.Shell;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-import org.apache.hadoop.io.Text;
-
-public class CompactCommand extends TableOperation {
-  private Option noFlushOption, waitOpt, profileOpt, cancelOpt;
-  private boolean flush;
-  private Text startRow;
-  private Text endRow;
-  private List<IteratorSetting> iterators;
-  
-  boolean override = false;
-  private boolean wait;
-  
-  private boolean cancel = false;
-
-  @Override
-  public String description() {
-    return "sets all tablets for a table to major compact as soon as possible (based on current time)";
-  }
-  
-  protected void doTableOp(final Shell shellState, final String tableName) throws AccumuloException, AccumuloSecurityException {
-    // compact the tables
-    
-    if (cancel) {
-      try {
-        shellState.getConnector().tableOperations().cancelCompaction(tableName);
-        Shell.log.info("Compaction canceled for table " + tableName);
-      } catch (TableNotFoundException e) {
-        throw new AccumuloException(e);
-      }
-    } else {
-      try {
-        if (wait) {
-          Shell.log.info("Compacting table ...");
-        }
-        
-        shellState.getConnector().tableOperations().compact(tableName, startRow, endRow, iterators, flush, wait);
-        
-        Shell.log.info("Compaction of table " + tableName + " " + (wait ? "completed" : "started") + " for given range");
-      } catch (Exception ex) {
-        throw new AccumuloException(ex);
-      }
-    }
-  }
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    
-    if (cl.hasOption(cancelOpt.getLongOpt())) {
-      cancel = true;
-      
-      if (cl.getOptions().length > 2) {
-        throw new IllegalArgumentException("Can not specify other options with cancel");
-      }
-    } else {
-      cancel = false;
-    }
-
-    flush = !cl.hasOption(noFlushOption.getOpt());
-    startRow = OptUtil.getStartRow(cl);
-    endRow = OptUtil.getEndRow(cl);
-    wait = cl.hasOption(waitOpt.getOpt());
-    
-    if (cl.hasOption(profileOpt.getOpt())) {
-      List<IteratorSetting> iterators = shellState.iteratorProfiles.get(cl.getOptionValue(profileOpt.getOpt()));
-      if (iterators == null) {
-        Shell.log.error("Profile " + cl.getOptionValue(profileOpt.getOpt()) + " does not exist");
-        return -1;
-      }
-      
-      this.iterators = new ArrayList<IteratorSetting>(iterators);
-    } else {
-      this.iterators = Collections.emptyList();
-    }
-
-
-    return super.execute(fullCommand, cl, shellState);
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options opts = super.getOptions();
-    
-    opts.addOption(OptUtil.startRowOpt());
-    opts.addOption(OptUtil.endRowOpt());
-    noFlushOption = new Option("nf", "noFlush", false, "do not flush table data in memory before compacting.");
-    opts.addOption(noFlushOption);
-    waitOpt = new Option("w", "wait", false, "wait for compact to finish");
-    opts.addOption(waitOpt);
-    
-    profileOpt = new Option("pn", "profile", true, "iterator profile name");
-    profileOpt.setArgName("profile");
-    opts.addOption(profileOpt);
-
-    cancelOpt = new Option(null, "cancel", false, "cancel user initiated compactions");
-    opts.addOption(cancelOpt);
-
-    return opts;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/ConfigCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/ConfigCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/ConfigCommand.java
deleted file mode 100644
index 9b39512..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/ConfigCommand.java
+++ /dev/null
@@ -1,315 +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.accumulo.shell.commands;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.TreeMap;
-
-import jline.console.ConsoleReader;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.NamespaceNotFoundException;
-import org.apache.accumulo.core.client.TableNotFoundException;
-import org.apache.accumulo.core.client.impl.Namespaces;
-import org.apache.accumulo.core.client.impl.Tables;
-import org.apache.accumulo.core.conf.AccumuloConfiguration;
-import org.apache.accumulo.core.conf.Property;
-import org.apache.accumulo.core.security.ColumnVisibility;
-import org.apache.accumulo.core.util.BadArgumentException;
-import org.apache.accumulo.shell.Shell;
-import org.apache.accumulo.shell.Token;
-import org.apache.accumulo.shell.Shell.Command;
-import org.apache.accumulo.shell.Shell.PrintFile;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.OptionGroup;
-import org.apache.commons.cli.Options;
-
-public class ConfigCommand extends Command {
-  private Option tableOpt, deleteOpt, setOpt, filterOpt, disablePaginationOpt, outputFileOpt, namespaceOpt;
-
-  private int COL1 = 10, COL2 = 7;
-  private ConsoleReader reader;
-
-  @Override
-  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> completionSet) {
-    final Token cmd = new Token(getName());
-    final Token sub = new Token("-" + setOpt.getOpt());
-    for (Property p : Property.values()) {
-      if (!(p.getKey().endsWith(".")) && !p.isExperimental()) {
-        sub.addSubcommand(new Token(p.toString()));
-      }
-    }
-    cmd.addSubcommand(sub);
-    root.addSubcommand(cmd);
-  }
-
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException,
-      TableNotFoundException, IOException, ClassNotFoundException, NamespaceNotFoundException {
-    reader = shellState.getReader();
-
-    final String tableName = cl.getOptionValue(tableOpt.getOpt());
-    if (tableName != null && !shellState.getConnector().tableOperations().exists(tableName)) {
-      throw new TableNotFoundException(null, tableName, null);
-    }
-    final String namespace = cl.getOptionValue(namespaceOpt.getOpt());
-    if (namespace != null && !shellState.getConnector().namespaceOperations().exists(namespace)) {
-      throw new NamespaceNotFoundException(null, namespace, null);
-    }
-    if (cl.hasOption(deleteOpt.getOpt())) {
-      // delete property from table
-      String property = cl.getOptionValue(deleteOpt.getOpt());
-      if (property.contains("=")) {
-        throw new BadArgumentException("Invalid '=' operator in delete operation.", fullCommand, fullCommand.indexOf('='));
-      }
-      if (tableName != null) {
-        if (!Property.isValidTablePropertyKey(property)) {
-          Shell.log.warn("Invalid per-table property : " + property + ", still removing from zookeeper if it's there.");
-        }
-        shellState.getConnector().tableOperations().removeProperty(tableName, property);
-        Shell.log.debug("Successfully deleted table configuration option.");
-      } else if (namespace != null) {
-        if (!Property.isValidTablePropertyKey(property)) {
-          Shell.log.warn("Invalid per-table property : " + property + ", still removing from zookeeper if it's there.");
-        }
-        shellState.getConnector().namespaceOperations().removeProperty(namespace, property);
-        Shell.log.debug("Successfully deleted namespace configuration option.");
-      } else {
-        if (!Property.isValidZooPropertyKey(property)) {
-          Shell.log.warn("Invalid per-table property : " + property + ", still removing from zookeeper if it's there.");
-        }
-        shellState.getConnector().instanceOperations().removeProperty(property);
-        Shell.log.debug("Successfully deleted system configuration option");
-      }
-    } else if (cl.hasOption(setOpt.getOpt())) {
-      // set property on table
-      String property = cl.getOptionValue(setOpt.getOpt()), value = null;
-      if (!property.contains("=")) {
-        throw new BadArgumentException("Missing '=' operator in set operation.", fullCommand, fullCommand.indexOf(property));
-      }
-      final String pair[] = property.split("=", 2);
-      property = pair[0];
-      value = pair[1];
-
-      if (tableName != null) {
-        if (!Property.isValidTablePropertyKey(property)) {
-          throw new BadArgumentException("Invalid per-table property.", fullCommand, fullCommand.indexOf(property));
-        }
-        if (property.equals(Property.TABLE_DEFAULT_SCANTIME_VISIBILITY.getKey())) {
-          new ColumnVisibility(value); // validate that it is a valid expression
-        }
-        shellState.getConnector().tableOperations().setProperty(tableName, property, value);
-        Shell.log.debug("Successfully set table configuration option.");
-      } else if (namespace != null) {
-        if (!Property.isValidTablePropertyKey(property)) {
-          throw new BadArgumentException("Invalid per-table property.", fullCommand, fullCommand.indexOf(property));
-        }
-        if (property.equals(Property.TABLE_DEFAULT_SCANTIME_VISIBILITY.getKey())) {
-          new ColumnVisibility(value); // validate that it is a valid expression
-        }
-        shellState.getConnector().namespaceOperations().setProperty(namespace, property, value);
-        Shell.log.debug("Successfully set table configuration option.");
-      } else {
-        if (!Property.isValidZooPropertyKey(property)) {
-          throw new BadArgumentException("Property cannot be modified in zookeeper", fullCommand, fullCommand.indexOf(property));
-        }
-        shellState.getConnector().instanceOperations().setProperty(property, value);
-        Shell.log.debug("Successfully set system configuration option");
-      }
-    } else {
-      // display properties
-      final TreeMap<String,String> systemConfig = new TreeMap<String,String>();
-      systemConfig.putAll(shellState.getConnector().instanceOperations().getSystemConfiguration());
-
-      final String outputFile = cl.getOptionValue(outputFileOpt.getOpt());
-      final PrintFile printFile = outputFile == null ? null : new PrintFile(outputFile);
-
-      final TreeMap<String,String> siteConfig = new TreeMap<String,String>();
-      siteConfig.putAll(shellState.getConnector().instanceOperations().getSiteConfiguration());
-
-      final TreeMap<String,String> defaults = new TreeMap<String,String>();
-      for (Entry<String,String> defaultEntry : AccumuloConfiguration.getDefaultConfiguration()) {
-        defaults.put(defaultEntry.getKey(), defaultEntry.getValue());
-      }
-
-      final TreeMap<String,String> namespaceConfig = new TreeMap<String,String>();
-      if (tableName != null) {
-        String n = Namespaces.getNamespaceName(shellState.getInstance(),
-            Tables.getNamespaceId(shellState.getInstance(), Tables.getTableId(shellState.getInstance(), tableName)));
-        for (Entry<String,String> e : shellState.getConnector().namespaceOperations().getProperties(n)) {
-          namespaceConfig.put(e.getKey(), e.getValue());
-        }
-      }
-
-      Iterable<Entry<String,String>> acuconf = shellState.getConnector().instanceOperations().getSystemConfiguration().entrySet();
-      if (tableName != null) {
-        acuconf = shellState.getConnector().tableOperations().getProperties(tableName);
-      } else if (namespace != null) {
-        acuconf = shellState.getConnector().namespaceOperations().getProperties(namespace);
-      }
-      final TreeMap<String,String> sortedConf = new TreeMap<String,String>();
-      for (Entry<String,String> propEntry : acuconf) {
-        sortedConf.put(propEntry.getKey(), propEntry.getValue());
-      }
-
-      for (Entry<String,String> propEntry : acuconf) {
-        final String key = propEntry.getKey();
-        // only show properties with similar names to that
-        // specified, or all of them if none specified
-        if (cl.hasOption(filterOpt.getOpt()) && !key.contains(cl.getOptionValue(filterOpt.getOpt()))) {
-          continue;
-        }
-        if ((tableName != null || namespace != null) && !Property.isValidTablePropertyKey(key)) {
-          continue;
-        }
-        COL2 = Math.max(COL2, propEntry.getKey().length() + 3);
-      }
-
-      final ArrayList<String> output = new ArrayList<String>();
-      printConfHeader(output);
-
-      for (Entry<String,String> propEntry : sortedConf.entrySet()) {
-        final String key = propEntry.getKey();
-
-        // only show properties with similar names to that
-        // specified, or all of them if none specified
-        if (cl.hasOption(filterOpt.getOpt()) && !key.contains(cl.getOptionValue(filterOpt.getOpt()))) {
-          continue;
-        }
-        if ((tableName != null || namespace != null) && !Property.isValidTablePropertyKey(key)) {
-          continue;
-        }
-        String siteVal = siteConfig.get(key);
-        String sysVal = systemConfig.get(key);
-        String curVal = propEntry.getValue();
-        String dfault = defaults.get(key);
-        String nspVal = namespaceConfig.get(key);
-        boolean printed = false;
-
-        if (dfault != null && key.toLowerCase().contains("password")) {
-          siteVal = sysVal = dfault = curVal = curVal.replaceAll(".", "*");
-        }
-        if (sysVal != null) {
-          if (defaults.containsKey(key) && !Property.getPropertyByKey(key).isExperimental()) {
-            printConfLine(output, "default", key, dfault);
-            printed = true;
-          }
-          if (!defaults.containsKey(key) || !defaults.get(key).equals(siteVal)) {
-            printConfLine(output, "site", printed ? "   @override" : key, siteVal == null ? "" : siteVal);
-            printed = true;
-          }
-          if (!siteConfig.containsKey(key) || !siteVal.equals(sysVal)) {
-            printConfLine(output, "system", printed ? "   @override" : key, sysVal == null ? "" : sysVal);
-            printed = true;
-          }
-
-        }
-        if (nspVal != null) {
-          if (!systemConfig.containsKey(key) || !sysVal.equals(nspVal)) {
-            printConfLine(output, "namespace", printed ? "   @override" : key, nspVal == null ? "" : nspVal);
-            printed = true;
-          }
-        }
-
-        // show per-table value only if it is different (overridden)
-        if (tableName != null && !curVal.equals(nspVal)) {
-          printConfLine(output, "table", printed ? "   @override" : key, curVal);
-        } else if (namespace != null && !curVal.equals(sysVal)) {
-          printConfLine(output, "namespace", printed ? "   @override" : key, curVal);
-        }
-      }
-      printConfFooter(output);
-      shellState.printLines(output.iterator(), !cl.hasOption(disablePaginationOpt.getOpt()), printFile);
-      if (printFile != null) {
-        printFile.close();
-      }
-    }
-    return 0;
-  }
-
-  private void printConfHeader(List<String> output) {
-    printConfFooter(output);
-    output.add(String.format("%-" + COL1 + "s | %-" + COL2 + "s | %s", "SCOPE", "NAME", "VALUE"));
-    printConfFooter(output);
-  }
-
-  private void printConfLine(List<String> output, String s1, String s2, String s3) {
-    if (s2.length() < COL2) {
-      s2 += " " + Shell.repeat(".", COL2 - s2.length() - 1);
-    }
-    output.add(String.format("%-" + COL1 + "s | %-" + COL2 + "s | %s", s1, s2,
-        s3.replace("\n", "\n" + Shell.repeat(" ", COL1 + 1) + "|" + Shell.repeat(" ", COL2 + 2) + "|" + " ")));
-  }
-
-  private void printConfFooter(List<String> output) {
-    int col3 = Math.max(1, Math.min(Integer.MAX_VALUE, reader.getTerminal().getWidth() - COL1 - COL2 - 6));
-    output.add(String.format("%" + COL1 + "s-+-%" + COL2 + "s-+-%-" + col3 + "s", Shell.repeat("-", COL1), Shell.repeat("-", COL2), Shell.repeat("-", col3)));
-  }
-
-  @Override
-  public String description() {
-    return "prints system properties and table specific properties";
-  }
-
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-    final OptionGroup og = new OptionGroup();
-    final OptionGroup tgroup = new OptionGroup();
-
-    tableOpt = new Option(Shell.tableOption, "table", true, "table to display/set/delete properties for");
-    deleteOpt = new Option("d", "delete", true, "delete a per-table property");
-    setOpt = new Option("s", "set", true, "set a per-table property");
-    filterOpt = new Option("f", "filter", true, "show only properties that contain this string");
-    disablePaginationOpt = new Option("np", "no-pagination", false, "disables pagination of output");
-    outputFileOpt = new Option("o", "output", true, "local file to write the scan output to");
-    namespaceOpt = new Option(Shell.namespaceOption, "namespace", true, "namespace to display/set/delete properties for");
-
-    tableOpt.setArgName("table");
-    deleteOpt.setArgName("property");
-    setOpt.setArgName("property=value");
-    filterOpt.setArgName("string");
-    outputFileOpt.setArgName("file");
-    namespaceOpt.setArgName("namespace");
-
-    og.addOption(deleteOpt);
-    og.addOption(setOpt);
-    og.addOption(filterOpt);
-
-    tgroup.addOption(tableOpt);
-    tgroup.addOption(namespaceOpt);
-
-    o.addOptionGroup(tgroup);
-    o.addOptionGroup(og);
-    o.addOption(disablePaginationOpt);
-    o.addOption(outputFileOpt);
-
-    return o;
-  }
-
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/ConstraintCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/ConstraintCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/ConstraintCommand.java
deleted file mode 100644
index 0b6adbf..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/ConstraintCommand.java
+++ /dev/null
@@ -1,134 +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.accumulo.shell.commands;
-
-import java.util.Map.Entry;
-
-import org.apache.accumulo.core.constraints.Constraint;
-import org.apache.accumulo.shell.Shell;
-import org.apache.accumulo.shell.ShellCommandException;
-import org.apache.accumulo.shell.Shell.Command;
-import org.apache.accumulo.shell.ShellCommandException.ErrorCode;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.OptionGroup;
-import org.apache.commons.cli.Options;
-
-public class ConstraintCommand extends Command {
-  protected Option namespaceOpt;
-
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    final String tableName;
-    final String namespace;
-
-    if (cl.hasOption(namespaceOpt.getOpt())) {
-      namespace = cl.getOptionValue(namespaceOpt.getOpt());
-    } else {
-      namespace = null;
-    }
-
-    if (cl.hasOption(OptUtil.tableOpt().getOpt()) || !shellState.getTableName().isEmpty()) {
-      tableName = OptUtil.getTableOpt(cl, shellState);
-    } else {
-      tableName = null;
-    }
-
-    int i;
-    switch (OptUtil.getAldOpt(cl)) {
-      case ADD:
-        for (String constraint : cl.getArgs()) {
-          if (namespace != null) {
-            if (!shellState.getConnector().namespaceOperations().testClassLoad(namespace, constraint, Constraint.class.getName())) {
-              throw new ShellCommandException(ErrorCode.INITIALIZATION_FAILURE, "Servers are unable to load " + constraint + " as type "
-                  + Constraint.class.getName());
-            }
-            i = shellState.getConnector().namespaceOperations().addConstraint(namespace, constraint);
-            shellState.getReader().println("Added constraint " + constraint + " to namespace " + namespace + " with number " + i);
-          } else if (tableName != null && !tableName.isEmpty()) {
-            if (!shellState.getConnector().tableOperations().testClassLoad(tableName, constraint, Constraint.class.getName())) {
-              throw new ShellCommandException(ErrorCode.INITIALIZATION_FAILURE, "Servers are unable to load " + constraint + " as type "
-                  + Constraint.class.getName());
-            }
-            i = shellState.getConnector().tableOperations().addConstraint(tableName, constraint);
-            shellState.getReader().println("Added constraint " + constraint + " to table " + tableName + " with number " + i);
-          } else {
-            throw new IllegalArgumentException("Please specify either a table or a namespace");
-          }
-        }
-        break;
-      case DELETE:
-        for (String constraint : cl.getArgs()) {
-          i = Integer.parseInt(constraint);
-          if (namespace != null) {
-            shellState.getConnector().namespaceOperations().removeConstraint(namespace, i);
-            shellState.getReader().println("Removed constraint " + i + " from namespace " + namespace);
-          } else if (tableName != null) {
-            shellState.getConnector().tableOperations().removeConstraint(tableName, i);
-            shellState.getReader().println("Removed constraint " + i + " from table " + tableName);
-          } else {
-            throw new IllegalArgumentException("Please specify either a table or a namespace");
-          }
-        }
-        break;
-      case LIST:
-        if (namespace != null) {
-          for (Entry<String,Integer> property : shellState.getConnector().namespaceOperations().listConstraints(namespace).entrySet()) {
-            shellState.getReader().println(property.toString());
-          }
-        } else if (tableName != null) {
-          for (Entry<String,Integer> property : shellState.getConnector().tableOperations().listConstraints(tableName).entrySet()) {
-            shellState.getReader().println(property.toString());
-          }
-        } else {
-          throw new IllegalArgumentException("Please specify either a table or a namespace");
-        }
-    }
-
-    return 0;
-  }
-
-  @Override
-  public String description() {
-    return "adds, deletes, or lists constraints for a table";
-  }
-
-  @Override
-  public int numArgs() {
-    return Shell.NO_FIXED_ARG_LENGTH_CHECK;
-  }
-
-  @Override
-  public String usage() {
-    return getName() + " <constraint>{ <constraint>}";
-  }
-
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-    o.addOptionGroup(OptUtil.addListDeleteGroup("constraint"));
-
-    OptionGroup grp = new OptionGroup();
-    grp.addOption(OptUtil.tableOpt("table to add, delete, or list constraints for"));
-    namespaceOpt = new Option(Shell.namespaceOption, "namespace", true, "name of a namespace to operate on");
-    namespaceOpt.setArgName("namespace");
-    grp.addOption(namespaceOpt);
-
-    o.addOptionGroup(grp);
-    return o;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/CreateNamespaceCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/CreateNamespaceCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/CreateNamespaceCommand.java
deleted file mode 100644
index e278105..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/CreateNamespaceCommand.java
+++ /dev/null
@@ -1,99 +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.accumulo.shell.commands;
-
-import java.io.IOException;
-import java.util.Map.Entry;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.NamespaceExistsException;
-import org.apache.accumulo.core.client.NamespaceNotFoundException;
-import org.apache.accumulo.core.client.TableExistsException;
-import org.apache.accumulo.core.client.TableNotFoundException;
-import org.apache.accumulo.core.conf.Property;
-import org.apache.accumulo.shell.Shell;
-import org.apache.accumulo.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.OptionGroup;
-import org.apache.commons.cli.Options;
-
-public class CreateNamespaceCommand extends Command {
-  private Option createNamespaceOptCopyConfig;
-
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException,
-      TableExistsException, TableNotFoundException, IOException, ClassNotFoundException, NamespaceExistsException, NamespaceNotFoundException {
-
-    if (createNamespaceOptCopyConfig == null) {
-      getOptions();
-    }
-
-    String namespace = cl.getArgs()[0];
-
-    shellState.getConnector().namespaceOperations().create(namespace);
-
-    // Copy options if flag was set
-    Iterable<Entry<String,String>> configuration = null;
-    if (cl.hasOption(createNamespaceOptCopyConfig.getOpt())) {
-      String copy = cl.getOptionValue(createNamespaceOptCopyConfig.getOpt());
-      if (shellState.getConnector().namespaceOperations().exists(namespace)) {
-        configuration = shellState.getConnector().namespaceOperations().getProperties(copy);
-      }
-    } 
-    if (configuration != null) {
-      for (Entry<String,String> entry : configuration) {
-        if (Property.isValidTablePropertyKey(entry.getKey())) {
-          shellState.getConnector().namespaceOperations().setProperty(namespace, entry.getKey(), entry.getValue());
-        }
-      }
-    }
-
-    return 0;
-  }
-
-  @Override
-  public String description() {
-    return "creates a new namespace";
-  }
-
-  @Override
-  public String usage() {
-    return getName() + " <namespaceName>";
-  }
-
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-
-    createNamespaceOptCopyConfig = new Option("cc", "copy-config", true, "namespace to copy configuration from");
-    createNamespaceOptCopyConfig.setArgName("namespace");
-
-    OptionGroup ogp = new OptionGroup();
-    ogp.addOption(createNamespaceOptCopyConfig);
-
-    o.addOptionGroup(ogp);
-
-    return o;
-  }
-
-  @Override
-  public int numArgs() {
-    return 1;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/CreateTableCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/CreateTableCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/CreateTableCommand.java
deleted file mode 100644
index 81b39d2..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/CreateTableCommand.java
+++ /dev/null
@@ -1,203 +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.accumulo.shell.commands;
-
-import java.io.IOException;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.SortedSet;
-import java.util.TreeSet;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.TableExistsException;
-import org.apache.accumulo.core.client.TableNotFoundException;
-import org.apache.accumulo.core.client.admin.TimeType;
-import org.apache.accumulo.core.client.impl.Tables;
-import org.apache.accumulo.core.conf.Property;
-import org.apache.accumulo.core.iterators.IteratorUtil;
-import org.apache.accumulo.core.security.VisibilityConstraint;
-import org.apache.accumulo.shell.Shell;
-import org.apache.accumulo.shell.ShellUtil;
-import org.apache.accumulo.shell.Token;
-import org.apache.accumulo.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.OptionGroup;
-import org.apache.commons.cli.Options;
-import org.apache.hadoop.io.Text;
-
-public class CreateTableCommand extends Command {
-  private Option createTableOptCopySplits;
-  private Option createTableOptCopyConfig;
-  private Option createTableOptSplit;
-  private Option createTableOptTimeLogical;
-  private Option createTableOptTimeMillis;
-  private Option createTableNoDefaultIters;
-  private Option createTableOptEVC;
-  private Option base64Opt;
-  private Option createTableOptFormatter;
-
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException,
-      TableExistsException, TableNotFoundException, IOException, ClassNotFoundException {
-
-    final String testTableName = cl.getArgs()[0];
-
-    if (!testTableName.matches(Tables.VALID_NAME_REGEX)) {
-      shellState.getReader().println("Only letters, numbers and underscores are allowed for use in table names.");
-      throw new IllegalArgumentException();
-    }
-
-    final String tableName = cl.getArgs()[0];
-    if (shellState.getConnector().tableOperations().exists(tableName)) {
-      throw new TableExistsException(null, tableName, null);
-    }
-    final SortedSet<Text> partitions = new TreeSet<Text>();
-    final boolean decode = cl.hasOption(base64Opt.getOpt());
-
-    if (cl.hasOption(createTableOptSplit.getOpt())) {
-      partitions.addAll(ShellUtil.scanFile(cl.getOptionValue(createTableOptSplit.getOpt()), decode));
-    } else if (cl.hasOption(createTableOptCopySplits.getOpt())) {
-      final String oldTable = cl.getOptionValue(createTableOptCopySplits.getOpt());
-      if (!shellState.getConnector().tableOperations().exists(oldTable)) {
-        throw new TableNotFoundException(null, oldTable, null);
-      }
-      partitions.addAll(shellState.getConnector().tableOperations().listSplits(oldTable));
-    }
-
-    if (cl.hasOption(createTableOptCopyConfig.getOpt())) {
-      final String oldTable = cl.getOptionValue(createTableOptCopyConfig.getOpt());
-      if (!shellState.getConnector().tableOperations().exists(oldTable)) {
-        throw new TableNotFoundException(null, oldTable, null);
-      }
-    }
-
-    TimeType timeType = TimeType.MILLIS;
-    if (cl.hasOption(createTableOptTimeLogical.getOpt())) {
-      timeType = TimeType.LOGICAL;
-    }
-
-    // create table
-    shellState.getConnector().tableOperations().create(tableName, true, timeType);
-    if (partitions.size() > 0) {
-      shellState.getConnector().tableOperations().addSplits(tableName, partitions);
-    }
-
-    shellState.setTableName(tableName); // switch shell to new table context
-
-    if (cl.hasOption(createTableNoDefaultIters.getOpt())) {
-      for (String key : IteratorUtil.generateInitialTableProperties(true).keySet()) {
-        shellState.getConnector().tableOperations().removeProperty(tableName, key);
-      }
-    }
-
-    // Copy options if flag was set
-    if (cl.hasOption(createTableOptCopyConfig.getOpt())) {
-      if (shellState.getConnector().tableOperations().exists(tableName)) {
-        final Iterable<Entry<String,String>> configuration = shellState.getConnector().tableOperations()
-            .getProperties(cl.getOptionValue(createTableOptCopyConfig.getOpt()));
-        for (Entry<String,String> entry : configuration) {
-          if (Property.isValidTablePropertyKey(entry.getKey())) {
-            shellState.getConnector().tableOperations().setProperty(tableName, entry.getKey(), entry.getValue());
-          }
-        }
-      }
-    }
-
-    if (cl.hasOption(createTableOptEVC.getOpt())) {
-      try {
-        shellState.getConnector().tableOperations().addConstraint(tableName, VisibilityConstraint.class.getName());
-      } catch (AccumuloException e) {
-        Shell.log.warn(e.getMessage() + " while setting visibility constraint, but table was created");
-      }
-    }
-
-    // Load custom formatter if set
-    if (cl.hasOption(createTableOptFormatter.getOpt())) {
-      final String formatterClass = cl.getOptionValue(createTableOptFormatter.getOpt());
-
-      shellState.getConnector().tableOperations().setProperty(tableName, Property.TABLE_FORMATTER_CLASS.toString(), formatterClass);
-    }
-
-    return 0;
-  }
-
-  @Override
-  public String description() {
-    return "creates a new table, with optional aggregators and optionally pre-split";
-  }
-
-  @Override
-  public String usage() {
-    return getName() + " <tableName>";
-  }
-
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-
-    createTableOptCopyConfig = new Option("cc", "copy-config", true, "table to copy configuration from");
-    createTableOptCopySplits = new Option("cs", "copy-splits", true, "table to copy current splits from");
-    createTableOptSplit = new Option("sf", "splits-file", true, "file with a newline-separated list of rows to split the table with");
-    createTableOptTimeLogical = new Option("tl", "time-logical", false, "use logical time");
-    createTableOptTimeMillis = new Option("tm", "time-millis", false, "use time in milliseconds");
-    createTableNoDefaultIters = new Option("ndi", "no-default-iterators", false, "prevent creation of the normal default iterator set");
-    createTableOptEVC = new Option("evc", "enable-visibility-constraint", false,
-        "prevent users from writing data they cannot read.  When enabling this, consider disabling bulk import and alter table.");
-    createTableOptFormatter = new Option("f", "formatter", true, "default formatter to set");
-
-    createTableOptCopyConfig.setArgName("table");
-    createTableOptCopySplits.setArgName("table");
-    createTableOptSplit.setArgName("filename");
-    createTableOptFormatter.setArgName("className");
-
-    // Splits and CopySplits are put in an optionsgroup to make them
-    // mutually exclusive
-    final OptionGroup splitOrCopySplit = new OptionGroup();
-    splitOrCopySplit.addOption(createTableOptSplit);
-    splitOrCopySplit.addOption(createTableOptCopySplits);
-
-    final OptionGroup timeGroup = new OptionGroup();
-    timeGroup.addOption(createTableOptTimeLogical);
-    timeGroup.addOption(createTableOptTimeMillis);
-
-    base64Opt = new Option("b64", "base64encoded", false, "decode encoded split points");
-    o.addOption(base64Opt);
-
-    o.addOptionGroup(splitOrCopySplit);
-    o.addOptionGroup(timeGroup);
-    o.addOption(createTableOptSplit);
-    o.addOption(createTableOptCopyConfig);
-    o.addOption(createTableNoDefaultIters);
-    o.addOption(createTableOptEVC);
-    o.addOption(createTableOptFormatter);
-
-    return o;
-  }
-
-  @Override
-  public int numArgs() {
-    return 1;
-  }
-
-  @Override
-  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> special) {
-    registerCompletionForNamespaces(root, special);
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/CreateUserCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/CreateUserCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/CreateUserCommand.java
deleted file mode 100644
index 2a7359f..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/CreateUserCommand.java
+++ /dev/null
@@ -1,76 +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.accumulo.shell.commands;
-
-import java.io.IOException;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.TableExistsException;
-import org.apache.accumulo.core.client.TableNotFoundException;
-import org.apache.accumulo.core.client.security.tokens.PasswordToken;
-import org.apache.accumulo.shell.Shell;
-import org.apache.accumulo.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Options;
-
-public class CreateUserCommand extends Command {
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, TableNotFoundException,
-      AccumuloSecurityException, TableExistsException, IOException {
-    final String user = cl.getArgs()[0];
-    
-    final String password = shellState.readMaskedLine("Enter new password for '" + user + "': ", '*');
-    if (password == null) {
-      shellState.getReader().println();
-      return 0;
-    } // user canceled
-    String passwordConfirm = shellState.readMaskedLine("Please confirm new password for '" + user + "': ", '*');
-    if (passwordConfirm == null) {
-      shellState.getReader().println();
-      return 0;
-    } // user canceled
-    
-    if (!password.equals(passwordConfirm)) {
-      throw new IllegalArgumentException("Passwords do not match");
-    }
-    shellState.getConnector().securityOperations().createLocalUser(user, new PasswordToken(password));
-    Shell.log.debug("Created user " + user);
-    return 0;
-  }
-  
-  @Override
-  public String usage() {
-    return getName() + " <username>";
-  }
-  
-  @Override
-  public String description() {
-    return "creates a new user";
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-    return o;
-  }
-  
-  @Override
-  public int numArgs() {
-    return 1;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/DUCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/DUCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/DUCommand.java
deleted file mode 100644
index eb6aeb5..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/DUCommand.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.accumulo.shell.commands;
-
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.SortedSet;
-import java.util.TreeSet;
-
-import org.apache.accumulo.core.client.Instance;
-import org.apache.accumulo.core.client.NamespaceNotFoundException;
-import org.apache.accumulo.core.client.TableNotFoundException;
-import org.apache.accumulo.core.client.admin.DiskUsage;
-import org.apache.accumulo.core.client.impl.Namespaces;
-import org.apache.accumulo.core.util.NumUtil;
-import org.apache.accumulo.shell.Shell;
-import org.apache.accumulo.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-
-public class DUCommand extends Command {
-
-  private Option optTablePattern, optHumanReadble, optNamespace;
-
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws IOException, TableNotFoundException,
-      NamespaceNotFoundException {
-
-    final SortedSet<String> tables = new TreeSet<String>(Arrays.asList(cl.getArgs()));
-
-    if (cl.hasOption(Shell.tableOption)) {
-      String tableName = cl.getOptionValue(Shell.tableOption);
-      if (!shellState.getConnector().tableOperations().exists(tableName)) {
-        throw new TableNotFoundException(tableName, tableName, "specified table that doesn't exist");
-      }
-      tables.add(tableName);
-    }
-
-    if (cl.hasOption(optNamespace.getOpt())) {
-      Instance instance = shellState.getInstance();
-      String namespaceId = Namespaces.getNamespaceId(instance, cl.getOptionValue(optNamespace.getOpt()));
-      tables.addAll(Namespaces.getTableNames(instance, namespaceId));
-    }
-
-    boolean prettyPrint = cl.hasOption(optHumanReadble.getOpt()) ? true : false;
-
-    // Add any patterns
-    if (cl.hasOption(optTablePattern.getOpt())) {
-      for (String table : shellState.getConnector().tableOperations().list()) {
-        if (table.matches(cl.getOptionValue(optTablePattern.getOpt()))) {
-          tables.add(table);
-        }
-      }
-    }
-
-    // If we didn't get any tables, and we have a table selected, add the current table
-    if (tables.isEmpty() && !shellState.getTableName().isEmpty()) {
-      tables.add(shellState.getTableName());
-    }
-
-    try {
-      String valueFormat = prettyPrint ? "%9s" : "%,24d";
-      for (DiskUsage usage : shellState.getConnector().tableOperations().getDiskUsage(tables)) {
-        Object value = prettyPrint ? NumUtil.bigNumberForSize(usage.getUsage()) : usage.getUsage();
-        shellState.getReader().println(String.format(valueFormat + " %s", value, usage.getTables()));
-      }
-    } catch (Exception ex) {
-      throw new RuntimeException(ex);
-    }
-    return 0;
-  }
-
-  @Override
-  public String description() {
-    return "prints how much space, in bytes, is used by files referenced by a table.  When multiple tables are specified it prints how much space, in bytes, is used by files shared between tables, if any.";
-  }
-
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-
-    optTablePattern = new Option("p", "pattern", true, "regex pattern of table names");
-    optTablePattern.setArgName("pattern");
-
-    optHumanReadble = new Option("h", "human-readable", false, "format large sizes to human readable units");
-    optHumanReadble.setArgName("human readable output");
-
-    optNamespace = new Option(Shell.namespaceOption, "namespace", true, "name of a namespace");
-    optNamespace.setArgName("namespace");
-
-    o.addOption(OptUtil.tableOpt("table to examine"));
-
-    o.addOption(optTablePattern);
-    o.addOption(optHumanReadble);
-    o.addOption(optNamespace);
-
-    return o;
-  }
-
-  @Override
-  public String usage() {
-    return getName() + " <table>{ <table>}";
-  }
-
-  @Override
-  public int numArgs() {
-    return Shell.NO_FIXED_ARG_LENGTH_CHECK;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/DebugCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/DebugCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/DebugCommand.java
deleted file mode 100644
index ab40adc..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/DebugCommand.java
+++ /dev/null
@@ -1,71 +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.accumulo.shell.commands;
-
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.accumulo.core.util.BadArgumentException;
-import org.apache.accumulo.shell.Shell;
-import org.apache.accumulo.shell.Token;
-import org.apache.accumulo.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-
-public class DebugCommand extends Command {
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws IOException {
-    if (cl.getArgs().length == 1) {
-      if (cl.getArgs()[0].equalsIgnoreCase("on")) {
-        Shell.setDebugging(true);
-      } else if (cl.getArgs()[0].equalsIgnoreCase("off")) {
-        Shell.setDebugging(false);
-      } else {
-        throw new BadArgumentException("Argument must be 'on' or 'off'", fullCommand, fullCommand.indexOf(cl.getArgs()[0]));
-      }
-    } else if (cl.getArgs().length == 0) {
-      shellState.getReader().println(Shell.isDebuggingEnabled() ? "on" : "off");
-    } else {
-      shellState.printException(new IllegalArgumentException("Expected 0 or 1 argument. There were " + cl.getArgs().length + "."));
-      printHelp(shellState);
-      return 1;
-    }
-    return 0;
-  }
-  
-  @Override
-  public String description() {
-    return "turns debug logging on or off";
-  }
-  
-  @Override
-  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> special) {
-    final Token debug_command = new Token(getName());
-    debug_command.addSubcommand(Arrays.asList(new String[] {"on", "off"}));
-    root.addSubcommand(debug_command);
-  }
-  
-  @Override
-  public String usage() {
-    return getName() + " [ on | off ]";
-  }
-  
-  @Override
-  public int numArgs() {
-    return Shell.NO_FIXED_ARG_LENGTH_CHECK;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteCommand.java
deleted file mode 100644
index 2601f58..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteCommand.java
+++ /dev/null
@@ -1,112 +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.accumulo.shell.commands;
-
-import java.io.IOException;
-import java.util.concurrent.TimeUnit;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.BatchWriter;
-import org.apache.accumulo.core.client.BatchWriterConfig;
-import org.apache.accumulo.core.client.TableNotFoundException;
-import org.apache.accumulo.core.conf.AccumuloConfiguration;
-import org.apache.accumulo.core.data.Mutation;
-import org.apache.accumulo.core.security.ColumnVisibility;
-import org.apache.accumulo.core.tabletserver.thrift.ConstraintViolationException;
-import org.apache.accumulo.shell.Shell;
-import org.apache.accumulo.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-import org.apache.hadoop.io.Text;
-
-public class DeleteCommand extends Command {
-  private Option deleteOptAuths, timestampOpt;
-  private Option timeoutOption;
-  
-  protected long getTimeout(final CommandLine cl) {
-    if (cl.hasOption(timeoutOption.getLongOpt())) {
-      return AccumuloConfiguration.getTimeInMillis(cl.getOptionValue(timeoutOption.getLongOpt()));
-    }
-    
-    return Long.MAX_VALUE;
-  }
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException,
-      TableNotFoundException, IOException, ConstraintViolationException {
-    shellState.checkTableState();
-    
-    final Mutation m = new Mutation(new Text(cl.getArgs()[0].getBytes(Shell.CHARSET)));
-    final Text colf = new Text(cl.getArgs()[1].getBytes(Shell.CHARSET));
-    final Text colq = new Text(cl.getArgs()[2].getBytes(Shell.CHARSET));
-    
-    if (cl.hasOption(deleteOptAuths.getOpt())) {
-      final ColumnVisibility le = new ColumnVisibility(cl.getOptionValue(deleteOptAuths.getOpt()));
-      if (cl.hasOption(timestampOpt.getOpt())) {
-        m.putDelete(colf, colq, le, Long.parseLong(cl.getOptionValue(timestampOpt.getOpt())));
-      } else {
-        m.putDelete(colf, colq, le);
-      }
-    } else if (cl.hasOption(timestampOpt.getOpt())) {
-      m.putDelete(colf, colq, Long.parseLong(cl.getOptionValue(timestampOpt.getOpt())));
-    } else {
-      m.putDelete(colf, colq);
-    }
-    final BatchWriter bw = shellState.getConnector().createBatchWriter(shellState.getTableName(),
-        new BatchWriterConfig().setMaxMemory(Math.max(m.estimatedMemoryUsed(), 1024)).setMaxWriteThreads(1).setTimeout(getTimeout(cl), TimeUnit.MILLISECONDS));
-    bw.addMutation(m);
-    bw.close();
-    return 0;
-  }
-  
-  @Override
-  public String description() {
-    return "deletes a record from a table";
-  }
-  
-  @Override
-  public String usage() {
-    return getName() + " <row> <colfamily> <colqualifier>";
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-    
-    deleteOptAuths = new Option("l", "visibility-label", true, "formatted visibility");
-    deleteOptAuths.setArgName("expression");
-    o.addOption(deleteOptAuths);
-    
-    timestampOpt = new Option("ts", "timestamp", true, "timestamp to use for deletion");
-    timestampOpt.setArgName("timestamp");
-    o.addOption(timestampOpt);
-    
-    timeoutOption = new Option(null, "timeout", true,
-        "time before insert should fail if no data is written. If no unit is given assumes seconds.  Units d,h,m,s,and ms are supported.  e.g. 30s or 100ms");
-    timeoutOption.setArgName("timeout");
-    o.addOption(timeoutOption);
-    
-    return o;
-  }
-  
-  @Override
-  public int numArgs() {
-    return 3;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteIterCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteIterCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteIterCommand.java
deleted file mode 100644
index ec60aee..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteIterCommand.java
+++ /dev/null
@@ -1,114 +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.accumulo.shell.commands;
-
-import java.util.EnumSet;
-
-import org.apache.accumulo.core.iterators.IteratorUtil.IteratorScope;
-import org.apache.accumulo.shell.Shell;
-import org.apache.accumulo.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.OptionGroup;
-import org.apache.commons.cli.Options;
-
-public class DeleteIterCommand extends Command {
-  private Option allScopeOpt, mincScopeOpt, majcScopeOpt, scanScopeOpt, nameOpt;
-
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-
-    boolean tables = cl.hasOption(OptUtil.tableOpt().getOpt()) || !shellState.getTableName().isEmpty();
-    boolean namespaces = cl.hasOption(OptUtil.namespaceOpt().getOpt());
-
-    final String name = cl.getOptionValue(nameOpt.getOpt());
-
-    if (namespaces) {
-      if (!shellState.getConnector().namespaceOperations().listIterators(OptUtil.getNamespaceOpt(cl, shellState)).containsKey(name)) {
-        Shell.log.warn("no iterators found that match your criteria");
-        return 0;
-      }
-    } else if (tables) {
-      if (!shellState.getConnector().tableOperations().listIterators(OptUtil.getTableOpt(cl, shellState)).containsKey(name)) {
-        Shell.log.warn("no iterators found that match your criteria");
-        return 0;
-      }
-    } else {
-      throw new IllegalArgumentException("No table or namespace specified");
-    }
-
-    final EnumSet<IteratorScope> scopes = EnumSet.noneOf(IteratorScope.class);
-    if (cl.hasOption(allScopeOpt.getOpt()) || cl.hasOption(mincScopeOpt.getOpt())) {
-      scopes.add(IteratorScope.minc);
-    }
-    if (cl.hasOption(allScopeOpt.getOpt()) || cl.hasOption(majcScopeOpt.getOpt())) {
-      scopes.add(IteratorScope.majc);
-    }
-    if (cl.hasOption(allScopeOpt.getOpt()) || cl.hasOption(scanScopeOpt.getOpt())) {
-      scopes.add(IteratorScope.scan);
-    }
-    if (scopes.isEmpty()) {
-      throw new IllegalArgumentException("You must select at least one scope to configure");
-    }
-
-    if (namespaces) {
-      shellState.getConnector().namespaceOperations().removeIterator(OptUtil.getNamespaceOpt(cl, shellState), name, scopes);
-    } else if (tables) {
-      shellState.getConnector().tableOperations().removeIterator(OptUtil.getTableOpt(cl, shellState), name, scopes);
-    } else {
-      throw new IllegalArgumentException("No table or namespace specified");
-    }
-    return 0;
-  }
-
-  @Override
-  public String description() {
-    return "deletes a table-specific or namespace-specific iterator";
-  }
-
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-
-    nameOpt = new Option("n", "name", true, "iterator to delete");
-    nameOpt.setArgName("itername");
-    nameOpt.setRequired(true);
-
-    allScopeOpt = new Option("all", "all-scopes", false, "remove from all scopes");
-    mincScopeOpt = new Option(IteratorScope.minc.name(), "minor-compaction", false, "remove from minor compaction scope");
-    majcScopeOpt = new Option(IteratorScope.majc.name(), "major-compaction", false, "remove from major compaction scope");
-    scanScopeOpt = new Option(IteratorScope.scan.name(), "scan-time", false, "remove from scan scope");
-
-    OptionGroup grp = new OptionGroup();
-    grp.addOption(OptUtil.tableOpt("table to delete the iterator from"));
-    grp.addOption(OptUtil.namespaceOpt("namespace to delete the iterator from"));
-    o.addOptionGroup(grp);
-    o.addOption(nameOpt);
-
-    o.addOption(allScopeOpt);
-    o.addOption(mincScopeOpt);
-    o.addOption(majcScopeOpt);
-    o.addOption(scanScopeOpt);
-
-    return o;
-  }
-
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteManyCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteManyCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteManyCommand.java
deleted file mode 100644
index c29a92c..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteManyCommand.java
+++ /dev/null
@@ -1,82 +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.accumulo.shell.commands;
-
-import java.util.concurrent.TimeUnit;
-
-import org.apache.accumulo.core.client.BatchWriter;
-import org.apache.accumulo.core.client.BatchWriterConfig;
-import org.apache.accumulo.core.client.IteratorSetting;
-import org.apache.accumulo.core.client.Scanner;
-import org.apache.accumulo.core.iterators.SortedKeyIterator;
-import org.apache.accumulo.core.security.Authorizations;
-import org.apache.accumulo.core.util.interpret.ScanInterpreter;
-import org.apache.accumulo.shell.Shell;
-import org.apache.accumulo.shell.format.DeleterFormatter;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-
-public class DeleteManyCommand extends ScanCommand {
-  private Option forceOpt;
-  
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    final String tableName = OptUtil.getTableOpt(cl, shellState);
-    
-    final ScanInterpreter interpeter = getInterpreter(cl, tableName, shellState);
-
-    // handle first argument, if present, the authorizations list to
-    // scan with
-    final Authorizations auths = getAuths(cl, shellState);
-    final Scanner scanner = shellState.getConnector().createScanner(tableName, auths);
-    
-    scanner.addScanIterator(new IteratorSetting(Integer.MAX_VALUE, "NOVALUE", SortedKeyIterator.class));
-    
-    // handle session-specific scan iterators
-    addScanIterators(shellState, cl, scanner, tableName);
-    
-    // handle remaining optional arguments
-    scanner.setRange(getRange(cl, interpeter));
-    
-    scanner.setTimeout(getTimeout(cl), TimeUnit.MILLISECONDS);
-
-    // handle columns
-    fetchColumns(cl, scanner, interpeter);
-    
-    // output / delete the records
-    final BatchWriter writer = shellState.getConnector()
-        .createBatchWriter(tableName, new BatchWriterConfig().setTimeout(getTimeout(cl), TimeUnit.MILLISECONDS));
-    shellState.printLines(new DeleterFormatter(writer, scanner, cl.hasOption(timestampOpt.getOpt()), shellState, cl.hasOption(forceOpt.getOpt())), false);
-    
-    return 0;
-  }
-  
-  @Override
-  public String description() {
-    return "scans a table and deletes the resulting records";
-  }
-  
-  @Override
-  public Options getOptions() {
-    forceOpt = new Option("f", "force", false, "force deletion without prompting");
-    final Options opts = super.getOptions();
-    opts.addOption(forceOpt);
-    opts.addOption(OptUtil.tableOpt("table to delete entries from"));
-    return opts;
-  }
-  
-}


[48/53] [abbrv] git commit: Merge branch '1.6.0-SNAPSHOT'

Posted by el...@apache.org.
Merge branch '1.6.0-SNAPSHOT'


Project: http://git-wip-us.apache.org/repos/asf/accumulo/repo
Commit: http://git-wip-us.apache.org/repos/asf/accumulo/commit/1b4c49c6
Tree: http://git-wip-us.apache.org/repos/asf/accumulo/tree/1b4c49c6
Diff: http://git-wip-us.apache.org/repos/asf/accumulo/diff/1b4c49c6

Branch: refs/heads/ACCUMULO-378
Commit: 1b4c49c6946990ce792e511a79d5fb348d5c6702
Parents: 066043d 479a36b
Author: Christopher Tubbs <ct...@apache.org>
Authored: Mon Apr 7 20:43:50 2014 -0400
Committer: Christopher Tubbs <ct...@apache.org>
Committed: Mon Apr 7 20:43:50 2014 -0400

----------------------------------------------------------------------
 assemble/build.sh                               |  8 +++----
 .../core/client/mapred/InputFormatBase.java     |  1 +
 .../client/mapreduce/AccumuloInputFormat.java   |  2 +-
 .../core/client/mapreduce/InputFormatBase.java  |  1 +
 .../EmptySplitsAccumuloInputFormat.java         | 10 ++++----
 .../org/apache/accumulo/fate/ReadOnlyStore.java | 22 ++++++++---------
 .../java/org/apache/accumulo/fate/TStore.java   | 16 ++++++-------
 .../apache/accumulo/master/util/FateAdmin.java  | 25 ++++++++++----------
 8 files changed, 43 insertions(+), 42 deletions(-)
----------------------------------------------------------------------



[06/53] [abbrv] ACCUMULO-1897 Move shell into new package and module

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/AddAuthsCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/AddAuthsCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/AddAuthsCommand.java
new file mode 100644
index 0000000..27fea1e
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/AddAuthsCommand.java
@@ -0,0 +1,82 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.security.Authorizations;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Token;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.OptionGroup;
+import org.apache.commons.cli.Options;
+
+public class AddAuthsCommand extends Command {
+  private Option userOpt;
+  private Option scanOptAuths;
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException {
+    final String user = cl.getOptionValue(userOpt.getOpt(), shellState.getConnector().whoami());
+    final String scanOpts = cl.getOptionValue(scanOptAuths.getOpt());
+    Authorizations auths = shellState.getConnector().securityOperations().getUserAuthorizations(user);
+    StringBuilder userAuths = new StringBuilder();
+    if (!auths.isEmpty()) {
+      userAuths.append(auths.toString());
+      userAuths.append(",");
+    }
+    userAuths.append(scanOpts);
+    shellState.getConnector().securityOperations().changeUserAuthorizations(user, ScanCommand.parseAuthorizations(userAuths.toString()));
+    Shell.log.debug("Changed record-level authorizations for user " + user);
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "adds authorizations to the maximum scan authorizations for a user";
+  }
+  
+  @Override
+  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> completionSet) {
+    registerCompletionForUsers(root, completionSet);
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+    final OptionGroup setOrClear = new OptionGroup();
+    scanOptAuths = new Option("s", "scan-authorizations", true, "scan authorizations to set");
+    scanOptAuths.setArgName("comma-separated-authorizations");
+    setOrClear.addOption(scanOptAuths);
+    setOrClear.setRequired(true);
+    o.addOptionGroup(setOrClear);
+    userOpt = new Option(Shell.userOption, "user", true, "user to operate on");
+    userOpt.setArgName("user");
+    o.addOption(userOpt);
+    return o;
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/AddSplitsCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/AddSplitsCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/AddSplitsCommand.java
new file mode 100644
index 0000000..b695d4d
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/AddSplitsCommand.java
@@ -0,0 +1,88 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.util.TreeSet;
+
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.ShellUtil;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.MissingArgumentException;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+import org.apache.hadoop.io.Text;
+
+public class AddSplitsCommand extends Command {
+  private Option optSplitsFile, base64Opt;
+  
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    final String tableName = OptUtil.getTableOpt(cl, shellState);
+    final boolean decode = cl.hasOption(base64Opt.getOpt());
+    
+    final TreeSet<Text> splits = new TreeSet<Text>();
+    
+    if (cl.hasOption(optSplitsFile.getOpt())) {
+      splits.addAll(ShellUtil.scanFile(cl.getOptionValue(optSplitsFile.getOpt()), decode));
+    } else {
+      if (cl.getArgList().isEmpty()) {
+        throw new MissingArgumentException("No split points specified");
+      }
+      for (String s : cl.getArgs()) {
+        splits.add(new Text(s.getBytes(Shell.CHARSET)));
+      }
+    }
+    
+    if (!shellState.getConnector().tableOperations().exists(tableName)) {
+      throw new TableNotFoundException(null, tableName, null);
+    }
+    shellState.getConnector().tableOperations().addSplits(tableName, splits);
+    
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "adds split points to an existing table";
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+    
+    optSplitsFile = new Option("sf", "splits-file", true, "file with a newline-separated list of rows to split the table with");
+    optSplitsFile.setArgName("filename");
+    
+    base64Opt = new Option("b64", "base64encoded", false, "decode encoded split points (splits file only)");
+    
+    o.addOption(OptUtil.tableOpt("name of the table to add split points to"));
+    o.addOption(optSplitsFile);
+    o.addOption(base64Opt);
+    return o;
+  }
+  
+  @Override
+  public String usage() {
+    return getName() + " [<split>{ <split>} ]";
+  }
+  
+  @Override
+  public int numArgs() {
+    return Shell.NO_FIXED_ARG_LENGTH_CHECK;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/AuthenticateCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/AuthenticateCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/AuthenticateCommand.java
new file mode 100644
index 0000000..807de24
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/AuthenticateCommand.java
@@ -0,0 +1,66 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.security.tokens.PasswordToken;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Token;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+
+public class AuthenticateCommand extends Command {
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException, IOException {
+    final String user = cl.getArgs()[0];
+    final String p = shellState.readMaskedLine("Enter current password for '" + user + "': ", '*');
+    if (p == null) {
+      shellState.getReader().println();
+      return 0;
+    } // user canceled
+    final byte[] password = p.getBytes(StandardCharsets.UTF_8);
+    final boolean valid = shellState.getConnector().securityOperations().authenticateUser(user, new PasswordToken(password));
+    shellState.getReader().println((valid ? "V" : "Not v") + "alid");
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "verifies a user's credentials";
+  }
+  
+  @Override
+  public String usage() {
+    return getName() + " <username>";
+  }
+  
+  @Override
+  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> completionSet) {
+    registerCompletionForUsers(root, completionSet);
+  }
+  
+  @Override
+  public int numArgs() {
+    return 1;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/ByeCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/ByeCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/ByeCommand.java
new file mode 100644
index 0000000..2f3baa9
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/ByeCommand.java
@@ -0,0 +1,19 @@
+/*
+ * 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.accumulo.shell.commands;
+
+public class ByeCommand extends ExitCommand {}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/ClasspathCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/ClasspathCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/ClasspathCommand.java
new file mode 100644
index 0000000..c056581
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/ClasspathCommand.java
@@ -0,0 +1,55 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.io.IOException;
+
+import jline.console.ConsoleReader;
+
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.accumulo.start.classloader.vfs.AccumuloVFSClassLoader;
+import org.apache.accumulo.start.classloader.vfs.AccumuloVFSClassLoader.Printer;
+import org.apache.commons.cli.CommandLine;
+
+public class ClasspathCommand extends Command {
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) {
+    final ConsoleReader reader = shellState.getReader();
+    AccumuloVFSClassLoader.printClassPath(new Printer() {
+      @Override
+      public void print(String s) {
+        try {
+          reader.println(s);
+        } catch (IOException ex) {
+          throw new RuntimeException(ex);
+        }
+      }
+    });
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "lists the current files on the classpath";
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/ClearCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/ClearCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/ClearCommand.java
new file mode 100644
index 0000000..9340d4e
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/ClearCommand.java
@@ -0,0 +1,52 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.io.IOException;
+
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+
+public class ClearCommand extends Command {
+  @Override
+  public String description() {
+    return "clears the screen";
+  }
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws IOException {
+    // custom clear screen, so I don't have to redraw the prompt twice
+    if (!shellState.getReader().getTerminal().isAnsiSupported()) {
+      throw new IOException("Terminal does not support ANSI commands");
+    }
+    // send the ANSI code to clear the screen
+    shellState.getReader().print(((char) 27) + "[2J");
+    shellState.getReader().flush();
+    
+    // then send the ANSI code to go to position 1,1
+    shellState.getReader().print(((char) 27) + "[1;1H");
+    shellState.getReader().flush();
+    
+    return 0;
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/CloneTableCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/CloneTableCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/CloneTableCommand.java
new file mode 100644
index 0000000..37de39d
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/CloneTableCommand.java
@@ -0,0 +1,102 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.TableExistsException;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Token;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+
+public class CloneTableCommand extends Command {
+  
+  private Option setPropsOption;
+  private Option excludePropsOption;
+  private Option noFlushOption;
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException, TableNotFoundException,
+      TableExistsException {
+    
+    final HashMap<String,String> props = new HashMap<String,String>();
+    final HashSet<String> exclude = new HashSet<String>();
+    boolean flush = true;
+    
+    if (cl.hasOption(setPropsOption.getOpt())) {
+      String[] keyVals = cl.getOptionValue(setPropsOption.getOpt()).split(",");
+      for (String keyVal : keyVals) {
+        String[] sa = keyVal.split("=");
+        props.put(sa[0], sa[1]);
+      }
+    }
+    
+    if (cl.hasOption(excludePropsOption.getOpt())) {
+      String[] keys = cl.getOptionValue(excludePropsOption.getOpt()).split(",");
+      for (String key : keys) {
+        exclude.add(key);
+      }
+    }
+    
+    if (cl.hasOption(noFlushOption.getOpt())) {
+      flush = false;
+    }
+    
+    shellState.getConnector().tableOperations().clone(cl.getArgs()[0], cl.getArgs()[1], flush, props, exclude);
+    return 0;
+  }
+  
+  @Override
+  public String usage() {
+    return getName() + " <current table name> <new table name>";
+  }
+  
+  @Override
+  public String description() {
+    return "clones a table";
+  }
+  
+  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> completionSet) {
+    registerCompletionForTables(root, completionSet);
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+    setPropsOption = new Option("s", "set", true, "set initial properties before the table comes online. Expects <prop>=<value>{,<prop>=<value>}");
+    o.addOption(setPropsOption);
+    excludePropsOption = new Option("e", "exclude", true, "exclude properties that should not be copied from source table. Expects <prop>{,<prop>}");
+    o.addOption(excludePropsOption);
+    noFlushOption = new Option("nf", "noFlush", false, "do not flush table data in memory before cloning.");
+    o.addOption(noFlushOption);
+    return o;
+  }
+  
+  @Override
+  public int numArgs() {
+    return 2;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/ClsCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/ClsCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/ClsCommand.java
new file mode 100644
index 0000000..e1ba4fd
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/ClsCommand.java
@@ -0,0 +1,19 @@
+/*
+ * 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.accumulo.shell.commands;
+
+public class ClsCommand extends ClearCommand {}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/CompactCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/CompactCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/CompactCommand.java
new file mode 100644
index 0000000..80dd9ba
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/CompactCommand.java
@@ -0,0 +1,129 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.IteratorSetting;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.shell.Shell;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+import org.apache.hadoop.io.Text;
+
+public class CompactCommand extends TableOperation {
+  private Option noFlushOption, waitOpt, profileOpt, cancelOpt;
+  private boolean flush;
+  private Text startRow;
+  private Text endRow;
+  private List<IteratorSetting> iterators;
+  
+  boolean override = false;
+  private boolean wait;
+  
+  private boolean cancel = false;
+
+  @Override
+  public String description() {
+    return "sets all tablets for a table to major compact as soon as possible (based on current time)";
+  }
+  
+  protected void doTableOp(final Shell shellState, final String tableName) throws AccumuloException, AccumuloSecurityException {
+    // compact the tables
+    
+    if (cancel) {
+      try {
+        shellState.getConnector().tableOperations().cancelCompaction(tableName);
+        Shell.log.info("Compaction canceled for table " + tableName);
+      } catch (TableNotFoundException e) {
+        throw new AccumuloException(e);
+      }
+    } else {
+      try {
+        if (wait) {
+          Shell.log.info("Compacting table ...");
+        }
+        
+        shellState.getConnector().tableOperations().compact(tableName, startRow, endRow, iterators, flush, wait);
+        
+        Shell.log.info("Compaction of table " + tableName + " " + (wait ? "completed" : "started") + " for given range");
+      } catch (Exception ex) {
+        throw new AccumuloException(ex);
+      }
+    }
+  }
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    
+    if (cl.hasOption(cancelOpt.getLongOpt())) {
+      cancel = true;
+      
+      if (cl.getOptions().length > 2) {
+        throw new IllegalArgumentException("Can not specify other options with cancel");
+      }
+    } else {
+      cancel = false;
+    }
+
+    flush = !cl.hasOption(noFlushOption.getOpt());
+    startRow = OptUtil.getStartRow(cl);
+    endRow = OptUtil.getEndRow(cl);
+    wait = cl.hasOption(waitOpt.getOpt());
+    
+    if (cl.hasOption(profileOpt.getOpt())) {
+      List<IteratorSetting> iterators = shellState.iteratorProfiles.get(cl.getOptionValue(profileOpt.getOpt()));
+      if (iterators == null) {
+        Shell.log.error("Profile " + cl.getOptionValue(profileOpt.getOpt()) + " does not exist");
+        return -1;
+      }
+      
+      this.iterators = new ArrayList<IteratorSetting>(iterators);
+    } else {
+      this.iterators = Collections.emptyList();
+    }
+
+
+    return super.execute(fullCommand, cl, shellState);
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options opts = super.getOptions();
+    
+    opts.addOption(OptUtil.startRowOpt());
+    opts.addOption(OptUtil.endRowOpt());
+    noFlushOption = new Option("nf", "noFlush", false, "do not flush table data in memory before compacting.");
+    opts.addOption(noFlushOption);
+    waitOpt = new Option("w", "wait", false, "wait for compact to finish");
+    opts.addOption(waitOpt);
+    
+    profileOpt = new Option("pn", "profile", true, "iterator profile name");
+    profileOpt.setArgName("profile");
+    opts.addOption(profileOpt);
+
+    cancelOpt = new Option(null, "cancel", false, "cancel user initiated compactions");
+    opts.addOption(cancelOpt);
+
+    return opts;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/ConfigCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/ConfigCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/ConfigCommand.java
new file mode 100644
index 0000000..9b39512
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/ConfigCommand.java
@@ -0,0 +1,315 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.TreeMap;
+
+import jline.console.ConsoleReader;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.NamespaceNotFoundException;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.core.client.impl.Namespaces;
+import org.apache.accumulo.core.client.impl.Tables;
+import org.apache.accumulo.core.conf.AccumuloConfiguration;
+import org.apache.accumulo.core.conf.Property;
+import org.apache.accumulo.core.security.ColumnVisibility;
+import org.apache.accumulo.core.util.BadArgumentException;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Token;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.accumulo.shell.Shell.PrintFile;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.OptionGroup;
+import org.apache.commons.cli.Options;
+
+public class ConfigCommand extends Command {
+  private Option tableOpt, deleteOpt, setOpt, filterOpt, disablePaginationOpt, outputFileOpt, namespaceOpt;
+
+  private int COL1 = 10, COL2 = 7;
+  private ConsoleReader reader;
+
+  @Override
+  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> completionSet) {
+    final Token cmd = new Token(getName());
+    final Token sub = new Token("-" + setOpt.getOpt());
+    for (Property p : Property.values()) {
+      if (!(p.getKey().endsWith(".")) && !p.isExperimental()) {
+        sub.addSubcommand(new Token(p.toString()));
+      }
+    }
+    cmd.addSubcommand(sub);
+    root.addSubcommand(cmd);
+  }
+
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException,
+      TableNotFoundException, IOException, ClassNotFoundException, NamespaceNotFoundException {
+    reader = shellState.getReader();
+
+    final String tableName = cl.getOptionValue(tableOpt.getOpt());
+    if (tableName != null && !shellState.getConnector().tableOperations().exists(tableName)) {
+      throw new TableNotFoundException(null, tableName, null);
+    }
+    final String namespace = cl.getOptionValue(namespaceOpt.getOpt());
+    if (namespace != null && !shellState.getConnector().namespaceOperations().exists(namespace)) {
+      throw new NamespaceNotFoundException(null, namespace, null);
+    }
+    if (cl.hasOption(deleteOpt.getOpt())) {
+      // delete property from table
+      String property = cl.getOptionValue(deleteOpt.getOpt());
+      if (property.contains("=")) {
+        throw new BadArgumentException("Invalid '=' operator in delete operation.", fullCommand, fullCommand.indexOf('='));
+      }
+      if (tableName != null) {
+        if (!Property.isValidTablePropertyKey(property)) {
+          Shell.log.warn("Invalid per-table property : " + property + ", still removing from zookeeper if it's there.");
+        }
+        shellState.getConnector().tableOperations().removeProperty(tableName, property);
+        Shell.log.debug("Successfully deleted table configuration option.");
+      } else if (namespace != null) {
+        if (!Property.isValidTablePropertyKey(property)) {
+          Shell.log.warn("Invalid per-table property : " + property + ", still removing from zookeeper if it's there.");
+        }
+        shellState.getConnector().namespaceOperations().removeProperty(namespace, property);
+        Shell.log.debug("Successfully deleted namespace configuration option.");
+      } else {
+        if (!Property.isValidZooPropertyKey(property)) {
+          Shell.log.warn("Invalid per-table property : " + property + ", still removing from zookeeper if it's there.");
+        }
+        shellState.getConnector().instanceOperations().removeProperty(property);
+        Shell.log.debug("Successfully deleted system configuration option");
+      }
+    } else if (cl.hasOption(setOpt.getOpt())) {
+      // set property on table
+      String property = cl.getOptionValue(setOpt.getOpt()), value = null;
+      if (!property.contains("=")) {
+        throw new BadArgumentException("Missing '=' operator in set operation.", fullCommand, fullCommand.indexOf(property));
+      }
+      final String pair[] = property.split("=", 2);
+      property = pair[0];
+      value = pair[1];
+
+      if (tableName != null) {
+        if (!Property.isValidTablePropertyKey(property)) {
+          throw new BadArgumentException("Invalid per-table property.", fullCommand, fullCommand.indexOf(property));
+        }
+        if (property.equals(Property.TABLE_DEFAULT_SCANTIME_VISIBILITY.getKey())) {
+          new ColumnVisibility(value); // validate that it is a valid expression
+        }
+        shellState.getConnector().tableOperations().setProperty(tableName, property, value);
+        Shell.log.debug("Successfully set table configuration option.");
+      } else if (namespace != null) {
+        if (!Property.isValidTablePropertyKey(property)) {
+          throw new BadArgumentException("Invalid per-table property.", fullCommand, fullCommand.indexOf(property));
+        }
+        if (property.equals(Property.TABLE_DEFAULT_SCANTIME_VISIBILITY.getKey())) {
+          new ColumnVisibility(value); // validate that it is a valid expression
+        }
+        shellState.getConnector().namespaceOperations().setProperty(namespace, property, value);
+        Shell.log.debug("Successfully set table configuration option.");
+      } else {
+        if (!Property.isValidZooPropertyKey(property)) {
+          throw new BadArgumentException("Property cannot be modified in zookeeper", fullCommand, fullCommand.indexOf(property));
+        }
+        shellState.getConnector().instanceOperations().setProperty(property, value);
+        Shell.log.debug("Successfully set system configuration option");
+      }
+    } else {
+      // display properties
+      final TreeMap<String,String> systemConfig = new TreeMap<String,String>();
+      systemConfig.putAll(shellState.getConnector().instanceOperations().getSystemConfiguration());
+
+      final String outputFile = cl.getOptionValue(outputFileOpt.getOpt());
+      final PrintFile printFile = outputFile == null ? null : new PrintFile(outputFile);
+
+      final TreeMap<String,String> siteConfig = new TreeMap<String,String>();
+      siteConfig.putAll(shellState.getConnector().instanceOperations().getSiteConfiguration());
+
+      final TreeMap<String,String> defaults = new TreeMap<String,String>();
+      for (Entry<String,String> defaultEntry : AccumuloConfiguration.getDefaultConfiguration()) {
+        defaults.put(defaultEntry.getKey(), defaultEntry.getValue());
+      }
+
+      final TreeMap<String,String> namespaceConfig = new TreeMap<String,String>();
+      if (tableName != null) {
+        String n = Namespaces.getNamespaceName(shellState.getInstance(),
+            Tables.getNamespaceId(shellState.getInstance(), Tables.getTableId(shellState.getInstance(), tableName)));
+        for (Entry<String,String> e : shellState.getConnector().namespaceOperations().getProperties(n)) {
+          namespaceConfig.put(e.getKey(), e.getValue());
+        }
+      }
+
+      Iterable<Entry<String,String>> acuconf = shellState.getConnector().instanceOperations().getSystemConfiguration().entrySet();
+      if (tableName != null) {
+        acuconf = shellState.getConnector().tableOperations().getProperties(tableName);
+      } else if (namespace != null) {
+        acuconf = shellState.getConnector().namespaceOperations().getProperties(namespace);
+      }
+      final TreeMap<String,String> sortedConf = new TreeMap<String,String>();
+      for (Entry<String,String> propEntry : acuconf) {
+        sortedConf.put(propEntry.getKey(), propEntry.getValue());
+      }
+
+      for (Entry<String,String> propEntry : acuconf) {
+        final String key = propEntry.getKey();
+        // only show properties with similar names to that
+        // specified, or all of them if none specified
+        if (cl.hasOption(filterOpt.getOpt()) && !key.contains(cl.getOptionValue(filterOpt.getOpt()))) {
+          continue;
+        }
+        if ((tableName != null || namespace != null) && !Property.isValidTablePropertyKey(key)) {
+          continue;
+        }
+        COL2 = Math.max(COL2, propEntry.getKey().length() + 3);
+      }
+
+      final ArrayList<String> output = new ArrayList<String>();
+      printConfHeader(output);
+
+      for (Entry<String,String> propEntry : sortedConf.entrySet()) {
+        final String key = propEntry.getKey();
+
+        // only show properties with similar names to that
+        // specified, or all of them if none specified
+        if (cl.hasOption(filterOpt.getOpt()) && !key.contains(cl.getOptionValue(filterOpt.getOpt()))) {
+          continue;
+        }
+        if ((tableName != null || namespace != null) && !Property.isValidTablePropertyKey(key)) {
+          continue;
+        }
+        String siteVal = siteConfig.get(key);
+        String sysVal = systemConfig.get(key);
+        String curVal = propEntry.getValue();
+        String dfault = defaults.get(key);
+        String nspVal = namespaceConfig.get(key);
+        boolean printed = false;
+
+        if (dfault != null && key.toLowerCase().contains("password")) {
+          siteVal = sysVal = dfault = curVal = curVal.replaceAll(".", "*");
+        }
+        if (sysVal != null) {
+          if (defaults.containsKey(key) && !Property.getPropertyByKey(key).isExperimental()) {
+            printConfLine(output, "default", key, dfault);
+            printed = true;
+          }
+          if (!defaults.containsKey(key) || !defaults.get(key).equals(siteVal)) {
+            printConfLine(output, "site", printed ? "   @override" : key, siteVal == null ? "" : siteVal);
+            printed = true;
+          }
+          if (!siteConfig.containsKey(key) || !siteVal.equals(sysVal)) {
+            printConfLine(output, "system", printed ? "   @override" : key, sysVal == null ? "" : sysVal);
+            printed = true;
+          }
+
+        }
+        if (nspVal != null) {
+          if (!systemConfig.containsKey(key) || !sysVal.equals(nspVal)) {
+            printConfLine(output, "namespace", printed ? "   @override" : key, nspVal == null ? "" : nspVal);
+            printed = true;
+          }
+        }
+
+        // show per-table value only if it is different (overridden)
+        if (tableName != null && !curVal.equals(nspVal)) {
+          printConfLine(output, "table", printed ? "   @override" : key, curVal);
+        } else if (namespace != null && !curVal.equals(sysVal)) {
+          printConfLine(output, "namespace", printed ? "   @override" : key, curVal);
+        }
+      }
+      printConfFooter(output);
+      shellState.printLines(output.iterator(), !cl.hasOption(disablePaginationOpt.getOpt()), printFile);
+      if (printFile != null) {
+        printFile.close();
+      }
+    }
+    return 0;
+  }
+
+  private void printConfHeader(List<String> output) {
+    printConfFooter(output);
+    output.add(String.format("%-" + COL1 + "s | %-" + COL2 + "s | %s", "SCOPE", "NAME", "VALUE"));
+    printConfFooter(output);
+  }
+
+  private void printConfLine(List<String> output, String s1, String s2, String s3) {
+    if (s2.length() < COL2) {
+      s2 += " " + Shell.repeat(".", COL2 - s2.length() - 1);
+    }
+    output.add(String.format("%-" + COL1 + "s | %-" + COL2 + "s | %s", s1, s2,
+        s3.replace("\n", "\n" + Shell.repeat(" ", COL1 + 1) + "|" + Shell.repeat(" ", COL2 + 2) + "|" + " ")));
+  }
+
+  private void printConfFooter(List<String> output) {
+    int col3 = Math.max(1, Math.min(Integer.MAX_VALUE, reader.getTerminal().getWidth() - COL1 - COL2 - 6));
+    output.add(String.format("%" + COL1 + "s-+-%" + COL2 + "s-+-%-" + col3 + "s", Shell.repeat("-", COL1), Shell.repeat("-", COL2), Shell.repeat("-", col3)));
+  }
+
+  @Override
+  public String description() {
+    return "prints system properties and table specific properties";
+  }
+
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+    final OptionGroup og = new OptionGroup();
+    final OptionGroup tgroup = new OptionGroup();
+
+    tableOpt = new Option(Shell.tableOption, "table", true, "table to display/set/delete properties for");
+    deleteOpt = new Option("d", "delete", true, "delete a per-table property");
+    setOpt = new Option("s", "set", true, "set a per-table property");
+    filterOpt = new Option("f", "filter", true, "show only properties that contain this string");
+    disablePaginationOpt = new Option("np", "no-pagination", false, "disables pagination of output");
+    outputFileOpt = new Option("o", "output", true, "local file to write the scan output to");
+    namespaceOpt = new Option(Shell.namespaceOption, "namespace", true, "namespace to display/set/delete properties for");
+
+    tableOpt.setArgName("table");
+    deleteOpt.setArgName("property");
+    setOpt.setArgName("property=value");
+    filterOpt.setArgName("string");
+    outputFileOpt.setArgName("file");
+    namespaceOpt.setArgName("namespace");
+
+    og.addOption(deleteOpt);
+    og.addOption(setOpt);
+    og.addOption(filterOpt);
+
+    tgroup.addOption(tableOpt);
+    tgroup.addOption(namespaceOpt);
+
+    o.addOptionGroup(tgroup);
+    o.addOptionGroup(og);
+    o.addOption(disablePaginationOpt);
+    o.addOption(outputFileOpt);
+
+    return o;
+  }
+
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/ConstraintCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/ConstraintCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/ConstraintCommand.java
new file mode 100644
index 0000000..0b6adbf
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/ConstraintCommand.java
@@ -0,0 +1,134 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.util.Map.Entry;
+
+import org.apache.accumulo.core.constraints.Constraint;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.ShellCommandException;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.accumulo.shell.ShellCommandException.ErrorCode;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.OptionGroup;
+import org.apache.commons.cli.Options;
+
+public class ConstraintCommand extends Command {
+  protected Option namespaceOpt;
+
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    final String tableName;
+    final String namespace;
+
+    if (cl.hasOption(namespaceOpt.getOpt())) {
+      namespace = cl.getOptionValue(namespaceOpt.getOpt());
+    } else {
+      namespace = null;
+    }
+
+    if (cl.hasOption(OptUtil.tableOpt().getOpt()) || !shellState.getTableName().isEmpty()) {
+      tableName = OptUtil.getTableOpt(cl, shellState);
+    } else {
+      tableName = null;
+    }
+
+    int i;
+    switch (OptUtil.getAldOpt(cl)) {
+      case ADD:
+        for (String constraint : cl.getArgs()) {
+          if (namespace != null) {
+            if (!shellState.getConnector().namespaceOperations().testClassLoad(namespace, constraint, Constraint.class.getName())) {
+              throw new ShellCommandException(ErrorCode.INITIALIZATION_FAILURE, "Servers are unable to load " + constraint + " as type "
+                  + Constraint.class.getName());
+            }
+            i = shellState.getConnector().namespaceOperations().addConstraint(namespace, constraint);
+            shellState.getReader().println("Added constraint " + constraint + " to namespace " + namespace + " with number " + i);
+          } else if (tableName != null && !tableName.isEmpty()) {
+            if (!shellState.getConnector().tableOperations().testClassLoad(tableName, constraint, Constraint.class.getName())) {
+              throw new ShellCommandException(ErrorCode.INITIALIZATION_FAILURE, "Servers are unable to load " + constraint + " as type "
+                  + Constraint.class.getName());
+            }
+            i = shellState.getConnector().tableOperations().addConstraint(tableName, constraint);
+            shellState.getReader().println("Added constraint " + constraint + " to table " + tableName + " with number " + i);
+          } else {
+            throw new IllegalArgumentException("Please specify either a table or a namespace");
+          }
+        }
+        break;
+      case DELETE:
+        for (String constraint : cl.getArgs()) {
+          i = Integer.parseInt(constraint);
+          if (namespace != null) {
+            shellState.getConnector().namespaceOperations().removeConstraint(namespace, i);
+            shellState.getReader().println("Removed constraint " + i + " from namespace " + namespace);
+          } else if (tableName != null) {
+            shellState.getConnector().tableOperations().removeConstraint(tableName, i);
+            shellState.getReader().println("Removed constraint " + i + " from table " + tableName);
+          } else {
+            throw new IllegalArgumentException("Please specify either a table or a namespace");
+          }
+        }
+        break;
+      case LIST:
+        if (namespace != null) {
+          for (Entry<String,Integer> property : shellState.getConnector().namespaceOperations().listConstraints(namespace).entrySet()) {
+            shellState.getReader().println(property.toString());
+          }
+        } else if (tableName != null) {
+          for (Entry<String,Integer> property : shellState.getConnector().tableOperations().listConstraints(tableName).entrySet()) {
+            shellState.getReader().println(property.toString());
+          }
+        } else {
+          throw new IllegalArgumentException("Please specify either a table or a namespace");
+        }
+    }
+
+    return 0;
+  }
+
+  @Override
+  public String description() {
+    return "adds, deletes, or lists constraints for a table";
+  }
+
+  @Override
+  public int numArgs() {
+    return Shell.NO_FIXED_ARG_LENGTH_CHECK;
+  }
+
+  @Override
+  public String usage() {
+    return getName() + " <constraint>{ <constraint>}";
+  }
+
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+    o.addOptionGroup(OptUtil.addListDeleteGroup("constraint"));
+
+    OptionGroup grp = new OptionGroup();
+    grp.addOption(OptUtil.tableOpt("table to add, delete, or list constraints for"));
+    namespaceOpt = new Option(Shell.namespaceOption, "namespace", true, "name of a namespace to operate on");
+    namespaceOpt.setArgName("namespace");
+    grp.addOption(namespaceOpt);
+
+    o.addOptionGroup(grp);
+    return o;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/CreateNamespaceCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/CreateNamespaceCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/CreateNamespaceCommand.java
new file mode 100644
index 0000000..e278105
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/CreateNamespaceCommand.java
@@ -0,0 +1,99 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.io.IOException;
+import java.util.Map.Entry;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.NamespaceExistsException;
+import org.apache.accumulo.core.client.NamespaceNotFoundException;
+import org.apache.accumulo.core.client.TableExistsException;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.core.conf.Property;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.OptionGroup;
+import org.apache.commons.cli.Options;
+
+public class CreateNamespaceCommand extends Command {
+  private Option createNamespaceOptCopyConfig;
+
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException,
+      TableExistsException, TableNotFoundException, IOException, ClassNotFoundException, NamespaceExistsException, NamespaceNotFoundException {
+
+    if (createNamespaceOptCopyConfig == null) {
+      getOptions();
+    }
+
+    String namespace = cl.getArgs()[0];
+
+    shellState.getConnector().namespaceOperations().create(namespace);
+
+    // Copy options if flag was set
+    Iterable<Entry<String,String>> configuration = null;
+    if (cl.hasOption(createNamespaceOptCopyConfig.getOpt())) {
+      String copy = cl.getOptionValue(createNamespaceOptCopyConfig.getOpt());
+      if (shellState.getConnector().namespaceOperations().exists(namespace)) {
+        configuration = shellState.getConnector().namespaceOperations().getProperties(copy);
+      }
+    } 
+    if (configuration != null) {
+      for (Entry<String,String> entry : configuration) {
+        if (Property.isValidTablePropertyKey(entry.getKey())) {
+          shellState.getConnector().namespaceOperations().setProperty(namespace, entry.getKey(), entry.getValue());
+        }
+      }
+    }
+
+    return 0;
+  }
+
+  @Override
+  public String description() {
+    return "creates a new namespace";
+  }
+
+  @Override
+  public String usage() {
+    return getName() + " <namespaceName>";
+  }
+
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+
+    createNamespaceOptCopyConfig = new Option("cc", "copy-config", true, "namespace to copy configuration from");
+    createNamespaceOptCopyConfig.setArgName("namespace");
+
+    OptionGroup ogp = new OptionGroup();
+    ogp.addOption(createNamespaceOptCopyConfig);
+
+    o.addOptionGroup(ogp);
+
+    return o;
+  }
+
+  @Override
+  public int numArgs() {
+    return 1;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/CreateTableCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/CreateTableCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/CreateTableCommand.java
new file mode 100644
index 0000000..81b39d2
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/CreateTableCommand.java
@@ -0,0 +1,203 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.io.IOException;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.TableExistsException;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.core.client.admin.TimeType;
+import org.apache.accumulo.core.client.impl.Tables;
+import org.apache.accumulo.core.conf.Property;
+import org.apache.accumulo.core.iterators.IteratorUtil;
+import org.apache.accumulo.core.security.VisibilityConstraint;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.ShellUtil;
+import org.apache.accumulo.shell.Token;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.OptionGroup;
+import org.apache.commons.cli.Options;
+import org.apache.hadoop.io.Text;
+
+public class CreateTableCommand extends Command {
+  private Option createTableOptCopySplits;
+  private Option createTableOptCopyConfig;
+  private Option createTableOptSplit;
+  private Option createTableOptTimeLogical;
+  private Option createTableOptTimeMillis;
+  private Option createTableNoDefaultIters;
+  private Option createTableOptEVC;
+  private Option base64Opt;
+  private Option createTableOptFormatter;
+
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException,
+      TableExistsException, TableNotFoundException, IOException, ClassNotFoundException {
+
+    final String testTableName = cl.getArgs()[0];
+
+    if (!testTableName.matches(Tables.VALID_NAME_REGEX)) {
+      shellState.getReader().println("Only letters, numbers and underscores are allowed for use in table names.");
+      throw new IllegalArgumentException();
+    }
+
+    final String tableName = cl.getArgs()[0];
+    if (shellState.getConnector().tableOperations().exists(tableName)) {
+      throw new TableExistsException(null, tableName, null);
+    }
+    final SortedSet<Text> partitions = new TreeSet<Text>();
+    final boolean decode = cl.hasOption(base64Opt.getOpt());
+
+    if (cl.hasOption(createTableOptSplit.getOpt())) {
+      partitions.addAll(ShellUtil.scanFile(cl.getOptionValue(createTableOptSplit.getOpt()), decode));
+    } else if (cl.hasOption(createTableOptCopySplits.getOpt())) {
+      final String oldTable = cl.getOptionValue(createTableOptCopySplits.getOpt());
+      if (!shellState.getConnector().tableOperations().exists(oldTable)) {
+        throw new TableNotFoundException(null, oldTable, null);
+      }
+      partitions.addAll(shellState.getConnector().tableOperations().listSplits(oldTable));
+    }
+
+    if (cl.hasOption(createTableOptCopyConfig.getOpt())) {
+      final String oldTable = cl.getOptionValue(createTableOptCopyConfig.getOpt());
+      if (!shellState.getConnector().tableOperations().exists(oldTable)) {
+        throw new TableNotFoundException(null, oldTable, null);
+      }
+    }
+
+    TimeType timeType = TimeType.MILLIS;
+    if (cl.hasOption(createTableOptTimeLogical.getOpt())) {
+      timeType = TimeType.LOGICAL;
+    }
+
+    // create table
+    shellState.getConnector().tableOperations().create(tableName, true, timeType);
+    if (partitions.size() > 0) {
+      shellState.getConnector().tableOperations().addSplits(tableName, partitions);
+    }
+
+    shellState.setTableName(tableName); // switch shell to new table context
+
+    if (cl.hasOption(createTableNoDefaultIters.getOpt())) {
+      for (String key : IteratorUtil.generateInitialTableProperties(true).keySet()) {
+        shellState.getConnector().tableOperations().removeProperty(tableName, key);
+      }
+    }
+
+    // Copy options if flag was set
+    if (cl.hasOption(createTableOptCopyConfig.getOpt())) {
+      if (shellState.getConnector().tableOperations().exists(tableName)) {
+        final Iterable<Entry<String,String>> configuration = shellState.getConnector().tableOperations()
+            .getProperties(cl.getOptionValue(createTableOptCopyConfig.getOpt()));
+        for (Entry<String,String> entry : configuration) {
+          if (Property.isValidTablePropertyKey(entry.getKey())) {
+            shellState.getConnector().tableOperations().setProperty(tableName, entry.getKey(), entry.getValue());
+          }
+        }
+      }
+    }
+
+    if (cl.hasOption(createTableOptEVC.getOpt())) {
+      try {
+        shellState.getConnector().tableOperations().addConstraint(tableName, VisibilityConstraint.class.getName());
+      } catch (AccumuloException e) {
+        Shell.log.warn(e.getMessage() + " while setting visibility constraint, but table was created");
+      }
+    }
+
+    // Load custom formatter if set
+    if (cl.hasOption(createTableOptFormatter.getOpt())) {
+      final String formatterClass = cl.getOptionValue(createTableOptFormatter.getOpt());
+
+      shellState.getConnector().tableOperations().setProperty(tableName, Property.TABLE_FORMATTER_CLASS.toString(), formatterClass);
+    }
+
+    return 0;
+  }
+
+  @Override
+  public String description() {
+    return "creates a new table, with optional aggregators and optionally pre-split";
+  }
+
+  @Override
+  public String usage() {
+    return getName() + " <tableName>";
+  }
+
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+
+    createTableOptCopyConfig = new Option("cc", "copy-config", true, "table to copy configuration from");
+    createTableOptCopySplits = new Option("cs", "copy-splits", true, "table to copy current splits from");
+    createTableOptSplit = new Option("sf", "splits-file", true, "file with a newline-separated list of rows to split the table with");
+    createTableOptTimeLogical = new Option("tl", "time-logical", false, "use logical time");
+    createTableOptTimeMillis = new Option("tm", "time-millis", false, "use time in milliseconds");
+    createTableNoDefaultIters = new Option("ndi", "no-default-iterators", false, "prevent creation of the normal default iterator set");
+    createTableOptEVC = new Option("evc", "enable-visibility-constraint", false,
+        "prevent users from writing data they cannot read.  When enabling this, consider disabling bulk import and alter table.");
+    createTableOptFormatter = new Option("f", "formatter", true, "default formatter to set");
+
+    createTableOptCopyConfig.setArgName("table");
+    createTableOptCopySplits.setArgName("table");
+    createTableOptSplit.setArgName("filename");
+    createTableOptFormatter.setArgName("className");
+
+    // Splits and CopySplits are put in an optionsgroup to make them
+    // mutually exclusive
+    final OptionGroup splitOrCopySplit = new OptionGroup();
+    splitOrCopySplit.addOption(createTableOptSplit);
+    splitOrCopySplit.addOption(createTableOptCopySplits);
+
+    final OptionGroup timeGroup = new OptionGroup();
+    timeGroup.addOption(createTableOptTimeLogical);
+    timeGroup.addOption(createTableOptTimeMillis);
+
+    base64Opt = new Option("b64", "base64encoded", false, "decode encoded split points");
+    o.addOption(base64Opt);
+
+    o.addOptionGroup(splitOrCopySplit);
+    o.addOptionGroup(timeGroup);
+    o.addOption(createTableOptSplit);
+    o.addOption(createTableOptCopyConfig);
+    o.addOption(createTableNoDefaultIters);
+    o.addOption(createTableOptEVC);
+    o.addOption(createTableOptFormatter);
+
+    return o;
+  }
+
+  @Override
+  public int numArgs() {
+    return 1;
+  }
+
+  @Override
+  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> special) {
+    registerCompletionForNamespaces(root, special);
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/CreateUserCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/CreateUserCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/CreateUserCommand.java
new file mode 100644
index 0000000..2a7359f
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/CreateUserCommand.java
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.accumulo.shell.commands;
+
+import java.io.IOException;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.TableExistsException;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.core.client.security.tokens.PasswordToken;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Options;
+
+public class CreateUserCommand extends Command {
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, TableNotFoundException,
+      AccumuloSecurityException, TableExistsException, IOException {
+    final String user = cl.getArgs()[0];
+    
+    final String password = shellState.readMaskedLine("Enter new password for '" + user + "': ", '*');
+    if (password == null) {
+      shellState.getReader().println();
+      return 0;
+    } // user canceled
+    String passwordConfirm = shellState.readMaskedLine("Please confirm new password for '" + user + "': ", '*');
+    if (passwordConfirm == null) {
+      shellState.getReader().println();
+      return 0;
+    } // user canceled
+    
+    if (!password.equals(passwordConfirm)) {
+      throw new IllegalArgumentException("Passwords do not match");
+    }
+    shellState.getConnector().securityOperations().createLocalUser(user, new PasswordToken(password));
+    Shell.log.debug("Created user " + user);
+    return 0;
+  }
+  
+  @Override
+  public String usage() {
+    return getName() + " <username>";
+  }
+  
+  @Override
+  public String description() {
+    return "creates a new user";
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+    return o;
+  }
+  
+  @Override
+  public int numArgs() {
+    return 1;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/DUCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/DUCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/DUCommand.java
new file mode 100644
index 0000000..eb6aeb5
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/DUCommand.java
@@ -0,0 +1,124 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import org.apache.accumulo.core.client.Instance;
+import org.apache.accumulo.core.client.NamespaceNotFoundException;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.core.client.admin.DiskUsage;
+import org.apache.accumulo.core.client.impl.Namespaces;
+import org.apache.accumulo.core.util.NumUtil;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+
+public class DUCommand extends Command {
+
+  private Option optTablePattern, optHumanReadble, optNamespace;
+
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws IOException, TableNotFoundException,
+      NamespaceNotFoundException {
+
+    final SortedSet<String> tables = new TreeSet<String>(Arrays.asList(cl.getArgs()));
+
+    if (cl.hasOption(Shell.tableOption)) {
+      String tableName = cl.getOptionValue(Shell.tableOption);
+      if (!shellState.getConnector().tableOperations().exists(tableName)) {
+        throw new TableNotFoundException(tableName, tableName, "specified table that doesn't exist");
+      }
+      tables.add(tableName);
+    }
+
+    if (cl.hasOption(optNamespace.getOpt())) {
+      Instance instance = shellState.getInstance();
+      String namespaceId = Namespaces.getNamespaceId(instance, cl.getOptionValue(optNamespace.getOpt()));
+      tables.addAll(Namespaces.getTableNames(instance, namespaceId));
+    }
+
+    boolean prettyPrint = cl.hasOption(optHumanReadble.getOpt()) ? true : false;
+
+    // Add any patterns
+    if (cl.hasOption(optTablePattern.getOpt())) {
+      for (String table : shellState.getConnector().tableOperations().list()) {
+        if (table.matches(cl.getOptionValue(optTablePattern.getOpt()))) {
+          tables.add(table);
+        }
+      }
+    }
+
+    // If we didn't get any tables, and we have a table selected, add the current table
+    if (tables.isEmpty() && !shellState.getTableName().isEmpty()) {
+      tables.add(shellState.getTableName());
+    }
+
+    try {
+      String valueFormat = prettyPrint ? "%9s" : "%,24d";
+      for (DiskUsage usage : shellState.getConnector().tableOperations().getDiskUsage(tables)) {
+        Object value = prettyPrint ? NumUtil.bigNumberForSize(usage.getUsage()) : usage.getUsage();
+        shellState.getReader().println(String.format(valueFormat + " %s", value, usage.getTables()));
+      }
+    } catch (Exception ex) {
+      throw new RuntimeException(ex);
+    }
+    return 0;
+  }
+
+  @Override
+  public String description() {
+    return "prints how much space, in bytes, is used by files referenced by a table.  When multiple tables are specified it prints how much space, in bytes, is used by files shared between tables, if any.";
+  }
+
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+
+    optTablePattern = new Option("p", "pattern", true, "regex pattern of table names");
+    optTablePattern.setArgName("pattern");
+
+    optHumanReadble = new Option("h", "human-readable", false, "format large sizes to human readable units");
+    optHumanReadble.setArgName("human readable output");
+
+    optNamespace = new Option(Shell.namespaceOption, "namespace", true, "name of a namespace");
+    optNamespace.setArgName("namespace");
+
+    o.addOption(OptUtil.tableOpt("table to examine"));
+
+    o.addOption(optTablePattern);
+    o.addOption(optHumanReadble);
+    o.addOption(optNamespace);
+
+    return o;
+  }
+
+  @Override
+  public String usage() {
+    return getName() + " <table>{ <table>}";
+  }
+
+  @Override
+  public int numArgs() {
+    return Shell.NO_FIXED_ARG_LENGTH_CHECK;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/DebugCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/DebugCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/DebugCommand.java
new file mode 100644
index 0000000..ab40adc
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/DebugCommand.java
@@ -0,0 +1,71 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.accumulo.core.util.BadArgumentException;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Token;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+
+public class DebugCommand extends Command {
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws IOException {
+    if (cl.getArgs().length == 1) {
+      if (cl.getArgs()[0].equalsIgnoreCase("on")) {
+        Shell.setDebugging(true);
+      } else if (cl.getArgs()[0].equalsIgnoreCase("off")) {
+        Shell.setDebugging(false);
+      } else {
+        throw new BadArgumentException("Argument must be 'on' or 'off'", fullCommand, fullCommand.indexOf(cl.getArgs()[0]));
+      }
+    } else if (cl.getArgs().length == 0) {
+      shellState.getReader().println(Shell.isDebuggingEnabled() ? "on" : "off");
+    } else {
+      shellState.printException(new IllegalArgumentException("Expected 0 or 1 argument. There were " + cl.getArgs().length + "."));
+      printHelp(shellState);
+      return 1;
+    }
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "turns debug logging on or off";
+  }
+  
+  @Override
+  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> special) {
+    final Token debug_command = new Token(getName());
+    debug_command.addSubcommand(Arrays.asList(new String[] {"on", "off"}));
+    root.addSubcommand(debug_command);
+  }
+  
+  @Override
+  public String usage() {
+    return getName() + " [ on | off ]";
+  }
+  
+  @Override
+  public int numArgs() {
+    return Shell.NO_FIXED_ARG_LENGTH_CHECK;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteCommand.java
new file mode 100644
index 0000000..2601f58
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteCommand.java
@@ -0,0 +1,112 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.io.IOException;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.BatchWriter;
+import org.apache.accumulo.core.client.BatchWriterConfig;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.core.conf.AccumuloConfiguration;
+import org.apache.accumulo.core.data.Mutation;
+import org.apache.accumulo.core.security.ColumnVisibility;
+import org.apache.accumulo.core.tabletserver.thrift.ConstraintViolationException;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+import org.apache.hadoop.io.Text;
+
+public class DeleteCommand extends Command {
+  private Option deleteOptAuths, timestampOpt;
+  private Option timeoutOption;
+  
+  protected long getTimeout(final CommandLine cl) {
+    if (cl.hasOption(timeoutOption.getLongOpt())) {
+      return AccumuloConfiguration.getTimeInMillis(cl.getOptionValue(timeoutOption.getLongOpt()));
+    }
+    
+    return Long.MAX_VALUE;
+  }
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException,
+      TableNotFoundException, IOException, ConstraintViolationException {
+    shellState.checkTableState();
+    
+    final Mutation m = new Mutation(new Text(cl.getArgs()[0].getBytes(Shell.CHARSET)));
+    final Text colf = new Text(cl.getArgs()[1].getBytes(Shell.CHARSET));
+    final Text colq = new Text(cl.getArgs()[2].getBytes(Shell.CHARSET));
+    
+    if (cl.hasOption(deleteOptAuths.getOpt())) {
+      final ColumnVisibility le = new ColumnVisibility(cl.getOptionValue(deleteOptAuths.getOpt()));
+      if (cl.hasOption(timestampOpt.getOpt())) {
+        m.putDelete(colf, colq, le, Long.parseLong(cl.getOptionValue(timestampOpt.getOpt())));
+      } else {
+        m.putDelete(colf, colq, le);
+      }
+    } else if (cl.hasOption(timestampOpt.getOpt())) {
+      m.putDelete(colf, colq, Long.parseLong(cl.getOptionValue(timestampOpt.getOpt())));
+    } else {
+      m.putDelete(colf, colq);
+    }
+    final BatchWriter bw = shellState.getConnector().createBatchWriter(shellState.getTableName(),
+        new BatchWriterConfig().setMaxMemory(Math.max(m.estimatedMemoryUsed(), 1024)).setMaxWriteThreads(1).setTimeout(getTimeout(cl), TimeUnit.MILLISECONDS));
+    bw.addMutation(m);
+    bw.close();
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "deletes a record from a table";
+  }
+  
+  @Override
+  public String usage() {
+    return getName() + " <row> <colfamily> <colqualifier>";
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+    
+    deleteOptAuths = new Option("l", "visibility-label", true, "formatted visibility");
+    deleteOptAuths.setArgName("expression");
+    o.addOption(deleteOptAuths);
+    
+    timestampOpt = new Option("ts", "timestamp", true, "timestamp to use for deletion");
+    timestampOpt.setArgName("timestamp");
+    o.addOption(timestampOpt);
+    
+    timeoutOption = new Option(null, "timeout", true,
+        "time before insert should fail if no data is written. If no unit is given assumes seconds.  Units d,h,m,s,and ms are supported.  e.g. 30s or 100ms");
+    timeoutOption.setArgName("timeout");
+    o.addOption(timeoutOption);
+    
+    return o;
+  }
+  
+  @Override
+  public int numArgs() {
+    return 3;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteIterCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteIterCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteIterCommand.java
new file mode 100644
index 0000000..ec60aee
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteIterCommand.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.accumulo.shell.commands;
+
+import java.util.EnumSet;
+
+import org.apache.accumulo.core.iterators.IteratorUtil.IteratorScope;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.OptionGroup;
+import org.apache.commons.cli.Options;
+
+public class DeleteIterCommand extends Command {
+  private Option allScopeOpt, mincScopeOpt, majcScopeOpt, scanScopeOpt, nameOpt;
+
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+
+    boolean tables = cl.hasOption(OptUtil.tableOpt().getOpt()) || !shellState.getTableName().isEmpty();
+    boolean namespaces = cl.hasOption(OptUtil.namespaceOpt().getOpt());
+
+    final String name = cl.getOptionValue(nameOpt.getOpt());
+
+    if (namespaces) {
+      if (!shellState.getConnector().namespaceOperations().listIterators(OptUtil.getNamespaceOpt(cl, shellState)).containsKey(name)) {
+        Shell.log.warn("no iterators found that match your criteria");
+        return 0;
+      }
+    } else if (tables) {
+      if (!shellState.getConnector().tableOperations().listIterators(OptUtil.getTableOpt(cl, shellState)).containsKey(name)) {
+        Shell.log.warn("no iterators found that match your criteria");
+        return 0;
+      }
+    } else {
+      throw new IllegalArgumentException("No table or namespace specified");
+    }
+
+    final EnumSet<IteratorScope> scopes = EnumSet.noneOf(IteratorScope.class);
+    if (cl.hasOption(allScopeOpt.getOpt()) || cl.hasOption(mincScopeOpt.getOpt())) {
+      scopes.add(IteratorScope.minc);
+    }
+    if (cl.hasOption(allScopeOpt.getOpt()) || cl.hasOption(majcScopeOpt.getOpt())) {
+      scopes.add(IteratorScope.majc);
+    }
+    if (cl.hasOption(allScopeOpt.getOpt()) || cl.hasOption(scanScopeOpt.getOpt())) {
+      scopes.add(IteratorScope.scan);
+    }
+    if (scopes.isEmpty()) {
+      throw new IllegalArgumentException("You must select at least one scope to configure");
+    }
+
+    if (namespaces) {
+      shellState.getConnector().namespaceOperations().removeIterator(OptUtil.getNamespaceOpt(cl, shellState), name, scopes);
+    } else if (tables) {
+      shellState.getConnector().tableOperations().removeIterator(OptUtil.getTableOpt(cl, shellState), name, scopes);
+    } else {
+      throw new IllegalArgumentException("No table or namespace specified");
+    }
+    return 0;
+  }
+
+  @Override
+  public String description() {
+    return "deletes a table-specific or namespace-specific iterator";
+  }
+
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+
+    nameOpt = new Option("n", "name", true, "iterator to delete");
+    nameOpt.setArgName("itername");
+    nameOpt.setRequired(true);
+
+    allScopeOpt = new Option("all", "all-scopes", false, "remove from all scopes");
+    mincScopeOpt = new Option(IteratorScope.minc.name(), "minor-compaction", false, "remove from minor compaction scope");
+    majcScopeOpt = new Option(IteratorScope.majc.name(), "major-compaction", false, "remove from major compaction scope");
+    scanScopeOpt = new Option(IteratorScope.scan.name(), "scan-time", false, "remove from scan scope");
+
+    OptionGroup grp = new OptionGroup();
+    grp.addOption(OptUtil.tableOpt("table to delete the iterator from"));
+    grp.addOption(OptUtil.namespaceOpt("namespace to delete the iterator from"));
+    o.addOptionGroup(grp);
+    o.addOption(nameOpt);
+
+    o.addOption(allScopeOpt);
+    o.addOption(mincScopeOpt);
+    o.addOption(majcScopeOpt);
+    o.addOption(scanScopeOpt);
+
+    return o;
+  }
+
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteManyCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteManyCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteManyCommand.java
new file mode 100644
index 0000000..c29a92c
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteManyCommand.java
@@ -0,0 +1,82 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.util.concurrent.TimeUnit;
+
+import org.apache.accumulo.core.client.BatchWriter;
+import org.apache.accumulo.core.client.BatchWriterConfig;
+import org.apache.accumulo.core.client.IteratorSetting;
+import org.apache.accumulo.core.client.Scanner;
+import org.apache.accumulo.core.iterators.SortedKeyIterator;
+import org.apache.accumulo.core.security.Authorizations;
+import org.apache.accumulo.core.util.interpret.ScanInterpreter;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.format.DeleterFormatter;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+
+public class DeleteManyCommand extends ScanCommand {
+  private Option forceOpt;
+  
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    final String tableName = OptUtil.getTableOpt(cl, shellState);
+    
+    final ScanInterpreter interpeter = getInterpreter(cl, tableName, shellState);
+
+    // handle first argument, if present, the authorizations list to
+    // scan with
+    final Authorizations auths = getAuths(cl, shellState);
+    final Scanner scanner = shellState.getConnector().createScanner(tableName, auths);
+    
+    scanner.addScanIterator(new IteratorSetting(Integer.MAX_VALUE, "NOVALUE", SortedKeyIterator.class));
+    
+    // handle session-specific scan iterators
+    addScanIterators(shellState, cl, scanner, tableName);
+    
+    // handle remaining optional arguments
+    scanner.setRange(getRange(cl, interpeter));
+    
+    scanner.setTimeout(getTimeout(cl), TimeUnit.MILLISECONDS);
+
+    // handle columns
+    fetchColumns(cl, scanner, interpeter);
+    
+    // output / delete the records
+    final BatchWriter writer = shellState.getConnector()
+        .createBatchWriter(tableName, new BatchWriterConfig().setTimeout(getTimeout(cl), TimeUnit.MILLISECONDS));
+    shellState.printLines(new DeleterFormatter(writer, scanner, cl.hasOption(timestampOpt.getOpt()), shellState, cl.hasOption(forceOpt.getOpt())), false);
+    
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "scans a table and deletes the resulting records";
+  }
+  
+  @Override
+  public Options getOptions() {
+    forceOpt = new Option("f", "force", false, "force deletion without prompting");
+    final Options opts = super.getOptions();
+    opts.addOption(forceOpt);
+    opts.addOption(OptUtil.tableOpt("table to delete entries from"));
+    return opts;
+  }
+  
+}


[18/53] [abbrv] git commit: ACCUMULO-2551 Fix type safety and import warnings.

Posted by el...@apache.org.
ACCUMULO-2551 Fix type safety and import warnings.


Project: http://git-wip-us.apache.org/repos/asf/accumulo/repo
Commit: http://git-wip-us.apache.org/repos/asf/accumulo/commit/5363d781
Tree: http://git-wip-us.apache.org/repos/asf/accumulo/tree/5363d781
Diff: http://git-wip-us.apache.org/repos/asf/accumulo/diff/5363d781

Branch: refs/heads/ACCUMULO-378
Commit: 5363d781d3c7f304765c1bdef93969e84f1d934f
Parents: e33c1f4
Author: Christopher Tubbs <ct...@apache.org>
Authored: Mon Apr 7 20:07:28 2014 -0400
Committer: Christopher Tubbs <ct...@apache.org>
Committed: Mon Apr 7 20:07:28 2014 -0400

----------------------------------------------------------------------
 .../org/apache/accumulo/fate/ReadOnlyStore.java | 22 ++++++------
 .../java/org/apache/accumulo/fate/TStore.java   | 16 ++++-----
 .../org/apache/accumulo/server/fate/Admin.java  | 38 +++++++++-----------
 .../test/continuous/ContinuousVerify.java       |  1 -
 4 files changed, 35 insertions(+), 42 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/accumulo/blob/5363d781/fate/src/main/java/org/apache/accumulo/fate/ReadOnlyStore.java
----------------------------------------------------------------------
diff --git a/fate/src/main/java/org/apache/accumulo/fate/ReadOnlyStore.java b/fate/src/main/java/org/apache/accumulo/fate/ReadOnlyStore.java
index 7cb20ff..ad5e7e1 100644
--- a/fate/src/main/java/org/apache/accumulo/fate/ReadOnlyStore.java
+++ b/fate/src/main/java/org/apache/accumulo/fate/ReadOnlyStore.java
@@ -16,26 +16,25 @@
  */
 package org.apache.accumulo.fate;
 
-import org.apache.accumulo.fate.ReadOnlyTStore.TStatus;
-import com.google.common.base.Preconditions;
-
 import java.io.Serializable;
 import java.util.EnumSet;
 import java.util.List;
 
+import com.google.common.base.Preconditions;
+
 /**
  * This store decorates a TStore to make sure it can not be modified.
- *
- * Unlike relying directly on the ReadOnlyTStore interface, this class will not allow subsequent users to cast back to a
- * mutable TStore successfully.
- *
+ * 
+ * Unlike relying directly on the ReadOnlyTStore interface, this class will not allow subsequent users to cast back to a mutable TStore successfully.
+ * 
  */
 public class ReadOnlyStore<T> implements ReadOnlyTStore<T> {
 
   private final TStore<T> store;
 
   /**
-   * @param store may not be null
+   * @param store
+   *          may not be null
    */
   public ReadOnlyStore(TStore<T> store) {
     Preconditions.checkNotNull(store);
@@ -59,14 +58,15 @@ public class ReadOnlyStore<T> implements ReadOnlyTStore<T> {
 
   /**
    * Decorates a Repo to make sure it is treated as a ReadOnlyRepo.
-   *
+   * 
    * Similar to ReadOnlyStore, won't allow subsequent user to cast a ReadOnlyRepo back to a mutable Repo.
    */
   protected static class ReadOnlyRepoWrapper<X> implements ReadOnlyRepo<X> {
     private final Repo<X> repo;
 
     /**
-     * @param repo may not be null
+     * @param repo
+     *          may not be null
      */
     public ReadOnlyRepoWrapper(Repo<X> repo) {
       Preconditions.checkNotNull(repo);
@@ -86,7 +86,7 @@ public class ReadOnlyStore<T> implements ReadOnlyTStore<T> {
 
   @Override
   public ReadOnlyRepo<T> top(long tid) {
-    return new ReadOnlyRepoWrapper(store.top(tid));
+    return new ReadOnlyRepoWrapper<T>(store.top(tid));
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/accumulo/blob/5363d781/fate/src/main/java/org/apache/accumulo/fate/TStore.java
----------------------------------------------------------------------
diff --git a/fate/src/main/java/org/apache/accumulo/fate/TStore.java b/fate/src/main/java/org/apache/accumulo/fate/TStore.java
index 5ca24fc..882cdbd 100644
--- a/fate/src/main/java/org/apache/accumulo/fate/TStore.java
+++ b/fate/src/main/java/org/apache/accumulo/fate/TStore.java
@@ -17,8 +17,6 @@
 package org.apache.accumulo.fate;
 
 import java.io.Serializable;
-import java.util.EnumSet;
-import java.util.List;
 
 /**
  * Transaction Store: a place to save transactions
@@ -28,14 +26,14 @@ import java.util.List;
  * fails, the stack can be unwound, undoing each operation.
  */
 public interface TStore<T> extends ReadOnlyTStore<T> {
-  
+
   /**
    * Create a new transaction id
    * 
    * @return a transaction id
    */
   long create();
-  
+
   /**
    * Get the current operation for the given transaction id.
    * 
@@ -45,7 +43,7 @@ public interface TStore<T> extends ReadOnlyTStore<T> {
    */
   @Override
   Repo<T> top(long tid);
-  
+
   /**
    * Update the given transaction with the next operation
    * 
@@ -55,14 +53,14 @@ public interface TStore<T> extends ReadOnlyTStore<T> {
    *          the operation
    */
   void push(long tid, Repo<T> repo) throws StackOverflowException;
-  
+
   /**
    * Remove the last pushed operation from the given transaction.
    * 
    * @param tid
    */
   void pop(long tid);
-  
+
   /**
    * Update the state of a given transaction
    * 
@@ -72,9 +70,9 @@ public interface TStore<T> extends ReadOnlyTStore<T> {
    *          execution status
    */
   void setStatus(long tid, TStatus status);
-  
+
   void setProperty(long tid, String prop, Serializable val);
-  
+
   /**
    * Remove the transaction from the store.
    * 

http://git-wip-us.apache.org/repos/asf/accumulo/blob/5363d781/server/src/main/java/org/apache/accumulo/server/fate/Admin.java
----------------------------------------------------------------------
diff --git a/server/src/main/java/org/apache/accumulo/server/fate/Admin.java b/server/src/main/java/org/apache/accumulo/server/fate/Admin.java
index fc9e342..16bfd0c 100644
--- a/server/src/main/java/org/apache/accumulo/server/fate/Admin.java
+++ b/server/src/main/java/org/apache/accumulo/server/fate/Admin.java
@@ -24,8 +24,8 @@ import org.apache.accumulo.core.cli.Help;
 import org.apache.accumulo.core.client.Instance;
 import org.apache.accumulo.core.zookeeper.ZooUtil;
 import org.apache.accumulo.fate.AdminUtil;
-import org.apache.accumulo.fate.ZooStore;
 import org.apache.accumulo.fate.ReadOnlyStore;
+import org.apache.accumulo.fate.ZooStore;
 import org.apache.accumulo.fate.zookeeper.IZooReaderWriter;
 import org.apache.accumulo.server.client.HdfsZooInstance;
 import org.apache.accumulo.server.master.Master;
@@ -35,29 +35,25 @@ import com.beust.jcommander.JCommander;
 import com.beust.jcommander.Parameter;
 import com.beust.jcommander.Parameters;
 
-
 /**
  * A utility to administer FATE operations
  */
 public class Admin {
-  
+
   static class TxOpts {
-    @Parameter(description="<txid>", required=true)
+    @Parameter(description = "<txid>", required = true)
     List<String> args = new ArrayList<String>();
   }
-  
-  @Parameters(commandDescription="Stop an existing FATE by transaction id")
-  static class FailOpts extends TxOpts {
-  }
-  
-  @Parameters(commandDescription="Delete an existing FATE by transaction id")
-  static class DeleteOpts extends TxOpts {
-  }
-  
-  @Parameters(commandDescription="List the existing FATE transactions")
-  static class PrintOpts {
-  }
-  
+
+  @Parameters(commandDescription = "Stop an existing FATE by transaction id")
+  static class FailOpts extends TxOpts {}
+
+  @Parameters(commandDescription = "Delete an existing FATE by transaction id")
+  static class DeleteOpts extends TxOpts {}
+
+  @Parameters(commandDescription = "List the existing FATE transactions")
+  static class PrintOpts {}
+
   public static void main(String[] args) throws Exception {
     Help opts = new Help();
     JCommander jc = new JCommander(opts);
@@ -70,15 +66,15 @@ public class Admin {
       jc.usage();
       System.exit(-1);
     }
-    
+
     AdminUtil<Master> admin = new AdminUtil<Master>();
-    
+
     Instance instance = HdfsZooInstance.getInstance();
     String path = ZooUtil.getRoot(instance) + Constants.ZFATE;
     String masterPath = ZooUtil.getRoot(instance) + Constants.ZMASTER_LOCK;
     IZooReaderWriter zk = ZooReaderWriter.getRetryingInstance();
     ZooStore<Master> zs = new ZooStore<Master>(path, zk);
-    
+
     if (jc.getParsedCommand().equals("fail")) {
       if (!admin.prepFail(zs, zk, masterPath, args[1])) {
         System.exit(1);
@@ -89,7 +85,7 @@ public class Admin {
       }
       admin.deleteLocks(zs, zk, ZooUtil.getRoot(instance) + Constants.ZTABLE_LOCKS, args[1]);
     } else if (jc.getParsedCommand().equals("print")) {
-      admin.print(new ReadOnlyStore(zs), zk, ZooUtil.getRoot(instance) + Constants.ZTABLE_LOCKS);
+      admin.print(new ReadOnlyStore<Master>(zs), zk, ZooUtil.getRoot(instance) + Constants.ZTABLE_LOCKS);
     }
   }
 }

http://git-wip-us.apache.org/repos/asf/accumulo/blob/5363d781/test/src/main/java/org/apache/accumulo/test/continuous/ContinuousVerify.java
----------------------------------------------------------------------
diff --git a/test/src/main/java/org/apache/accumulo/test/continuous/ContinuousVerify.java b/test/src/main/java/org/apache/accumulo/test/continuous/ContinuousVerify.java
index 8095b50..06b9a7c 100644
--- a/test/src/main/java/org/apache/accumulo/test/continuous/ContinuousVerify.java
+++ b/test/src/main/java/org/apache/accumulo/test/continuous/ContinuousVerify.java
@@ -38,7 +38,6 @@ import org.apache.hadoop.fs.Path;
 import org.apache.hadoop.io.LongWritable;
 import org.apache.hadoop.io.Text;
 import org.apache.hadoop.io.VLongWritable;
-import org.apache.hadoop.mapred.Counters.Counter;
 import org.apache.hadoop.mapreduce.Job;
 import org.apache.hadoop.mapreduce.Mapper;
 import org.apache.hadoop.mapreduce.Reducer;


[21/53] [abbrv] Revert "ACCUMULO-1897 Move shell into new package and module"

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/TableOperation.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/TableOperation.java b/shell/src/main/java/org/apache/accumulo/shell/commands/TableOperation.java
deleted file mode 100644
index 032579b..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/TableOperation.java
+++ /dev/null
@@ -1,153 +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.accumulo.shell.commands;
-
-import java.util.Map;
-import java.util.Set;
-import java.util.SortedSet;
-import java.util.TreeSet;
-
-import org.apache.accumulo.core.client.Instance;
-import org.apache.accumulo.core.client.TableNotFoundException;
-import org.apache.accumulo.core.client.impl.Namespaces;
-import org.apache.accumulo.core.client.impl.Tables;
-import org.apache.accumulo.shell.Shell;
-import org.apache.accumulo.shell.Token;
-import org.apache.accumulo.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.OptionGroup;
-import org.apache.commons.cli.Options;
-
-public abstract class TableOperation extends Command {
-
-  protected Option optTablePattern, optTableName, optNamespace;
-  private boolean force = true;
-  private boolean useCommandLine = true;
-
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    // populate the tableSet set with the tables you want to operate on
-    final SortedSet<String> tableSet = new TreeSet<String>();
-    if (cl.hasOption(optTablePattern.getOpt())) {
-      for (String table : shellState.getConnector().tableOperations().list())
-        if (table.matches(cl.getOptionValue(optTablePattern.getOpt()))) {
-          tableSet.add(table);
-        }
-    } else if (cl.hasOption(optTableName.getOpt())) {
-      tableSet.add(cl.getOptionValue(optTableName.getOpt()));
-    } else if (cl.hasOption(optNamespace.getOpt())) {
-      Instance instance = shellState.getInstance();
-      String namespaceId = Namespaces.getNamespaceId(instance, cl.getOptionValue(optNamespace.getOpt()));
-      for (String tableId : Namespaces.getTableIds(instance, namespaceId)) {
-        tableSet.add(Tables.getTableName(instance, tableId));
-      }
-    } else if (useCommandLine && cl.getArgs().length > 0) {
-      for (String tableName : cl.getArgs()) {
-        tableSet.add(tableName);
-      }
-    } else {
-      shellState.checkTableState();
-      tableSet.add(shellState.getTableName());
-    }
-
-    if (tableSet.isEmpty())
-      Shell.log.warn("No tables found that match your criteria");
-
-    boolean more = true;
-    // flush the tables
-    for (String tableName : tableSet) {
-      if (!more) {
-        break;
-      }
-      if (!shellState.getConnector().tableOperations().exists(tableName)) {
-        throw new TableNotFoundException(null, tableName, null);
-      }
-      boolean operate = true;
-      if (!force) {
-        shellState.getReader().flush();
-        String line = shellState.getReader().readLine(getName() + " { " + tableName + " } (yes|no)? ");
-        more = line != null;
-        operate = line != null && (line.equalsIgnoreCase("y") || line.equalsIgnoreCase("yes"));
-      }
-      if (operate) {
-        doTableOp(shellState, tableName);
-      }
-    }
-
-    return 0;
-  }
-
-  protected abstract void doTableOp(Shell shellState, String tableName) throws Exception;
-
-  @Override
-  public String description() {
-    return "makes a best effort to flush tables from memory to disk";
-  }
-
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-
-    optTablePattern = new Option("p", "pattern", true, "regex pattern of table names to operate on");
-    optTablePattern.setArgName("pattern");
-
-    optTableName = new Option(Shell.tableOption, "table", true, "name of a table to operate on");
-    optTableName.setArgName("tableName");
-
-    optNamespace = new Option(Shell.namespaceOption, "namespace", true, "name of a namespace to operate on");
-    optNamespace.setArgName("namespace");
-
-    final OptionGroup opg = new OptionGroup();
-
-    opg.addOption(optTablePattern);
-    opg.addOption(optTableName);
-    opg.addOption(optNamespace);
-
-    o.addOptionGroup(opg);
-
-    return o;
-  }
-
-  @Override
-  public int numArgs() {
-    return useCommandLine ? Shell.NO_FIXED_ARG_LENGTH_CHECK : 0;
-  }
-
-  protected void force() {
-    force = true;
-  }
-
-  protected void noForce() {
-    force = false;
-  }
-
-  protected void disableUnflaggedTableOptions() {
-    useCommandLine = false;
-  }
-
-  @Override
-  public String usage() {
-    return getName() + " [<table>{ <table>}]";
-  }
-
-  @Override
-  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> special) {
-    if (useCommandLine)
-      registerCompletionForTables(root, special);
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/TablePermissionsCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/TablePermissionsCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/TablePermissionsCommand.java
deleted file mode 100644
index 75e3fbd..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/TablePermissionsCommand.java
+++ /dev/null
@@ -1,44 +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.accumulo.shell.commands;
-
-import java.io.IOException;
-
-import org.apache.accumulo.core.security.TablePermission;
-import org.apache.accumulo.shell.Shell;
-import org.apache.accumulo.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-
-public class TablePermissionsCommand extends Command {
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws IOException {
-    for (String p : TablePermission.printableValues()) {
-      shellState.getReader().println(p);
-    }
-    return 0;
-  }
-  
-  @Override
-  public String description() {
-    return "displays a list of valid table permissions";
-  }
-  
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/TablesCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/TablesCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/TablesCommand.java
deleted file mode 100644
index 5bded8d..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/TablesCommand.java
+++ /dev/null
@@ -1,107 +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.accumulo.shell.commands;
-
-import java.io.IOException;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.TreeMap;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.NamespaceNotFoundException;
-import org.apache.accumulo.core.client.impl.Tables;
-import org.apache.accumulo.shell.Shell;
-import org.apache.accumulo.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-import org.apache.commons.collections.MapUtils;
-
-import com.google.common.base.Function;
-import com.google.common.base.Predicate;
-import com.google.common.collect.Iterators;
-import com.google.common.collect.Maps;
-
-public class TablesCommand extends Command {
-  static final String NAME_AND_ID_FORMAT = "%-20s => %9s%n";
-
-  private Option tableIdOption;
-  private Option sortByTableIdOption;
-  private Option disablePaginationOpt;
-
-  @SuppressWarnings("unchecked")
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException, IOException,
-      NamespaceNotFoundException {
-
-    final String namespace = cl.hasOption(OptUtil.namespaceOpt().getOpt()) ? OptUtil.getNamespaceOpt(cl, shellState) : null;
-    Map<String,String> tables = shellState.getConnector().tableOperations().tableIdMap();
-
-    // filter only specified namespace
-    tables = Maps.filterKeys(tables, new Predicate<String>() {
-      @Override
-      public boolean apply(String tableName) {
-        return namespace == null || Tables.qualify(tableName).getFirst().equals(namespace);
-      }
-    });
-
-    final boolean sortByTableId = cl.hasOption(sortByTableIdOption.getOpt());
-    tables = new TreeMap<String,String>((sortByTableId ? MapUtils.invertMap(tables) : tables));
-
-    Iterator<String> it = Iterators.transform(tables.entrySet().iterator(), new Function<Entry<String,String>,String>() {
-      @Override
-      public String apply(Map.Entry<String,String> entry) {
-        String tableName = String.valueOf(sortByTableId ? entry.getValue() : entry.getKey());
-        String tableId = String.valueOf(sortByTableId ? entry.getKey() : entry.getValue());
-        if (namespace != null)
-          tableName = Tables.qualify(tableName).getSecond();
-        if (cl.hasOption(tableIdOption.getOpt()))
-          return String.format(NAME_AND_ID_FORMAT, tableName, tableId);
-        else
-          return tableName;
-      };
-    });
-
-    shellState.printLines(it, !cl.hasOption(disablePaginationOpt.getOpt()));
-    return 0;
-  }
-
-  @Override
-  public String description() {
-    return "displays a list of all existing tables";
-  }
-
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-    tableIdOption = new Option("l", "list-ids", false, "display internal table ids along with the table name");
-    o.addOption(tableIdOption);
-    sortByTableIdOption = new Option("s", "sort-ids", false, "with -l: sort output by table ids");
-    o.addOption(sortByTableIdOption);
-    disablePaginationOpt = new Option("np", "no-pagination", false, "disable pagination of output");
-    o.addOption(disablePaginationOpt);
-    o.addOption(OptUtil.namespaceOpt("name of namespace to list only its tables"));
-    return o;
-  }
-
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/TraceCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/TraceCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/TraceCommand.java
deleted file mode 100644
index 7f63570..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/TraceCommand.java
+++ /dev/null
@@ -1,101 +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.accumulo.shell.commands;
-
-import java.io.IOException;
-import java.util.Map;
-
-import org.apache.accumulo.shell.Shell;
-import org.apache.accumulo.trace.instrument.Trace;
-import org.apache.accumulo.core.client.Scanner;
-import org.apache.accumulo.core.conf.Property;
-import org.apache.accumulo.core.data.Range;
-import org.apache.accumulo.core.security.Authorizations;
-import org.apache.accumulo.core.trace.TraceDump;
-import org.apache.accumulo.core.trace.TraceDump.Printer;
-import org.apache.accumulo.core.util.BadArgumentException;
-import org.apache.accumulo.core.util.UtilWaitThread;
-import org.apache.commons.cli.CommandLine;
-import org.apache.hadoop.io.Text;
-
-public class TraceCommand extends DebugCommand {
-  
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws IOException {
-    if (cl.getArgs().length == 1) {
-      if (cl.getArgs()[0].equalsIgnoreCase("on")) {
-        Trace.on("shell:" + shellState.getPrincipal());
-      } else if (cl.getArgs()[0].equalsIgnoreCase("off")) {
-        if (Trace.isTracing()) {
-          final long trace = Trace.currentTrace().traceId();
-          Trace.off();
-          StringBuffer sb = new StringBuffer();
-          int traceCount = 0;
-          for (int i = 0; i < 30; i++) {
-            sb = new StringBuffer();
-            try {
-              final Map<String,String> properties = shellState.getConnector().instanceOperations().getSystemConfiguration();
-              final String table = properties.get(Property.TRACE_TABLE.getKey());
-              final String user = shellState.getConnector().whoami();
-              final Authorizations auths = shellState.getConnector().securityOperations().getUserAuthorizations(user);
-              final Scanner scanner = shellState.getConnector().createScanner(table, auths);
-              scanner.setRange(new Range(new Text(Long.toHexString(trace))));
-              final StringBuffer finalSB = sb;
-              traceCount = TraceDump.printTrace(scanner, new Printer() {
-                @Override
-                public void print(final String line) {
-                  try {
-                    finalSB.append(line + "\n");
-                  } catch (Exception ex) {
-                    throw new RuntimeException(ex);
-                  }
-                }
-              });
-              if (traceCount > 0) {
-                shellState.getReader().print(sb.toString());
-                break;
-              }
-            } catch (Exception ex) {
-              shellState.printException(ex);
-            }
-            shellState.getReader().println("Waiting for trace information");
-            shellState.getReader().flush();
-            UtilWaitThread.sleep(500);
-          }
-          if (traceCount < 0) {
-            // display the trace even though there are unrooted spans
-            shellState.getReader().print(sb.toString());
-          }
-        } else {
-          shellState.getReader().println("Not tracing");
-        }
-      } else
-        throw new BadArgumentException("Argument must be 'on' or 'off'", fullCommand, fullCommand.indexOf(cl.getArgs()[0]));
-    } else if (cl.getArgs().length == 0) {
-      shellState.getReader().println(Trace.isTracing() ? "on" : "off");
-    } else {
-      shellState.printException(new IllegalArgumentException("Expected 0 or 1 argument. There were " + cl.getArgs().length + "."));
-      printHelp(shellState);
-      return 1;
-    }
-    return 0;
-  }
-  
-  @Override
-  public String description() {
-    return "turns trace logging on or off";
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/UserCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/UserCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/UserCommand.java
deleted file mode 100644
index 491f144..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/UserCommand.java
+++ /dev/null
@@ -1,71 +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.accumulo.shell.commands;
-
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.security.tokens.PasswordToken;
-import org.apache.accumulo.shell.Shell;
-import org.apache.accumulo.shell.Token;
-import org.apache.accumulo.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-
-public class UserCommand extends Command {
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException, IOException {
-    // save old credentials and connection in case of failure
-    String user = cl.getArgs()[0];
-    byte[] pass;
-    
-    // We can't let the wrapping try around the execute method deal
-    // with the exceptions because we have to do something if one
-    // of these methods fails
-    final String p = shellState.readMaskedLine("Enter password for user " + user + ": ", '*');
-    if (p == null) {
-      shellState.getReader().println();
-      return 0;
-    } // user canceled
-    pass = p.getBytes(StandardCharsets.UTF_8);
-    shellState.updateUser(user, new PasswordToken(pass));
-    return 0;
-  }
-  
-  @Override
-  public String description() {
-    return "switches to the specified user";
-  }
-  
-  @Override
-  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> special) {
-    registerCompletionForUsers(root, special);
-  }
-  
-  @Override
-  public String usage() {
-    return getName() + " <username>";
-  }
-  
-  @Override
-  public int numArgs() {
-    return 1;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/UserPermissionsCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/UserPermissionsCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/UserPermissionsCommand.java
deleted file mode 100644
index ad6a20d..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/UserPermissionsCommand.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.accumulo.shell.commands;
-
-import java.io.IOException;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.security.NamespacePermission;
-import org.apache.accumulo.core.security.SystemPermission;
-import org.apache.accumulo.core.security.TablePermission;
-import org.apache.accumulo.shell.Shell;
-import org.apache.accumulo.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-
-public class UserPermissionsCommand extends Command {
-  private Option userOpt;
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException, IOException {
-    final String user = cl.getOptionValue(userOpt.getOpt(), shellState.getConnector().whoami());
-
-    String delim = "";
-    shellState.getReader().print("System permissions: ");
-    for (SystemPermission p : SystemPermission.values()) {
-      if (p != null && shellState.getConnector().securityOperations().hasSystemPermission(user, p)) {
-        shellState.getReader().print(delim + "System." + p.name());
-        delim = ", ";
-      }
-    }
-    shellState.getReader().println();
-
-    boolean runOnce = true;
-    for (String n : shellState.getConnector().namespaceOperations().list()) {
-      delim = "";
-      for (NamespacePermission p : NamespacePermission.values()) {
-        if (p != null && shellState.getConnector().securityOperations().hasNamespacePermission(user, n, p)) {
-          if (runOnce) {
-            shellState.getReader().print("\nNamespace permissions (" + n + "): ");
-            runOnce = false;
-          }
-          shellState.getReader().print(delim + "Namespace." + p.name());
-          delim = ", ";
-        }
-      }
-      runOnce = true;
-    }
-    shellState.getReader().println();
-
-    
-    runOnce = true;
-    for (String t : shellState.getConnector().tableOperations().list()) {
-      delim = "";
-      for (TablePermission p : TablePermission.values()) {
-        if (shellState.getConnector().securityOperations().hasTablePermission(user, t, p) && p != null) {
-          if (runOnce) {
-            shellState.getReader().print("\nTable permissions (" + t + "): ");
-            runOnce = false;
-          }
-          shellState.getReader().print(delim + "Table." + p.name());
-          delim = ", ";
-        }
-
-      }
-      runOnce = true;
-    }
-    shellState.getReader().println();
-
-    return 0;
-  }
-
-  @Override
-  public String description() {
-    return "displays a user's system, table, and namespace permissions";
-  }
-
-  @Override
-  public Options getOptions() {
-    Options o = new Options();
-    userOpt = new Option(Shell.userOption, "user", true, "user to operate on");
-    userOpt.setArgName("user");
-    o.addOption(userOpt);
-    return o;
-  }
-
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/UsersCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/UsersCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/UsersCommand.java
deleted file mode 100644
index 5ea61bf..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/UsersCommand.java
+++ /dev/null
@@ -1,45 +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.accumulo.shell.commands;
-
-import java.io.IOException;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.shell.Shell;
-import org.apache.accumulo.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-
-public class UsersCommand extends Command {
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException, IOException {
-    for (String user : shellState.getConnector().securityOperations().listLocalUsers()) {
-      shellState.getReader().println(user);
-    }
-    return 0;
-  }
-  
-  @Override
-  public String description() {
-    return "displays a list of existing users";
-  }
-  
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/WhoAmICommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/WhoAmICommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/WhoAmICommand.java
deleted file mode 100644
index f80a621..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/WhoAmICommand.java
+++ /dev/null
@@ -1,41 +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.accumulo.shell.commands;
-
-import java.io.IOException;
-
-import org.apache.accumulo.shell.Shell;
-import org.apache.accumulo.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-
-public class WhoAmICommand extends Command {
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws IOException {
-    shellState.getReader().println(shellState.getConnector().whoami());
-    return 0;
-  }
-  
-  @Override
-  public String description() {
-    return "reports the current user name";
-  }
-  
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/format/DeleterFormatter.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/format/DeleterFormatter.java b/shell/src/main/java/org/apache/accumulo/shell/format/DeleterFormatter.java
deleted file mode 100644
index b90b55e..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/format/DeleterFormatter.java
+++ /dev/null
@@ -1,102 +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.accumulo.shell.format;
-
-import java.io.IOException;
-import java.util.Map.Entry;
-
-import org.apache.accumulo.core.client.BatchWriter;
-import org.apache.accumulo.core.client.MutationsRejectedException;
-import org.apache.accumulo.core.data.ConstraintViolationSummary;
-import org.apache.accumulo.core.data.Key;
-import org.apache.accumulo.core.data.Mutation;
-import org.apache.accumulo.core.data.Value;
-import org.apache.accumulo.core.security.ColumnVisibility;
-import org.apache.accumulo.core.util.format.DefaultFormatter;
-import org.apache.accumulo.shell.Shell;
-import org.apache.log4j.Logger;
-
-public class DeleterFormatter extends DefaultFormatter {
-  
-  private static final Logger log = Logger.getLogger(DeleterFormatter.class);
-  private BatchWriter writer;
-  private Shell shellState;
-  private boolean printTimestamps;
-  private boolean force;
-  private boolean more;
-  
-  public DeleterFormatter(BatchWriter writer, Iterable<Entry<Key,Value>> scanner, boolean printTimestamps, Shell shellState, boolean force) {
-    super.initialize(scanner, printTimestamps);
-    this.writer = writer;
-    this.shellState = shellState;
-    this.printTimestamps = printTimestamps;
-    this.force = force;
-    this.more = true;
-  }
-  
-  @Override
-  public boolean hasNext() {
-    if (!getScannerIterator().hasNext() || !more) {
-      try {
-        writer.close();
-      } catch (MutationsRejectedException e) {
-        log.error(e.toString());
-        if (Shell.isDebuggingEnabled())
-          for (ConstraintViolationSummary cvs : e.getConstraintViolationSummaries())
-            log.trace(cvs.toString());
-      }
-      return false;
-    }
-    return true;
-  }
-  
-  /**
-   * @return null, because the iteration will provide prompts and handle deletes internally.
-   */
-  @Override
-  public String next() {
-    Entry<Key,Value> next = getScannerIterator().next();
-    Key key = next.getKey();
-    Mutation m = new Mutation(key.getRow());
-    String entryStr = formatEntry(next, printTimestamps);
-    boolean delete = force;
-    try {
-      if (!force) {
-        shellState.getReader().flush();
-        String line = shellState.getReader().readLine("Delete { " + entryStr + " } ? ");
-        more = line != null;
-        delete = line != null && (line.equalsIgnoreCase("y") || line.equalsIgnoreCase("yes"));
-      }
-      if (delete) {
-        m.putDelete(key.getColumnFamily(), key.getColumnQualifier(), new ColumnVisibility(key.getColumnVisibility()), key.getTimestamp());
-        try {
-          writer.addMutation(m);
-        } catch (MutationsRejectedException e) {
-          log.error(e.toString());
-          if (Shell.isDebuggingEnabled())
-            for (ConstraintViolationSummary cvs : e.getConstraintViolationSummaries())
-              log.trace(cvs.toString());
-        }
-      }
-      shellState.getReader().print(String.format("[%s] %s%n", delete ? "DELETED" : "SKIPPED", entryStr));
-    } catch (IOException e) {
-      log.error("Cannot write to console", e);
-      throw new RuntimeException(e);
-    }
-    return null;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/mock/MockShell.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/mock/MockShell.java b/shell/src/main/java/org/apache/accumulo/shell/mock/MockShell.java
deleted file mode 100644
index 151648a..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/mock/MockShell.java
+++ /dev/null
@@ -1,143 +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.accumulo.shell.mock;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.nio.charset.StandardCharsets;
-
-import jline.console.ConsoleReader;
-
-import org.apache.accumulo.core.client.mock.MockInstance;
-import org.apache.accumulo.shell.Shell;
-import org.apache.accumulo.shell.ShellOptionsJC;
-
-/**
- * An Accumulo Shell implementation that allows a developer to attach an InputStream and Writer to the Shell for testing purposes.
- */
-public class MockShell extends Shell {
-  private static final String NEWLINE = "\n";
-  
-  protected InputStream in;
-  protected OutputStream out;
-  
-  public MockShell(InputStream in, OutputStream out) throws IOException {
-    super();
-    this.in = in;
-    this.out = out;
-  }
-  
-  public boolean config(String... args) {
-    configError = super.config(args);
-    
-    // Update the ConsoleReader with the input and output "redirected"
-    try {
-      this.reader = new ConsoleReader(in, out);
-    } catch (Exception e) {
-      printException(e);
-      configError = true;
-    }
-    
-    // Don't need this for testing purposes
-    this.reader.setHistoryEnabled(false);
-    this.reader.setPaginationEnabled(false);
-    
-    // Make the parsing from the client easier;
-    this.verbose = false;
-    return configError;
-  }
-  
-  @Override
-  protected void setInstance(ShellOptionsJC options) {
-    // We always want a MockInstance for this test
-    instance = new MockInstance();
-  }
-  
-  public int start() throws IOException {
-    if (configError)
-      return 1;
-    
-    String input;
-    if (isVerbose())
-      printInfo();
-    
-    if (execFile != null) {
-      java.util.Scanner scanner = new java.util.Scanner(execFile, StandardCharsets.UTF_8.name());
-      try {
-        while (scanner.hasNextLine() && !hasExited()) {
-          execCommand(scanner.nextLine(), true, isVerbose());
-        }
-      } finally {
-        scanner.close();
-      }
-    } else if (execCommand != null) {
-      for (String command : execCommand.split("\n")) {
-        execCommand(command, true, isVerbose());
-      }
-      return exitCode;
-    }
-    
-    while (true) {
-      if (hasExited())
-        return exitCode;
-      
-      reader.setPrompt(getDefaultPrompt());
-      input = reader.readLine();
-      if (input == null) {
-        reader.println();
-        return exitCode;
-      } // user canceled
-      
-      execCommand(input, false, false);
-    }
-  }
-  
-  /**
-   * @param in
-   *          the in to set
-   */
-  public void setConsoleInputStream(InputStream in) {
-    this.in = in;
-  }
-  
-  /**
-   * @param out
-   *          the output stream to set
-   */
-  public void setConsoleWriter(OutputStream out) {
-    this.out = out;
-  }
-  
-  /**
-   * Convenience method to create the byte-array to hand to the console
-   * 
-   * @param commands
-   *          An array of commands to run
-   * @return A byte[] input stream which can be handed to the console.
-   */
-  public static ByteArrayInputStream makeCommands(String... commands) {
-    StringBuilder sb = new StringBuilder(commands.length * 8);
-    
-    for (String command : commands) {
-      sb.append(command).append(NEWLINE);
-    }
-    
-    return new ByteArrayInputStream(sb.toString().getBytes(StandardCharsets.UTF_8));
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/resources/.gitignore
----------------------------------------------------------------------
diff --git a/shell/src/main/resources/.gitignore b/shell/src/main/resources/.gitignore
deleted file mode 100644
index e69de29..0000000

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/test/java/org/apache/accumulo/shell/PasswordConverterTest.java
----------------------------------------------------------------------
diff --git a/shell/src/test/java/org/apache/accumulo/shell/PasswordConverterTest.java b/shell/src/test/java/org/apache/accumulo/shell/PasswordConverterTest.java
deleted file mode 100644
index 8e03830..0000000
--- a/shell/src/test/java/org/apache/accumulo/shell/PasswordConverterTest.java
+++ /dev/null
@@ -1,113 +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.accumulo.shell;
-
-import static org.junit.Assert.assertEquals;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStreamWriter;
-import java.io.PipedInputStream;
-import java.io.PipedOutputStream;
-import java.util.Scanner;
-
-import org.apache.accumulo.shell.ShellOptionsJC.PasswordConverter;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-
-import com.beust.jcommander.JCommander;
-import com.beust.jcommander.Parameter;
-import com.beust.jcommander.ParameterException;
-
-public class PasswordConverterTest {
-  
-  private class Password {
-    @Parameter(names = "--password", converter = PasswordConverter.class)
-    String password;
-  }
-  
-  private String[] argv;
-  private Password password;
-  private static InputStream realIn;
-  
-  @BeforeClass
-  public static void saveIn() {
-    realIn = System.in;
-  }
-  
-  @Before
-  public void setup() throws IOException {
-    argv = new String[] {"--password", ""};
-    password = new Password();
-    
-    PipedInputStream in = new PipedInputStream();
-    PipedOutputStream out = new PipedOutputStream(in);
-    OutputStreamWriter osw = new OutputStreamWriter(out);
-    osw.write("secret");
-    osw.close();
-    
-    System.setIn(in);
-  }
-  
-  @After
-  public void teardown() {
-    System.setIn(realIn);
-  }
-  
-  @Test
-  public void testPass() {
-    String expected = String.valueOf(Math.random());
-    argv[1] = "pass:" + expected;
-    new JCommander(password, argv);
-    assertEquals(expected, password.password);
-  }
-  
-  @Test
-  public void testEnv() {
-    String name = System.getenv().keySet().iterator().next();
-    argv[1] = "env:" + name;
-    new JCommander(password, argv);
-    assertEquals(System.getenv(name), password.password);
-  }
-  
-  @Test
-  public void testFile() throws FileNotFoundException {
-    argv[1] = "file:pom.xml";
-    Scanner scan = new Scanner(new File("pom.xml"));
-    String expected = scan.nextLine();
-    scan.close();
-    new JCommander(password, argv);
-    assertEquals(expected, password.password);
-  }
-  
-  @Test(expected=ParameterException.class)
-  public void testNoFile() throws FileNotFoundException {
-    argv[1] = "file:doesnotexist";
-    new JCommander(password, argv);
-  }
-
-  @Test
-  public void testStdin() {
-    argv[1] = "stdin";
-    new JCommander(password, argv);
-    assertEquals("stdin", password.password);
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/test/java/org/apache/accumulo/shell/ShellConfigTest.java
----------------------------------------------------------------------
diff --git a/shell/src/test/java/org/apache/accumulo/shell/ShellConfigTest.java b/shell/src/test/java/org/apache/accumulo/shell/ShellConfigTest.java
deleted file mode 100644
index 27f3247..0000000
--- a/shell/src/test/java/org/apache/accumulo/shell/ShellConfigTest.java
+++ /dev/null
@@ -1,91 +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.accumulo.shell;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import java.io.FileDescriptor;
-import java.io.FileInputStream;
-import java.io.PrintStream;
-import java.io.PrintWriter;
-
-import jline.console.ConsoleReader;
-
-import org.apache.accumulo.core.client.security.tokens.PasswordToken;
-import org.apache.accumulo.shell.Shell;
-import org.apache.accumulo.shell.ShellTest.TestOutputStream;
-import org.apache.log4j.Level;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-import com.beust.jcommander.ParameterException;
-
-public class ShellConfigTest {
-  TestOutputStream output;
-  Shell shell;
-  PrintStream out;
-  
-  @Before
-  public void setUp() throws Exception {
-    Shell.log.setLevel(Level.ERROR);
-    
-    out = System.out;
-    output = new TestOutputStream();
-    System.setOut(new PrintStream(output));
-
-    shell = new Shell(new ConsoleReader(new FileInputStream(FileDescriptor.in), output), new PrintWriter(output));
-    shell.setLogErrorsToConsole();
-  }
-  
-  @After
-  public void teardown() throws Exception {
-    shell.shutdown();
-    output.clear();
-    System.setOut(out);
-  }
-  
-  @Test
-  public void testHelp() {
-    assertTrue(shell.config("--help"));
-    assertTrue("Did not print usage", output.get().startsWith("Usage"));
-  }
-  
-  @Test
-  public void testBadArg() {
-    assertTrue(shell.config("--bogus"));
-    assertTrue("Did not print usage", output.get().startsWith("Usage"));
-  }
-  
-  @Test
-  public void testToken() {
-    assertTrue(shell.config("--fake", "-tc", PasswordToken.class.getCanonicalName()));
-    assertTrue(output.get().contains(ParameterException.class.getCanonicalName()));
-  }
-  
-  @Test
-  public void testTokenAndOption() {
-    assertFalse(shell.config("--fake", "-tc", PasswordToken.class.getCanonicalName(), "-u", "foo", "-l", "password=foo"));
-  }
-  
-  @Test
-  public void testTokenAndOptionAndPassword() {
-    assertTrue(shell.config("--fake", "-tc", PasswordToken.class.getCanonicalName(), "-l", "password=foo", "-p", "bar"));
-    assertTrue(output.get().contains(ParameterException.class.getCanonicalName()));
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/test/java/org/apache/accumulo/shell/ShellSetInstanceTest.java
----------------------------------------------------------------------
diff --git a/shell/src/test/java/org/apache/accumulo/shell/ShellSetInstanceTest.java b/shell/src/test/java/org/apache/accumulo/shell/ShellSetInstanceTest.java
deleted file mode 100644
index 463f97d..0000000
--- a/shell/src/test/java/org/apache/accumulo/shell/ShellSetInstanceTest.java
+++ /dev/null
@@ -1,244 +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.accumulo.shell;
-
-import static org.easymock.EasyMock.anyObject;
-import static org.easymock.EasyMock.expect;
-import static org.powermock.api.easymock.PowerMock.createMock;
-import static org.powermock.api.easymock.PowerMock.expectLastCall;
-import static org.powermock.api.easymock.PowerMock.expectNew;
-import static org.powermock.api.easymock.PowerMock.mockStatic;
-import static org.powermock.api.easymock.PowerMock.replay;
-import static org.powermock.api.easymock.PowerMock.verify;
-
-import java.io.FileDescriptor;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.PrintWriter;
-import java.util.Collections;
-import java.util.List;
-import java.util.UUID;
-
-import jline.console.ConsoleReader;
-
-import org.apache.accumulo.core.client.ClientConfiguration;
-import org.apache.accumulo.core.client.ClientConfiguration.ClientProperty;
-import org.apache.accumulo.core.client.ZooKeeperInstance;
-import org.apache.accumulo.core.client.mock.MockInstance;
-import org.apache.accumulo.core.conf.AccumuloConfiguration;
-import org.apache.accumulo.core.conf.ConfigSanityCheck;
-import org.apache.accumulo.core.conf.Property;
-import org.apache.accumulo.core.conf.SiteConfiguration;
-import org.apache.accumulo.core.zookeeper.ZooUtil;
-import org.apache.accumulo.shell.Shell;
-import org.apache.accumulo.shell.ShellOptionsJC;
-import org.apache.hadoop.fs.Path;
-import org.apache.log4j.Level;
-import org.easymock.EasyMock;
-import org.junit.After;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
-
-@RunWith(PowerMockRunner.class)
-@PrepareForTest({Shell.class, ZooUtil.class, ConfigSanityCheck.class})
-public class ShellSetInstanceTest {
-  public static class TestOutputStream extends OutputStream {
-    StringBuilder sb = new StringBuilder();
-
-    @Override
-    public void write(int b) throws IOException {
-      sb.append((char) (0xff & b));
-    }
-
-    public String get() {
-      return sb.toString();
-    }
-
-    public void clear() {
-      sb.setLength(0);
-    }
-  }
-
-  @BeforeClass
-  public static void setupClass() {
-    // This is necessary because PowerMock messes with Hadoop's ability to
-    // determine the current user (see security.UserGroupInformation).
-    System.setProperty("HADOOP_USER_NAME", "test");
-  }
-  @AfterClass
-  public static void teardownClass() {
-    System.clearProperty("HADOOP_USER_NAME");
-  }
-
-  private TestOutputStream output;
-  private Shell shell;
-
-  @Before
-  public void setup() throws IOException {
-    Shell.log.setLevel(Level.OFF);
-    output = new TestOutputStream();
-    shell = new Shell(new ConsoleReader(new FileInputStream(FileDescriptor.in), output), new PrintWriter(output));
-    shell.setLogErrorsToConsole();
-  }
-  @After
-  public void tearDown() {
-    shell.shutdown();
-    SiteConfiguration.clearInstance();
-  }
-
-  @Test
-  public void testSetInstance_Fake() throws Exception {
-    ShellOptionsJC opts = createMock(ShellOptionsJC.class);
-    expect(opts.isFake()).andReturn(true);
-    replay(opts);
-    MockInstance theInstance = createMock(MockInstance.class);
-    expectNew(MockInstance.class, "fake").andReturn(theInstance);
-    replay(theInstance, MockInstance.class);
-
-    shell.setInstance(opts);
-    verify(theInstance, MockInstance.class);
-  }
-  @Test
-  public void testSetInstance_HdfsZooInstance_Explicit() throws Exception {
-    testSetInstance_HdfsZooInstance(true, false, false);
-  }
-  @Test
-  public void testSetInstance_HdfsZooInstance_InstanceGiven() throws Exception {
-    testSetInstance_HdfsZooInstance(false, true, false);
-  }
-  @Test
-  public void testSetInstance_HdfsZooInstance_HostsGiven() throws Exception {
-    testSetInstance_HdfsZooInstance(false, false, true);
-  }
-  @Test
-  public void testSetInstance_HdfsZooInstance_Implicit() throws Exception {
-    testSetInstance_HdfsZooInstance(false, false, false);
-  }
-  
-  @SuppressWarnings("deprecation")
-  private void testSetInstance_HdfsZooInstance(boolean explicitHdfs, boolean onlyInstance, boolean onlyHosts)
-    throws Exception {
-    ClientConfiguration clientConf = createMock(ClientConfiguration.class);
-    ShellOptionsJC opts = createMock(ShellOptionsJC.class);
-    expect(opts.isFake()).andReturn(false);
-    expect(opts.getClientConfiguration()).andReturn(clientConf);
-    expect(opts.isHdfsZooInstance()).andReturn(explicitHdfs);
-    if (!explicitHdfs) {
-      expect(opts.getZooKeeperInstance())
-        .andReturn(Collections.<String>emptyList());
-      if (onlyInstance) {
-        expect(opts.getZooKeeperInstanceName()).andReturn("instance");
-        expect(clientConf.withInstance("instance")).andReturn(clientConf);
-      } else {
-        expect(opts.getZooKeeperInstanceName()).andReturn(null);
-      }
-      if (onlyHosts) {
-        expect(opts.getZooKeeperHosts()).andReturn("host3,host4");
-        expect(clientConf.withZkHosts("host3,host4")).andReturn(clientConf);
-      } else {
-        expect(opts.getZooKeeperHosts()).andReturn(null);
-      }
-    }
-    replay(opts);
-
-    if (!onlyInstance) {
-      expect(clientConf.get(ClientProperty.INSTANCE_NAME)).andReturn(null);
-    }
-
-    mockStatic(ConfigSanityCheck.class);
-    ConfigSanityCheck.validate(EasyMock.<AccumuloConfiguration>anyObject());
-    expectLastCall().atLeastOnce();
-    replay(ConfigSanityCheck.class);
-
-    if (!onlyHosts) {
-      expect(clientConf.containsKey(Property.INSTANCE_ZK_HOST.getKey())).andReturn(true).atLeastOnce();
-      expect(clientConf.getString(Property.INSTANCE_ZK_HOST.getKey())).andReturn("host1,host2").atLeastOnce();
-      expect(clientConf.withZkHosts("host1,host2")).andReturn(clientConf);
-    }
-    if (!onlyInstance) {
-      expect(clientConf.containsKey(Property.INSTANCE_VOLUMES.getKey())).andReturn(false).atLeastOnce();
-      expect(clientConf.containsKey(Property.INSTANCE_DFS_DIR.getKey())).andReturn(true).atLeastOnce();
-      expect(clientConf.containsKey(Property.INSTANCE_DFS_URI.getKey())).andReturn(true).atLeastOnce();
-      expect(clientConf.getString(Property.INSTANCE_DFS_URI.getKey())).andReturn("hdfs://nn1").atLeastOnce();
-      expect(clientConf.getString(Property.INSTANCE_DFS_DIR.getKey())).andReturn("/dfs").atLeastOnce();
-    }
-
-    UUID randomUUID = null;
-    if (!onlyInstance) {
-      mockStatic(ZooUtil.class);
-      randomUUID = UUID.randomUUID();
-      expect(ZooUtil.getInstanceIDFromHdfs(anyObject(Path.class), anyObject(AccumuloConfiguration.class)))
-        .andReturn(randomUUID.toString());
-      replay(ZooUtil.class);
-      expect(clientConf.withInstance(randomUUID)).andReturn(clientConf);
-    }
-    replay(clientConf);
-
-    ZooKeeperInstance theInstance = createMock(ZooKeeperInstance.class);
-    
-    expectNew(ZooKeeperInstance.class, clientConf).andReturn(theInstance);
-    replay(theInstance, ZooKeeperInstance.class);
-
-    shell.setInstance(opts);
-    verify(theInstance, ZooKeeperInstance.class);
-  }
-  @Test
-  public void testSetInstance_ZKInstance_DashZ() throws Exception {
-    testSetInstance_ZKInstance(true);
-  }
-  @Test
-  public void testSetInstance_ZKInstance_DashZIandZH() throws Exception {
-    testSetInstance_ZKInstance(false);
-  }
-  private void testSetInstance_ZKInstance(boolean dashZ) throws Exception {
-    ClientConfiguration clientConf = createMock(ClientConfiguration.class);
-    ShellOptionsJC opts = createMock(ShellOptionsJC.class);
-    expect(opts.isFake()).andReturn(false);
-    expect(opts.getClientConfiguration()).andReturn(clientConf);
-    expect(opts.isHdfsZooInstance()).andReturn(false);
-    if (dashZ) {
-      expect(clientConf.withInstance("foo")).andReturn(clientConf);
-      expect(clientConf.withZkHosts("host1,host2")).andReturn(clientConf);
-      List<String> zl = new java.util.ArrayList<String>();
-      zl.add("foo");
-      zl.add("host1,host2");
-      expect(opts.getZooKeeperInstance()).andReturn(zl);
-      expectLastCall().anyTimes();
-    } else {
-      expect(clientConf.withInstance("bar")).andReturn(clientConf);
-      expect(clientConf.withZkHosts("host3,host4")).andReturn(clientConf);
-      expect(opts.getZooKeeperInstance()).andReturn(Collections.<String>emptyList());
-      expect(opts.getZooKeeperInstanceName()).andReturn("bar");
-      expect(opts.getZooKeeperHosts()).andReturn("host3,host4");
-    }
-    replay(clientConf);
-    replay(opts);
-
-    ZooKeeperInstance theInstance = createMock(ZooKeeperInstance.class);
-    expectNew(ZooKeeperInstance.class, clientConf).andReturn(theInstance);
-    replay(theInstance, ZooKeeperInstance.class);
-
-    shell.setInstance(opts);
-    verify(theInstance, ZooKeeperInstance.class);
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/test/java/org/apache/accumulo/shell/ShellTest.java
----------------------------------------------------------------------
diff --git a/shell/src/test/java/org/apache/accumulo/shell/ShellTest.java b/shell/src/test/java/org/apache/accumulo/shell/ShellTest.java
deleted file mode 100644
index ef12baa..0000000
--- a/shell/src/test/java/org/apache/accumulo/shell/ShellTest.java
+++ /dev/null
@@ -1,282 +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.accumulo.shell;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.io.PrintWriter;
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.TimeZone;
-
-import jline.console.ConsoleReader;
-
-import org.apache.accumulo.core.util.format.DateStringFormatter;
-import org.apache.accumulo.shell.Shell;
-import org.apache.log4j.Level;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-public class ShellTest {
-  public static class TestOutputStream extends OutputStream {
-    StringBuilder sb = new StringBuilder();
-
-    @Override
-    public void write(int b) throws IOException {
-      sb.append((char) (0xff & b));
-    }
-
-    public String get() {
-      return sb.toString();
-    }
-
-    public void clear() {
-      sb.setLength(0);
-    }
-  }
-
-  public static class StringInputStream extends InputStream {
-    private String source = "";
-    private int offset = 0;
-
-    @Override
-    public int read() throws IOException {
-      if (offset == source.length())
-        return '\n';
-      else
-        return source.charAt(offset++);
-    }
-
-    public void set(String other) {
-      source = other;
-      offset = 0;
-    }
-  }
-
-  private StringInputStream input;
-  private TestOutputStream output;
-  private Shell shell;
-
-  void exec(String cmd) throws IOException {
-    output.clear();
-    shell.execCommand(cmd, true, true);
-  }
-
-  void exec(String cmd, boolean expectGoodExit) throws IOException {
-    exec(cmd);
-    if (expectGoodExit)
-      assertGoodExit("", true);
-    else
-      assertBadExit("", true);
-  }
-
-  void exec(String cmd, boolean expectGoodExit, String expectString) throws IOException {
-    exec(cmd, expectGoodExit, expectString, true);
-  }
-
-  void exec(String cmd, boolean expectGoodExit, String expectString, boolean stringPresent) throws IOException {
-    exec(cmd);
-    if (expectGoodExit)
-      assertGoodExit(expectString, stringPresent);
-    else
-      assertBadExit(expectString, stringPresent);
-  }
-
-  @Before
-  public void setup() throws IOException {
-    TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
-    Shell.log.setLevel(Level.OFF);
-    output = new TestOutputStream();
-    input = new StringInputStream();
-    PrintWriter pw = new PrintWriter(new OutputStreamWriter(output));
-    shell = new Shell(new ConsoleReader(input, output), pw);
-    shell.setLogErrorsToConsole();
-    shell.config("--fake", "-u", "test", "-p", "secret");
-  }
-
-  @After
-  public void teardown() {
-    shell.shutdown();
-  }
-
-  void assertGoodExit(String s, boolean stringPresent) {
-    Shell.log.debug(output.get());
-    assertEquals(shell.getExitCode(), 0);
-    if (s.length() > 0)
-      assertEquals(s + " present in " + output.get() + " was not " + stringPresent, stringPresent, output.get().contains(s));
-  }
-
-  void assertBadExit(String s, boolean stringPresent) {
-    Shell.log.debug(output.get());
-    assertTrue(shell.getExitCode() > 0);
-    if (s.length() > 0)
-      assertEquals(s + " present in " + output.get() + " was not " + stringPresent, stringPresent, output.get().contains(s));
-    shell.resetExitCode();
-  }
-
-  @Test
-  public void aboutTest() throws IOException {
-    Shell.log.debug("Starting about test -----------------------------------");
-    exec("about", true, "Shell - Apache Accumulo Interactive Shell");
-    exec("about -v", true, "Current user:");
-    exec("about arg", false, "java.lang.IllegalArgumentException: Expected 0 arguments");
-  }
-
-  @Test
-  public void addGetSplitsTest() throws IOException {
-    Shell.log.debug("Starting addGetSplits test ----------------------------");
-    exec("addsplits arg", false, "java.lang.IllegalStateException: Not in a table context");
-    exec("createtable test", true);
-    exec("addsplits 1 \\x80", true);
-    exec("getsplits", true, "1\n\\x80");
-    exec("deletetable test -f", true, "Table: [test] has been deleted");
-  }
-
-  @Test
-  public void insertDeleteScanTest() throws IOException {
-    Shell.log.debug("Starting insertDeleteScan test ------------------------");
-    exec("insert r f q v", false, "java.lang.IllegalStateException: Not in a table context");
-    exec("delete r f q", false, "java.lang.IllegalStateException: Not in a table context");
-    exec("createtable test", true);
-    exec("insert r f q v", true);
-    exec("scan", true, "r f:q []    v");
-    exec("delete r f q", true);
-    exec("scan", true, "r f:q []    v", false);
-    exec("insert \\x90 \\xa0 \\xb0 \\xc0\\xd0\\xe0\\xf0", true);
-    exec("scan", true, "\\x90 \\xA0:\\xB0 []    \\xC0\\xD0");
-    exec("scan -f 2", true, "\\x90 \\xA0:\\xB0 []    \\xC0\\xD0");
-    exec("scan -f 2", true, "\\x90 \\xA0:\\xB0 []    \\xC0\\xD0\\xE0", false);
-    exec("scan -b \\x90 -e \\x90 -c \\xA0", true, "\\x90 \\xA0:\\xB0 []    \\xC0");
-    exec("scan -b \\x90 -e \\x90 -c \\xA0:\\xB0", true, "\\x90 \\xA0:\\xB0 []    \\xC0");
-    exec("scan -b \\x90 -be", true, "\\x90 \\xA0:\\xB0 []    \\xC0", false);
-    exec("scan -e \\x90 -ee", true, "\\x90 \\xA0:\\xB0 []    \\xC0", false);
-    exec("scan -b \\x90\\x00", true, "\\x90 \\xA0:\\xB0 []    \\xC0", false);
-    exec("scan -e \\x8f", true, "\\x90 \\xA0:\\xB0 []    \\xC0", false);
-    exec("delete \\x90 \\xa0 \\xb0", true);
-    exec("scan", true, "\\x90 \\xA0:\\xB0 []    \\xC0", false);
-    exec("deletetable test -f", true, "Table: [test] has been deleted");
-  }
-
-  @Test
-  public void authsTest() throws Exception {
-    Shell.log.debug("Starting auths test --------------------------");
-    exec("setauths x,y,z", false, "Missing required option");
-    exec("setauths -s x,y,z -u notauser", false, "user does not exist");
-    exec("setauths -s y,z,x", true);
-    exec("getauths -u notauser", false, "user does not exist");
-    exec("getauths", true, "x,y,z");
-    exec("addauths -u notauser", false, "Missing required option");
-    exec("addauths -u notauser -s foo", false, "user does not exist");
-    exec("addauths -s a", true);
-    exec("getauths", true, "a,x,y,z");
-    exec("setauths -c", true);
-  }
-
-  @Test
-  public void userTest() throws Exception {
-    Shell.log.debug("Starting user test --------------------------");
-    // Test cannot be done via junit because createuser only prompts for password
-    // exec("createuser root", false, "user exists");
-  }
-
-  @Test
-  public void duContextTest() throws Exception {
-    Shell.log.debug("Starting du context test --------------------------");
-    exec("createtable t", true);
-    exec("du", true, "0 [t]");
-    exec("deletetable t -f", true, "Table: [t] has been deleted");
-  }
-
-  @Test
-  public void duTest() throws IOException {
-    Shell.log.debug("Starting DU test --------------------------");
-    exec("createtable t", true);
-    exec("du t", true, "0 [t]");
-    exec("deletetable t -f", true, "Table: [t] has been deleted");
-  }
-
-  @Test
-  public void duPatternTest() throws IOException {
-    Shell.log.debug("Starting DU with pattern test --------------------------");
-    exec("createtable t", true);
-    exec("createtable tt", true);
-    exec("du -p t.*", true, "0 [t, tt]");
-    exec("deletetable t -f", true, "Table: [t] has been deleted");
-    exec("deletetable tt -f", true, "Table: [tt] has been deleted");
-  }
-
-  @Test
-  public void scanDateStringFormatterTest() throws IOException {
-    Shell.log.debug("Starting scan dateStringFormatter test --------------------------");
-    exec("createtable t", true);
-    exec("insert r f q v -ts 0", true);
-    DateFormat dateFormat = new SimpleDateFormat(DateStringFormatter.DATE_FORMAT);
-    String expected = String.format("r f:q [] %s    v", dateFormat.format(new Date(0)));
-    exec("scan -fm org.apache.accumulo.core.util.format.DateStringFormatter -st", true, expected);
-    exec("deletetable t -f", true, "Table: [t] has been deleted");
-  }
-
-  @Test
-  public void commentTest() throws IOException {
-    Shell.log.debug("Starting comment test --------------------------");
-    exec("#", true, "Unknown command", false);
-    exec("# foo", true, "Unknown command", false);
-    exec("- foo", true, "Unknown command", true);
-  }
-
-  @Test
-  public void execFileTest() throws IOException {
-    Shell.log.debug("Starting exec file test --------------------------");
-    shell.config("--fake", "-u", "test", "-p", "secret", "-f", "src/test/resources/shelltest.txt");
-    assertEquals(0, shell.start());
-    assertGoodExit("Unknown command", false);
-  }
-
-  @Test
-  public void setIterTest() throws IOException {
-    Shell.log.debug("Starting setiter test --------------------------");
-    exec("createtable t", true);
-
-    String cmdJustClass = "setiter -class VersioningIterator -p 1";
-    exec(cmdJustClass, false, "java.lang.IllegalArgumentException", false);
-    exec(cmdJustClass, false, "fully qualified package name", true);
-
-    String cmdFullPackage = "setiter -class o.a.a.foo -p 1";
-    exec(cmdFullPackage, false, "java.lang.IllegalArgumentException", false);
-    exec(cmdFullPackage, false, "class not found", true);
-
-    String cmdNoOption = "setiter -class java.lang.String -p 1";
-    exec(cmdNoOption, false, "loaded successfully but does not implement SortedKeyValueIterator", true);
-
-    input.set("\n\n");
-    exec("setiter -scan -class org.apache.accumulo.core.iterators.ColumnFamilyCounter -p 30 -name foo", true);
-    
-    input.set("bar\nname value\n");
-    exec("setiter -scan -class org.apache.accumulo.core.iterators.ColumnFamilyCounter -p 31", true);
-    
-    //TODO can't verify this as config -t fails, functionality verified in ShellServerIT
-    
-    exec("deletetable t -f", true, "Table: [t] has been deleted");
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/test/java/org/apache/accumulo/shell/ShellUtilTest.java
----------------------------------------------------------------------
diff --git a/shell/src/test/java/org/apache/accumulo/shell/ShellUtilTest.java b/shell/src/test/java/org/apache/accumulo/shell/ShellUtilTest.java
deleted file mode 100644
index 4e99336..0000000
--- a/shell/src/test/java/org/apache/accumulo/shell/ShellUtilTest.java
+++ /dev/null
@@ -1,67 +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.accumulo.shell;
-
-import static org.junit.Assert.*;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-import java.util.List;
-
-import org.apache.accumulo.shell.ShellUtil;
-import org.apache.commons.codec.binary.Base64;
-import org.apache.commons.io.FileUtils;
-import org.apache.hadoop.io.Text;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-
-import com.google.common.collect.ImmutableList;
-
-public class ShellUtilTest {
-
-  @Rule
-  public TemporaryFolder folder = new TemporaryFolder(new File(System.getProperty("user.dir") + "/target"));
-
-  // String with 3 lines, with one empty line
-  private static final String FILEDATA = "line1\n\nline2";
-
-  @Test
-  public void testWithoutDecode() throws IOException {
-    File testFile = new File(folder.getRoot(), "testFileNoDecode.txt");
-    FileUtils.writeStringToFile(testFile, FILEDATA);
-    List<Text> output = ShellUtil.scanFile(testFile.getAbsolutePath(), false);
-    assertEquals(ImmutableList.of(new Text("line1"), new Text("line2")), output);
-  }
-
-  @Test
-  public void testWithDecode() throws IOException {
-    File testFile = new File(folder.getRoot(), "testFileWithDecode.txt");
-    FileUtils.writeStringToFile(testFile, FILEDATA);
-    List<Text> output = ShellUtil.scanFile(testFile.getAbsolutePath(), true);
-    assertEquals(
-        ImmutableList.of(new Text(Base64.decodeBase64("line1".getBytes(StandardCharsets.UTF_8))), new Text(Base64.decodeBase64("line2".getBytes(StandardCharsets.UTF_8)))),
-        output);
-  }
-
-  @Test(expected = FileNotFoundException.class)
-  public void testWithMissingFile() throws FileNotFoundException {
-    ShellUtil.scanFile("missingFile.txt", false);
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/test/java/org/apache/accumulo/shell/command/FormatterCommandTest.java
----------------------------------------------------------------------
diff --git a/shell/src/test/java/org/apache/accumulo/shell/command/FormatterCommandTest.java b/shell/src/test/java/org/apache/accumulo/shell/command/FormatterCommandTest.java
deleted file mode 100644
index 203f08f..0000000
--- a/shell/src/test/java/org/apache/accumulo/shell/command/FormatterCommandTest.java
+++ /dev/null
@@ -1,184 +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.accumulo.shell.command;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Iterator;
-import java.util.Map.Entry;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.TableExistsException;
-import org.apache.accumulo.core.data.Key;
-import org.apache.accumulo.core.data.Value;
-import org.apache.accumulo.core.util.format.Formatter;
-import org.apache.accumulo.shell.Shell;
-import org.apache.accumulo.shell.mock.MockShell;
-import org.apache.log4j.Level;
-import org.apache.log4j.Logger;
-import org.junit.Assert;
-import org.junit.Test;
-
-/**
- * Uses the MockShell to test the shell output with Formatters
- */
-public class FormatterCommandTest {
-  ByteArrayOutputStream out = null;
-  InputStream in = null;
-  
-  @Test
-  public void test() throws IOException, AccumuloException, AccumuloSecurityException, TableExistsException, ClassNotFoundException {
-    // Keep the Shell AUDIT log off the test output
-    Logger.getLogger(Shell.class).setLevel(Level.WARN);
-    
-    final String[] args = new String[] {"--fake", "-u", "root", "-p", ""};
-    
-    final String[] commands = createCommands();
-    
-    in = MockShell.makeCommands(commands);
-    out = new ByteArrayOutputStream();
-    
-    final MockShell shell = new MockShell(in, out);
-    shell.config(args);
-    
-    // Can't call createtable in the shell with MockAccumulo
-    shell.getConnector().tableOperations().create("test");
-    
-    try {
-      shell.start();
-    } catch (Exception e) {
-      Assert.fail("Exception while running commands: " + e.getMessage());
-    }
-    
-    shell.getReader().flush();
-    
-    final String[] output = new String(out.toByteArray()).split("\n\r");
-    
-    boolean formatterOn = false;
-    
-    final String[] expectedDefault = new String[] {"row cf:cq []    1234abcd", "row cf1:cq1 []    9876fedc", "row2 cf:cq []    13579bdf",
-        "row2 cf1:cq []    2468ace"};
-    
-    final String[] expectedFormatted = new String[] {"row cf:cq []    0x31 0x32 0x33 0x34 0x61 0x62 0x63 0x64",
-        "row cf1:cq1 []    0x39 0x38 0x37 0x36 0x66 0x65 0x64 0x63", "row2 cf:cq []    0x31 0x33 0x35 0x37 0x39 0x62 0x64 0x66",
-        "row2 cf1:cq []    0x32 0x34 0x36 0x38 0x61 0x63 0x65"};
-    
-    int outputIndex = 0;
-    while (outputIndex < output.length) {
-      final String line = output[outputIndex];
-      
-      if (line.startsWith("root@mock-instance")) {
-        if (line.contains("formatter")) {
-          formatterOn = true;
-        }
-        
-        outputIndex++;
-      } else if (line.startsWith("row")) {
-        int expectedIndex = 0;
-        String[] comparisonData;
-        
-        // Pick the type of data we expect (formatted or default)
-        if (formatterOn) {
-          comparisonData = expectedFormatted;
-        } else {
-          comparisonData = expectedDefault;
-        }
-        
-        // Ensure each output is what we expected
-        while (expectedIndex + outputIndex < output.length && expectedIndex < expectedFormatted.length) {
-          Assert.assertEquals(comparisonData[expectedIndex].trim(), output[expectedIndex + outputIndex].trim());
-          expectedIndex++;
-        }
-        
-        outputIndex += expectedIndex;
-      }
-    }
-  }
-  
-  private String[] createCommands() {
-    return new String[] {"table test", "insert row cf cq 1234abcd", "insert row cf1 cq1 9876fedc", "insert row2 cf cq 13579bdf", "insert row2 cf1 cq 2468ace",
-        "scan", "formatter -t test -f org.apache.accumulo.core.util.shell.command.FormatterCommandTest$HexFormatter", "scan"};
-  }
-  
-  /**
-   * <p>
-   * Simple <code>Formatter</code> that will convert each character in the Value from decimal to hexadecimal. Will automatically skip over characters in the
-   * value which do not fall within the [0-9,a-f] range.
-   * </p>
-   * 
-   * <p>
-   * Example: <code>'0'</code> will be displayed as <code>'0x30'</code>
-   * </p>
-   */
-  public static class HexFormatter implements Formatter {
-    private Iterator<Entry<Key,Value>> iter = null;
-    private boolean printTs = false;
-    
-    private final static String tab = "\t";
-    private final static String newline = "\n";
-    
-    public HexFormatter() {}
-    
-    @Override
-    public boolean hasNext() {
-      return this.iter.hasNext();
-    }
-    
-    @Override
-    public String next() {
-      final Entry<Key,Value> entry = iter.next();
-      
-      String key;
-      
-      // Observe the timestamps
-      if (printTs) {
-        key = entry.getKey().toString();
-      } else {
-        key = entry.getKey().toStringNoTime();
-      }
-      
-      final Value v = entry.getValue();
-      
-      // Approximate how much space we'll need
-      final StringBuilder sb = new StringBuilder(key.length() + v.getSize() * 5);
-      
-      sb.append(key).append(tab);
-      
-      for (byte b : v.get()) {
-        if ((b >= 48 && b <= 57) || (b >= 97 || b <= 102)) {
-          sb.append(String.format("0x%x ", Integer.valueOf(b)));
-        }
-      }
-      
-      sb.append(newline);
-      
-      return sb.toString();
-    }
-    
-    @Override
-    public void remove() {}
-    
-    @Override
-    public void initialize(final Iterable<Entry<Key,Value>> scanner, final boolean printTimestamps) {
-      this.iter = scanner.iterator();
-      this.printTs = printTimestamps;
-    }
-  }
-  
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/test/java/org/apache/accumulo/shell/format/DeleterFormatterTest.java
----------------------------------------------------------------------
diff --git a/shell/src/test/java/org/apache/accumulo/shell/format/DeleterFormatterTest.java b/shell/src/test/java/org/apache/accumulo/shell/format/DeleterFormatterTest.java
deleted file mode 100644
index e5b7394..0000000
--- a/shell/src/test/java/org/apache/accumulo/shell/format/DeleterFormatterTest.java
+++ /dev/null
@@ -1,177 +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.accumulo.shell.format;
-
-import static org.easymock.EasyMock.anyObject;
-import static org.easymock.EasyMock.createMock;
-import static org.easymock.EasyMock.createNiceMock;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.expectLastCall;
-import static org.easymock.EasyMock.replay;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.charset.StandardCharsets;
-import java.util.Collections;
-import java.util.Map;
-import java.util.TreeMap;
-
-import jline.UnsupportedTerminal;
-import jline.console.ConsoleReader;
-
-import org.apache.accumulo.core.client.BatchWriter;
-import org.apache.accumulo.core.client.MutationsRejectedException;
-import org.apache.accumulo.core.data.Key;
-import org.apache.accumulo.core.data.Mutation;
-import org.apache.accumulo.core.data.Value;
-import org.apache.accumulo.shell.Shell;
-import org.apache.accumulo.shell.format.DeleterFormatter;
-import org.junit.Before;
-import org.junit.Test;
-
-public class DeleterFormatterTest {
-  DeleterFormatter formatter;
-  Map<Key,Value> data;
-  BatchWriter writer;
-  BatchWriter exceptionWriter;
-  Shell shellState;
-
-  ByteArrayOutputStream baos;
-  ConsoleReader reader;
-
-  SettableInputStream input;
-
-  class SettableInputStream extends InputStream {
-    ByteArrayInputStream bais;
-
-    @Override
-    public int read() throws IOException {
-      return bais.read();
-    }
-
-    public void set(String in) {
-      bais = new ByteArrayInputStream(in.getBytes(StandardCharsets.UTF_8));
-    }
-  };
-
-  @Before
-  public void setUp() throws IOException, MutationsRejectedException {
-    input = new SettableInputStream();
-    baos = new ByteArrayOutputStream();
-
-    MutationsRejectedException mre = createMock(MutationsRejectedException.class);
-
-    writer = createNiceMock(BatchWriter.class);
-    exceptionWriter = createNiceMock(BatchWriter.class);
-    exceptionWriter.close();
-    expectLastCall().andThrow(mre);
-    exceptionWriter.addMutation(anyObject(Mutation.class));
-    expectLastCall().andThrow(mre);
-
-    shellState = createNiceMock(Shell.class);
-
-    reader = new ConsoleReader(input, baos, new UnsupportedTerminal());
-    expect(shellState.getReader()).andReturn(reader).anyTimes();
-
-    replay(writer, exceptionWriter, shellState);
-
-    data = new TreeMap<Key,Value>();
-    data.put(new Key("r", "cf", "cq"), new Value("value".getBytes(StandardCharsets.UTF_8)));
-  }
-
-  @Test
-  public void testEmpty() {
-    formatter = new DeleterFormatter(writer, Collections.<Key,Value> emptyMap().entrySet(), true, shellState, true);
-    assertFalse(formatter.hasNext());
-  }
-
-  @Test
-  public void testSingle() throws IOException {
-    formatter = new DeleterFormatter(writer, data.entrySet(), true, shellState, true);
-
-    assertTrue(formatter.hasNext());
-    assertNull(formatter.next());
-
-    verify("[DELETED]", " r ", "cf", "cq", "value");
-  }
-
-  @Test
-  public void testNo() throws IOException {
-    input.set("no\n");
-    data.put(new Key("z"), new Value("v2".getBytes(StandardCharsets.UTF_8)));
-    formatter = new DeleterFormatter(writer, data.entrySet(), true, shellState, false);
-
-    assertTrue(formatter.hasNext());
-    assertNull(formatter.next());
-
-    verify("[SKIPPED]", " r ", "cf", "cq", "value");
-
-    assertTrue(formatter.hasNext());
-  }
-
-  @Test
-  public void testNoConfirmation() throws IOException {
-    input.set("");
-    data.put(new Key("z"), new Value("v2".getBytes(StandardCharsets.UTF_8)));
-    formatter = new DeleterFormatter(writer, data.entrySet(), true, shellState, false);
-
-    assertTrue(formatter.hasNext());
-    assertNull(formatter.next());
-
-    verify("[SKIPPED]", " r ", "cf", "cq", "value");
-
-    assertFalse(formatter.hasNext());
-  }
-
-  @Test
-  public void testYes() throws IOException {
-    input.set("y\nyes\n");
-    data.put(new Key("z"), new Value("v2".getBytes(StandardCharsets.UTF_8)));
-    formatter = new DeleterFormatter(writer, data.entrySet(), true, shellState, false);
-
-    assertTrue(formatter.hasNext());
-    assertNull(formatter.next());
-    verify("[DELETED]", " r ", "cf", "cq", "value");
-
-    assertTrue(formatter.hasNext());
-    assertNull(formatter.next());
-    verify("[DELETED]", " z ", "v2");
-  }
-
-  @Test
-  public void testMutationException() {
-    formatter = new DeleterFormatter(exceptionWriter, data.entrySet(), true, shellState, true);
-
-    assertTrue(formatter.hasNext());
-    assertNull(formatter.next());
-    assertFalse(formatter.hasNext());
-  }
-
-  private void verify(String... chunks) throws IOException {
-    reader.flush();
-
-    String output = baos.toString();
-    for (String chunk : chunks) {
-      assertTrue(output.contains(chunk));
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/test/resources/log4j.properties
----------------------------------------------------------------------
diff --git a/shell/src/test/resources/log4j.properties b/shell/src/test/resources/log4j.properties
deleted file mode 100644
index 9f968f8..0000000
--- a/shell/src/test/resources/log4j.properties
+++ /dev/null
@@ -1,28 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License.  You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-log4j.rootLogger=INFO, CA
-log4j.appender.CA=org.apache.log4j.ConsoleAppender
-log4j.appender.CA.layout=org.apache.log4j.PatternLayout
-log4j.appender.CA.layout.ConversionPattern=[%t] %-5p %c %x - %m%n
-
-log4j.logger.org.apache.accumulo.core.iterators.system.VisibilityFilter=FATAL
-log4j.logger.org.apache.accumulo.core.iterators.user.TransformingIteratorTest$IllegalVisCompactionKeyTransformingIterator=FATAL
-log4j.logger.org.apache.accumulo.core.iterators.user.TransformingIteratorTest$IllegalVisKeyTransformingIterator=FATAL
-log4j.logger.org.apache.commons.vfs2.impl.DefaultFileSystemManager=WARN
-log4j.logger.org.apache.hadoop.mapred=ERROR
-log4j.logger.org.apache.hadoop.mapreduce.lib.output.FileOutputCommitter=ERROR
-log4j.logger.org.apache.hadoop.util.ProcessTree=ERROR
-log4j.logger.org.apache.accumulo.core.util.format=FATAL

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/test/resources/shelltest.txt
----------------------------------------------------------------------
diff --git a/shell/src/test/resources/shelltest.txt b/shell/src/test/resources/shelltest.txt
deleted file mode 100644
index 19b6f61..0000000
--- a/shell/src/test/resources/shelltest.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-# 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.
-exit
-foo

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/start/src/main/java/org/apache/accumulo/start/Main.java
----------------------------------------------------------------------
diff --git a/start/src/main/java/org/apache/accumulo/start/Main.java b/start/src/main/java/org/apache/accumulo/start/Main.java
index f34cd30..3c7da95 100644
--- a/start/src/main/java/org/apache/accumulo/start/Main.java
+++ b/start/src/main/java/org/apache/accumulo/start/Main.java
@@ -54,7 +54,7 @@ public class Main {
       } else if (args[0].equals("tserver")) {
         runTMP = cl.loadClass("org.apache.accumulo.tserver.TabletServer");
       } else if (args[0].equals("shell")) {
-        runTMP = cl.loadClass("org.apache.accumulo.shell.Shell");
+        runTMP = cl.loadClass("org.apache.accumulo.core.util.shell.Shell");
       } else if (args[0].equals("init")) {
         runTMP = cl.loadClass("org.apache.accumulo.server.init.Initialize");
       } else if (args[0].equals("admin")) {


[41/53] [abbrv] ACCUMULO-1879 Move shell into new package and module

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SetIterCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SetIterCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SetIterCommand.java
deleted file mode 100644
index 3d8a5a7..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SetIterCommand.java
+++ /dev/null
@@ -1,453 +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.accumulo.core.util.shell.commands;
-
-import java.io.IOException;
-import java.util.EnumSet;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Map.Entry;
-
-import jline.console.ConsoleReader;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.IteratorSetting;
-import org.apache.accumulo.core.client.NamespaceNotFoundException;
-import org.apache.accumulo.core.client.TableNotFoundException;
-import org.apache.accumulo.core.conf.Property;
-import org.apache.accumulo.core.data.Key;
-import org.apache.accumulo.core.data.Value;
-import org.apache.accumulo.core.iterators.IteratorUtil.IteratorScope;
-import org.apache.accumulo.core.iterators.OptionDescriber;
-import org.apache.accumulo.core.iterators.OptionDescriber.IteratorOptions;
-import org.apache.accumulo.core.iterators.SortedKeyValueIterator;
-import org.apache.accumulo.core.iterators.user.AgeOffFilter;
-import org.apache.accumulo.core.iterators.user.RegExFilter;
-import org.apache.accumulo.core.iterators.user.ReqVisFilter;
-import org.apache.accumulo.core.iterators.user.VersioningIterator;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.accumulo.core.util.shell.ShellCommandException;
-import org.apache.accumulo.core.util.shell.ShellCommandException.ErrorCode;
-import org.apache.accumulo.start.classloader.vfs.AccumuloVFSClassLoader;
-import org.apache.accumulo.start.classloader.vfs.ContextManager;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.OptionGroup;
-import org.apache.commons.cli.Options;
-import org.apache.commons.lang.StringUtils;
-import org.apache.commons.vfs2.FileSystemException;
-
-public class SetIterCommand extends Command {
-
-  private Option allScopeOpt, mincScopeOpt, majcScopeOpt, scanScopeOpt, nameOpt, priorityOpt;
-  private Option aggTypeOpt, ageoffTypeOpt, regexTypeOpt, versionTypeOpt, reqvisTypeOpt, classnameTypeOpt;
-
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException,
-      TableNotFoundException, IOException, ShellCommandException {
-
-    boolean tables = cl.hasOption(OptUtil.tableOpt().getOpt()) || !shellState.getTableName().isEmpty();
-    boolean namespaces = cl.hasOption(OptUtil.namespaceOpt().getOpt());
-
-    final int priority = Integer.parseInt(cl.getOptionValue(priorityOpt.getOpt()));
-
-    final Map<String,String> options = new HashMap<String,String>();
-    String classname = cl.getOptionValue(classnameTypeOpt.getOpt());
-    if (cl.hasOption(aggTypeOpt.getOpt())) {
-      Shell.log.warn("aggregators are deprecated");
-      @SuppressWarnings("deprecation")
-      String deprecatedClassName = org.apache.accumulo.core.iterators.AggregatingIterator.class.getName();
-      classname = deprecatedClassName;
-    } else if (cl.hasOption(regexTypeOpt.getOpt())) {
-      classname = RegExFilter.class.getName();
-    } else if (cl.hasOption(ageoffTypeOpt.getOpt())) {
-      classname = AgeOffFilter.class.getName();
-    } else if (cl.hasOption(versionTypeOpt.getOpt())) {
-      classname = VersioningIterator.class.getName();
-    } else if (cl.hasOption(reqvisTypeOpt.getOpt())) {
-      classname = ReqVisFilter.class.getName();
-    }
-
-    ClassLoader classloader = getClassLoader(cl, shellState);
-
-    // Get the iterator options, with potentially a name provided by the OptionDescriber impl or through user input
-    String configuredName = setUpOptions(classloader, shellState.getReader(), classname, options);
-
-    // Try to get the name provided by the setiter command
-    String name = cl.getOptionValue(nameOpt.getOpt(), null);
-    
-    // Cannot continue if no name is provided
-    if (null == name && null == configuredName) {
-      throw new IllegalArgumentException("No provided or default name for iterator");
-    } else if (null == name) {
-      // Fall back to the name from OptionDescriber or user input if none is provided on setiter option
-      name = configuredName;
-    }
-
-    if (namespaces) {
-      try {
-        setNamespaceProperties(cl, shellState, priority, options, classname, name);
-      } catch (NamespaceNotFoundException e) {
-        throw new IllegalArgumentException(e);
-      }
-    } else if (tables) {
-      setTableProperties(cl, shellState, priority, options, classname, name);
-    } else {
-      throw new IllegalArgumentException("No table or namespace specified");
-    }
-    return 0;
-  }
-
-  private ClassLoader getClassLoader(final CommandLine cl, final Shell shellState) throws AccumuloException, TableNotFoundException, AccumuloSecurityException,
-      IOException, FileSystemException {
-
-    boolean tables = cl.hasOption(OptUtil.tableOpt().getOpt()) || !shellState.getTableName().isEmpty();
-    boolean namespaces = cl.hasOption(OptUtil.namespaceOpt().getOpt());
-
-    String classpath = null;
-    Iterable<Entry<String,String>> tableProps;
-
-    if (namespaces) {
-      try {
-        tableProps = shellState.getConnector().namespaceOperations().getProperties(OptUtil.getNamespaceOpt(cl, shellState));
-      } catch (NamespaceNotFoundException e) {
-        throw new IllegalArgumentException(e);
-      }
-    } else if (tables) {
-      tableProps = shellState.getConnector().tableOperations().getProperties(OptUtil.getTableOpt(cl, shellState));
-    } else {
-      throw new IllegalArgumentException("No table or namespace specified");
-    }
-    for (Entry<String,String> entry : tableProps) {
-      if (entry.getKey().equals(Property.TABLE_CLASSPATH.getKey())) {
-        classpath = entry.getValue();
-      }
-    }
-
-    ClassLoader classloader;
-
-    if (classpath != null && !classpath.equals("")) {
-      shellState.getConnector().instanceOperations().getSystemConfiguration().get(Property.VFS_CONTEXT_CLASSPATH_PROPERTY.getKey() + classpath);
-
-      try {
-        AccumuloVFSClassLoader.getContextManager().setContextConfig(new ContextManager.DefaultContextsConfig(new Iterable<Map.Entry<String,String>>() {
-          @Override
-          public Iterator<Entry<String,String>> iterator() {
-            try {
-              return shellState.getConnector().instanceOperations().getSystemConfiguration().entrySet().iterator();
-            } catch (AccumuloException e) {
-              throw new RuntimeException(e);
-            } catch (AccumuloSecurityException e) {
-              throw new RuntimeException(e);
-            }
-          }
-        }));
-      } catch (IllegalStateException ise) {}
-
-      classloader = AccumuloVFSClassLoader.getContextManager().getClassLoader(classpath);
-    } else {
-      classloader = AccumuloVFSClassLoader.getClassLoader();
-    }
-    return classloader;
-  }
-
-  protected void setTableProperties(final CommandLine cl, final Shell shellState, final int priority, final Map<String,String> options, final String classname,
-      final String name) throws AccumuloException, AccumuloSecurityException, ShellCommandException, TableNotFoundException {
-    // remove empty values
-
-    final String tableName = OptUtil.getTableOpt(cl, shellState);
-
-    if (!shellState.getConnector().tableOperations().testClassLoad(tableName, classname, SortedKeyValueIterator.class.getName())) {
-      throw new ShellCommandException(ErrorCode.INITIALIZATION_FAILURE, "Servers are unable to load " + classname + " as type "
-          + SortedKeyValueIterator.class.getName());
-    }
-
-    final String aggregatorClass = options.get("aggregatorClass");
-    @SuppressWarnings("deprecation")
-    String deprecatedAggregatorClassName = org.apache.accumulo.core.iterators.aggregation.Aggregator.class.getName();
-    if (aggregatorClass != null && !shellState.getConnector().tableOperations().testClassLoad(tableName, aggregatorClass, deprecatedAggregatorClassName)) {
-      throw new ShellCommandException(ErrorCode.INITIALIZATION_FAILURE, "Servers are unable to load " + aggregatorClass + " as type "
-          + deprecatedAggregatorClassName);
-    }
-
-    for (Iterator<Entry<String,String>> i = options.entrySet().iterator(); i.hasNext();) {
-      final Entry<String,String> entry = i.next();
-      if (entry.getValue() == null || entry.getValue().isEmpty()) {
-        i.remove();
-      }
-    }
-    final EnumSet<IteratorScope> scopes = EnumSet.noneOf(IteratorScope.class);
-    if (cl.hasOption(allScopeOpt.getOpt()) || cl.hasOption(mincScopeOpt.getOpt())) {
-      scopes.add(IteratorScope.minc);
-    }
-    if (cl.hasOption(allScopeOpt.getOpt()) || cl.hasOption(majcScopeOpt.getOpt())) {
-      scopes.add(IteratorScope.majc);
-    }
-    if (cl.hasOption(allScopeOpt.getOpt()) || cl.hasOption(scanScopeOpt.getOpt())) {
-      scopes.add(IteratorScope.scan);
-    }
-    if (scopes.isEmpty()) {
-      throw new IllegalArgumentException("You must select at least one scope to configure");
-    }
-    final IteratorSetting setting = new IteratorSetting(priority, name, classname, options);
-    shellState.getConnector().tableOperations().attachIterator(tableName, setting, scopes);
-  }
-
-  protected void setNamespaceProperties(final CommandLine cl, final Shell shellState, final int priority, final Map<String,String> options,
-      final String classname, final String name) throws AccumuloException, AccumuloSecurityException, ShellCommandException, NamespaceNotFoundException {
-    // remove empty values
-
-    final String namespace = OptUtil.getNamespaceOpt(cl, shellState);
-
-    if (!shellState.getConnector().namespaceOperations().testClassLoad(namespace, classname, SortedKeyValueIterator.class.getName())) {
-      throw new ShellCommandException(ErrorCode.INITIALIZATION_FAILURE, "Servers are unable to load " + classname + " as type "
-          + SortedKeyValueIterator.class.getName());
-    }
-
-    final String aggregatorClass = options.get("aggregatorClass");
-    @SuppressWarnings("deprecation")
-    String deprecatedAggregatorClassName = org.apache.accumulo.core.iterators.aggregation.Aggregator.class.getName();
-    if (aggregatorClass != null && !shellState.getConnector().namespaceOperations().testClassLoad(namespace, aggregatorClass, deprecatedAggregatorClassName)) {
-      throw new ShellCommandException(ErrorCode.INITIALIZATION_FAILURE, "Servers are unable to load " + aggregatorClass + " as type "
-          + deprecatedAggregatorClassName);
-    }
-
-    for (Iterator<Entry<String,String>> i = options.entrySet().iterator(); i.hasNext();) {
-      final Entry<String,String> entry = i.next();
-      if (entry.getValue() == null || entry.getValue().isEmpty()) {
-        i.remove();
-      }
-    }
-    final EnumSet<IteratorScope> scopes = EnumSet.noneOf(IteratorScope.class);
-    if (cl.hasOption(allScopeOpt.getOpt()) || cl.hasOption(mincScopeOpt.getOpt())) {
-      scopes.add(IteratorScope.minc);
-    }
-    if (cl.hasOption(allScopeOpt.getOpt()) || cl.hasOption(majcScopeOpt.getOpt())) {
-      scopes.add(IteratorScope.majc);
-    }
-    if (cl.hasOption(allScopeOpt.getOpt()) || cl.hasOption(scanScopeOpt.getOpt())) {
-      scopes.add(IteratorScope.scan);
-    }
-    if (scopes.isEmpty()) {
-      throw new IllegalArgumentException("You must select at least one scope to configure");
-    }
-    final IteratorSetting setting = new IteratorSetting(priority, name, classname, options);
-    shellState.getConnector().namespaceOperations().attachIterator(namespace, setting, scopes);
-  }
-
-  private static String setUpOptions(ClassLoader classloader, final ConsoleReader reader, final String className, final Map<String,String> options)
-      throws IOException, ShellCommandException {
-    String input;
-    @SuppressWarnings("rawtypes")
-    SortedKeyValueIterator untypedInstance;
-    @SuppressWarnings("rawtypes")
-    Class<? extends SortedKeyValueIterator> clazz;
-    try {
-      clazz = classloader.loadClass(className).asSubclass(SortedKeyValueIterator.class);
-      untypedInstance = clazz.newInstance();
-    } catch (ClassNotFoundException e) {
-      StringBuilder msg = new StringBuilder("Unable to load ").append(className);
-      if (className.indexOf('.') < 0) {
-        msg.append("; did you use a fully qualified package name?");
-      } else {
-        msg.append("; class not found.");
-      }
-      throw new ShellCommandException(ErrorCode.INITIALIZATION_FAILURE, msg.toString());
-    } catch (InstantiationException e) {
-      throw new IllegalArgumentException(e.getMessage());
-    } catch (IllegalAccessException e) {
-      throw new IllegalArgumentException(e.getMessage());
-    } catch (ClassCastException e) {
-      StringBuilder msg = new StringBuilder(50);
-      msg.append(className).append(" loaded successfully but does not implement SortedKeyValueIterator.");
-      msg.append(" This class cannot be used with this command.");
-      throw new ShellCommandException(ErrorCode.INITIALIZATION_FAILURE, msg.toString());
-    }
-
-    @SuppressWarnings("unchecked")
-    SortedKeyValueIterator<Key,Value> skvi = (SortedKeyValueIterator<Key,Value>) untypedInstance;
-    OptionDescriber iterOptions = null;
-    if (OptionDescriber.class.isAssignableFrom(skvi.getClass())) {
-      iterOptions = (OptionDescriber) skvi;
-    }
-
-    String iteratorName;
-    if (null != iterOptions) {
-      final IteratorOptions itopts = iterOptions.describeOptions();
-      iteratorName = itopts.getName();
-      
-      if (iteratorName == null) {
-        throw new IllegalArgumentException(className + " described its default distinguishing name as null");
-      }
-      String shortClassName = className;
-      if (className.contains(".")) {
-        shortClassName = className.substring(className.lastIndexOf('.') + 1);
-      }
-      final Map<String,String> localOptions = new HashMap<String,String>();
-      do {
-        // clean up the overall options that caused things to fail
-        for (String key : localOptions.keySet()) {
-          options.remove(key);
-        }
-        localOptions.clear();
-  
-        reader.println(itopts.getDescription());
-  
-        String prompt;
-        if (itopts.getNamedOptions() != null) {
-          for (Entry<String,String> e : itopts.getNamedOptions().entrySet()) {
-            prompt = Shell.repeat("-", 10) + "> set " + shortClassName + " parameter " + e.getKey() + ", " + e.getValue() + ": ";
-            reader.flush();
-            input = reader.readLine(prompt);
-            if (input == null) {
-              reader.println();
-              throw new IOException("Input stream closed");
-            }
-            // Places all Parameters and Values into the LocalOptions, even if the value is "".
-            // This allows us to check for "" values when setting the iterators and allows us to remove
-            // the parameter and value from the table property.
-            localOptions.put(e.getKey(), input);
-          }
-        }
-  
-        if (itopts.getUnnamedOptionDescriptions() != null) {
-          for (String desc : itopts.getUnnamedOptionDescriptions()) {
-            reader.println(Shell.repeat("-", 10) + "> entering options: " + desc);
-            input = "start";
-            prompt = Shell.repeat("-", 10) + "> set " + shortClassName + " option (<name> <value>, hit enter to skip): ";
-            while (true) {
-              reader.flush();
-              input = reader.readLine(prompt);
-              if (input == null) {
-                reader.println();
-                throw new IOException("Input stream closed");
-              } else {
-                input = new String(input);
-              }
-  
-              if (input.length() == 0)
-                break;
-  
-              String[] sa = input.split(" ", 2);
-              localOptions.put(sa[0], sa[1]);
-            }
-          }
-        }
-  
-        options.putAll(localOptions);
-        if (!iterOptions.validateOptions(options))
-          reader.println("invalid options for " + clazz.getName());
-  
-      } while (!iterOptions.validateOptions(options));
-    } else {
-      reader.flush();
-      reader.println("The iterator class does not implement OptionDescriber. Consider this for better iterator configuration using this setiter command.");
-      iteratorName = reader.readLine("Name for iterator (enter to skip): ");
-      if (null == iteratorName) {
-        reader.println();
-        throw new IOException("Input stream closed");
-      } else if (StringUtils.isWhitespace(iteratorName)) {
-        // Treat whitespace or empty string as no name provided
-        iteratorName = null;
-      }
-      
-      reader.flush();
-      reader.println("Optional, configure name-value options for iterator:");
-      String prompt = Shell.repeat("-", 10) + "> set option (<name> <value>, hit enter to skip): ";
-      final HashMap<String,String> localOptions = new HashMap<String,String>();
-      
-      while (true) {
-        reader.flush();
-        input = reader.readLine(prompt);
-        if (input == null) {
-          reader.println();
-          throw new IOException("Input stream closed");
-        } else if (StringUtils.isWhitespace(input)) {
-          break;
-        } 
-
-        String[] sa = input.split(" ", 2);
-        localOptions.put(sa[0], sa[1]);
-      }
-      
-      options.putAll(localOptions);
-    }
-    
-    return iteratorName;
-  }
-
-  @Override
-  public String description() {
-    return "sets a table-specific or namespace-specific iterator";
-  }
-
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-
-    priorityOpt = new Option("p", "priority", true, "the order in which the iterator is applied");
-    priorityOpt.setArgName("pri");
-    priorityOpt.setRequired(true);
-
-    nameOpt = new Option("n", "name", true, "iterator to set");
-    nameOpt.setArgName("itername");
-
-    allScopeOpt = new Option("all", "all-scopes", false, "applied at scan time, minor and major compactions");
-    mincScopeOpt = new Option(IteratorScope.minc.name(), "minor-compaction", false, "applied at minor compaction");
-    majcScopeOpt = new Option(IteratorScope.majc.name(), "major-compaction", false, "applied at major compaction");
-    scanScopeOpt = new Option(IteratorScope.scan.name(), "scan-time", false, "applied at scan time");
-
-    final OptionGroup typeGroup = new OptionGroup();
-    classnameTypeOpt = new Option("class", "class-name", true, "a java class that implements SortedKeyValueIterator");
-    classnameTypeOpt.setArgName("name");
-    aggTypeOpt = new Option("agg", "aggregator", false, "an aggregating type");
-    regexTypeOpt = new Option("regex", "regular-expression", false, "a regex matching iterator");
-    versionTypeOpt = new Option("vers", "version", false, "a versioning iterator");
-    reqvisTypeOpt = new Option("reqvis", "require-visibility", false, "an iterator that omits entries with empty visibilities");
-    ageoffTypeOpt = new Option("ageoff", "ageoff", false, "an aging off iterator");
-
-    typeGroup.addOption(classnameTypeOpt);
-    typeGroup.addOption(aggTypeOpt);
-    typeGroup.addOption(regexTypeOpt);
-    typeGroup.addOption(versionTypeOpt);
-    typeGroup.addOption(reqvisTypeOpt);
-    typeGroup.addOption(ageoffTypeOpt);
-    typeGroup.setRequired(true);
-
-    final OptionGroup tableGroup = new OptionGroup();
-    tableGroup.addOption(OptUtil.tableOpt("table to configure iterators on"));
-    tableGroup.addOption(OptUtil.namespaceOpt("namespace to configure iterators on"));
-
-    o.addOption(priorityOpt);
-    o.addOption(nameOpt);
-    o.addOption(allScopeOpt);
-    o.addOption(mincScopeOpt);
-    o.addOption(majcScopeOpt);
-    o.addOption(scanScopeOpt);
-    o.addOptionGroup(typeGroup);
-    o.addOptionGroup(tableGroup);
-    return o;
-  }
-
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SetScanIterCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SetScanIterCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SetScanIterCommand.java
deleted file mode 100644
index 513975c..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SetScanIterCommand.java
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.accumulo.core.util.shell.commands;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.IteratorSetting;
-import org.apache.accumulo.core.client.Scanner;
-import org.apache.accumulo.core.client.TableNotFoundException;
-import org.apache.accumulo.core.iterators.IteratorUtil.IteratorScope;
-import org.apache.accumulo.core.iterators.SortedKeyValueIterator;
-import org.apache.accumulo.core.security.Authorizations;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.ShellCommandException;
-import org.apache.accumulo.core.util.shell.ShellCommandException.ErrorCode;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.OptionGroup;
-import org.apache.commons.cli.Options;
-
-public class SetScanIterCommand extends SetIterCommand {
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException, TableNotFoundException,
-      IOException, ShellCommandException {
-    Shell.log.warn("Deprecated, use " + new SetShellIterCommand().getName());
-    return super.execute(fullCommand, cl, shellState);
-  }
-  
-  @Override
-  protected void setTableProperties(final CommandLine cl, final Shell shellState, final int priority, final Map<String,String> options, final String classname,
-      final String name) throws AccumuloException, AccumuloSecurityException, ShellCommandException, TableNotFoundException {
-    
-    final String tableName = OptUtil.getTableOpt(cl, shellState);
-
-    // instead of setting table properties, just put the options in a list to use at scan time
-    Class<?> loadClass;
-    try {
-      loadClass = getClass().getClassLoader().loadClass(classname);
-    } catch (ClassNotFoundException e) {
-      throw new ShellCommandException(ErrorCode.INITIALIZATION_FAILURE, "Unable to load " + classname);
-    }
-    try {
-      loadClass.asSubclass(SortedKeyValueIterator.class);
-    } catch (ClassCastException ex) {
-      throw new ShellCommandException(ErrorCode.INITIALIZATION_FAILURE, "Unable to load " + classname  + " as type "
-          + SortedKeyValueIterator.class.getName());
-    }
-    
-    for (Iterator<Entry<String,String>> i = options.entrySet().iterator(); i.hasNext();) {
-      final Entry<String,String> entry = i.next();
-      if (entry.getValue() == null || entry.getValue().isEmpty()) {
-        i.remove();
-      }
-    }
-
-    List<IteratorSetting> tableScanIterators = shellState.scanIteratorOptions.get(tableName);
-    if (tableScanIterators == null) {
-      tableScanIterators = new ArrayList<IteratorSetting>();
-      shellState.scanIteratorOptions.put(tableName, tableScanIterators);
-    }
-    final IteratorSetting setting = new IteratorSetting(priority, name, classname);
-    setting.addOptions(options);
-    
-    // initialize a scanner to ensure the new setting does not conflict with existing settings
-    final String user = shellState.getConnector().whoami();
-    final Authorizations auths = shellState.getConnector().securityOperations().getUserAuthorizations(user);
-    final Scanner scanner = shellState.getConnector().createScanner(tableName, auths);
-    for (IteratorSetting s : tableScanIterators) {
-      scanner.addScanIterator(s);
-    }
-    scanner.addScanIterator(setting);
-    
-    // if no exception has been thrown, it's safe to add it to the list
-    tableScanIterators.add(setting);
-    Shell.log.debug("Scan iterators :" + shellState.scanIteratorOptions.get(tableName));
-  }
-  
-  @Override
-  public String description() {
-    return "sets a table-specific scan iterator for this shell session";
-  }
-  
-  @Override
-  public Options getOptions() {
-    // Remove the options that specify which type of iterator this is, since
-    // they are all scan iterators with this command.
-    final HashSet<OptionGroup> groups = new HashSet<OptionGroup>();
-    final Options parentOptions = super.getOptions();
-    final Options modifiedOptions = new Options();
-    for (Iterator<?> it = parentOptions.getOptions().iterator(); it.hasNext();) {
-      Option o = (Option) it.next();
-      if (!IteratorScope.majc.name().equals(o.getOpt()) && !IteratorScope.minc.name().equals(o.getOpt()) && !IteratorScope.scan.name().equals(o.getOpt())) {
-        modifiedOptions.addOption(o);
-        OptionGroup group = parentOptions.getOptionGroup(o);
-        if (group != null)
-          groups.add(group);
-      }
-    }
-    for (OptionGroup group : groups) {
-      modifiedOptions.addOptionGroup(group);
-    }
-    return modifiedOptions;
-  }
-  
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SetShellIterCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SetShellIterCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SetShellIterCommand.java
deleted file mode 100644
index b95725a..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SetShellIterCommand.java
+++ /dev/null
@@ -1,131 +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.accumulo.core.util.shell.commands;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.IteratorSetting;
-import org.apache.accumulo.core.client.TableNotFoundException;
-import org.apache.accumulo.core.iterators.IteratorUtil.IteratorScope;
-import org.apache.accumulo.core.iterators.SortedKeyValueIterator;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.ShellCommandException;
-import org.apache.accumulo.core.util.shell.ShellCommandException.ErrorCode;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.OptionGroup;
-import org.apache.commons.cli.Options;
-
-public class SetShellIterCommand extends SetIterCommand {
-  private Option profileOpt;
-
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException,
-      TableNotFoundException, IOException, ShellCommandException {
-    return super.execute(fullCommand, cl, shellState);
-  }
-  
-  @Override
-  protected void setTableProperties(final CommandLine cl, final Shell shellState, final int priority, final Map<String,String> options, final String classname,
-      final String name) throws AccumuloException, AccumuloSecurityException, ShellCommandException, TableNotFoundException {
-    // instead of setting table properties, just put the options in a list to use at scan time
-    
-    String profile = cl.getOptionValue(profileOpt.getOpt());
-
-    // instead of setting table properties, just put the options in a list to use at scan time
-    Class<?> loadClass;
-    try {
-      loadClass = getClass().getClassLoader().loadClass(classname);
-    } catch (ClassNotFoundException e) {
-      throw new ShellCommandException(ErrorCode.INITIALIZATION_FAILURE, "Unable to load " + classname);
-    }
-    try {
-      loadClass.asSubclass(SortedKeyValueIterator.class);
-    } catch (ClassCastException ex) {
-      throw new ShellCommandException(ErrorCode.INITIALIZATION_FAILURE, "xUnable to load " + classname  + " as type "
-          + SortedKeyValueIterator.class.getName());
-    }
-    
-    for (Iterator<Entry<String,String>> i = options.entrySet().iterator(); i.hasNext();) {
-      final Entry<String,String> entry = i.next();
-      if (entry.getValue() == null || entry.getValue().isEmpty()) {
-        i.remove();
-      }
-    }
-
-    List<IteratorSetting> tableScanIterators = shellState.iteratorProfiles.get(profile);
-    if (tableScanIterators == null) {
-      tableScanIterators = new ArrayList<IteratorSetting>();
-      shellState.iteratorProfiles.put(profile, tableScanIterators);
-    }
-    final IteratorSetting setting = new IteratorSetting(priority, name, classname);
-    setting.addOptions(options);
-
-    Iterator<IteratorSetting> iter = tableScanIterators.iterator();
-    while (iter.hasNext()) {
-      if (iter.next().getName().equals(name)) {
-        iter.remove();
-      }
-    }
-
-    tableScanIterators.add(setting);
-  }
-  
-  @Override
-  public String description() {
-    return "adds an iterator to a profile for this shell session";
-  }
-  
-  @Override
-  public Options getOptions() {
-    // Remove the options that specify which type of iterator this is, since
-    // they are all scan iterators with this command.
-    final HashSet<OptionGroup> groups = new HashSet<OptionGroup>();
-    final Options parentOptions = super.getOptions();
-    final Options modifiedOptions = new Options();
-    for (Iterator<?> it = parentOptions.getOptions().iterator(); it.hasNext();) {
-      Option o = (Option) it.next();
-      if (!IteratorScope.majc.name().equals(o.getOpt()) && !IteratorScope.minc.name().equals(o.getOpt()) && !IteratorScope.scan.name().equals(o.getOpt())
-          && !"table".equals(o.getLongOpt())) {
-        modifiedOptions.addOption(o);
-        OptionGroup group = parentOptions.getOptionGroup(o);
-        if (group != null)
-          groups.add(group);
-      }
-    }
-    for (OptionGroup group : groups) {
-      modifiedOptions.addOptionGroup(group);
-    }
-    
-    profileOpt = new Option("pn", "profile", true, "iterator profile name");
-    profileOpt.setRequired(true);
-    profileOpt.setArgName("profile");
-    
-    modifiedOptions.addOption(profileOpt);
-
-    return modifiedOptions;
-  }
-  
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ShellPluginConfigurationCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ShellPluginConfigurationCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ShellPluginConfigurationCommand.java
deleted file mode 100644
index d4c9739..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ShellPluginConfigurationCommand.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.accumulo.core.util.shell.commands;
-
-import java.util.Iterator;
-import java.util.Map.Entry;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.TableNotFoundException;
-import org.apache.accumulo.core.conf.Property;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.accumulo.start.classloader.vfs.AccumuloVFSClassLoader;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.OptionGroup;
-import org.apache.commons.cli.Options;
-import org.apache.log4j.Logger;
-
-public abstract class ShellPluginConfigurationCommand extends Command {
-  private Option removePluginOption, pluginClassOption, listPluginOption;
-  
-  private String pluginType;
-  
-  private Property tableProp;
-  
-  private String classOpt;
-  
-  ShellPluginConfigurationCommand(final String typeName, final Property tableProp, final String classOpt) {
-    this.pluginType = typeName;
-    this.tableProp = tableProp;
-    this.classOpt = classOpt;
-  }
-
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    final String tableName = OptUtil.getTableOpt(cl, shellState);
-    
-    if (cl.hasOption(removePluginOption.getOpt())) {
-      // Remove the property
-      removePlugin(cl, shellState, tableName);
-      
-      shellState.getReader().println("Removed "+pluginType+" on " + tableName);
-    } else if (cl.hasOption(listPluginOption.getOpt())) {
-      // Get the options for this table
-      final Iterator<Entry<String,String>> iter = shellState.getConnector().tableOperations().getProperties(tableName).iterator();
-      
-      while (iter.hasNext()) {
-        Entry<String,String> ent = iter.next();
-        
-        // List all parameters with the property name
-        if (ent.getKey().startsWith(tableProp.toString())) {
-          shellState.getReader().println(ent.getKey() + ": " + ent.getValue());
-        }
-      }
-    } else {
-      // Set the plugin with the provided options
-      String className = cl.getOptionValue(pluginClassOption.getOpt());
-      
-      // Set the plugin property on the table
-      setPlugin(cl, shellState, tableName, className);
-    }
-    
-    return 0;
-  }
-
-  protected void setPlugin(final CommandLine cl, final Shell shellState, final String tableName, final String className) throws AccumuloException, AccumuloSecurityException {
-    shellState.getConnector().tableOperations().setProperty(tableName, tableProp.toString(), className);
-  }
-  
-  protected void removePlugin(final CommandLine cl, final Shell shellState, final String tableName) throws AccumuloException, AccumuloSecurityException {
-    shellState.getConnector().tableOperations().removeProperty(tableName, tableProp.toString());
-  }
-  
-  public static <T> Class<? extends T> getPluginClass(final String tableName, final Shell shellState, final Class<T> clazz, final Property pluginProp) {
-    Iterator<Entry<String,String>> props;
-    try {
-      props = shellState.getConnector().tableOperations().getProperties(tableName).iterator();
-    } catch (AccumuloException e) {
-      return null;
-    } catch (TableNotFoundException e) {
-      return null;
-    }
-    
-    while (props.hasNext()) {
-      final Entry<String,String> ent = props.next();
-      if (ent.getKey().equals(pluginProp.toString())) {
-        Class<? extends T> pluginClazz;
-        try {
-          pluginClazz = AccumuloVFSClassLoader.loadClass(ent.getValue(), clazz);
-        } catch (ClassNotFoundException e) {
-          Logger.getLogger(ShellPluginConfigurationCommand.class).warn("Class not found" + e.getMessage());
-          return null;
-        }
-        
-        return pluginClazz;
-      }
-    }
-    
-    return null;
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-    final OptionGroup actionGroup = new OptionGroup();
-    
-    pluginClassOption = new Option(classOpt, pluginType, true, "fully qualified name of the " + pluginType + " class to use");
-    pluginClassOption.setArgName("className");
-    
-    // Action to take: apply (default), remove, list
-    removePluginOption = new Option("r", "remove", false, "remove the current "+pluginType+"");
-    listPluginOption = new Option("l", "list", false, "display the current "+pluginType+"");
-    
-    actionGroup.addOption(pluginClassOption);
-    actionGroup.addOption(removePluginOption);
-    actionGroup.addOption(listPluginOption);
-    actionGroup.setRequired(true);
-    
-    o.addOptionGroup(actionGroup);
-    o.addOption(OptUtil.tableOpt("table to set the "+pluginType+" on"));
-    
-    return o;
-  }
-  
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-  
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SleepCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SleepCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SleepCommand.java
deleted file mode 100644
index ab69456..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SleepCommand.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.accumulo.core.util.shell.commands;
-
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-
-public class SleepCommand extends Command {
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    final double secs = Double.parseDouble(cl.getArgs()[0]);
-    Thread.sleep((long) (secs * 1000));
-    return 0;
-  }
-  
-  @Override
-  public String description() {
-    return "sleeps for the given number of seconds";
-  }
-  
-  @Override
-  public int numArgs() {
-    return 1;
-  }
-  
-  @Override
-  public String usage() {
-    return getName() + " <seconds>";
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SystemPermissionsCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SystemPermissionsCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SystemPermissionsCommand.java
deleted file mode 100644
index 3dec6fc..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SystemPermissionsCommand.java
+++ /dev/null
@@ -1,44 +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.accumulo.core.util.shell.commands;
-
-import java.io.IOException;
-
-import org.apache.accumulo.core.security.SystemPermission;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-
-public class SystemPermissionsCommand extends Command {
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws IOException {
-    for (String p : SystemPermission.printableValues()) {
-      shellState.getReader().println(p);
-    }
-    return 0;
-  }
-  
-  @Override
-  public String description() {
-    return "displays a list of valid system permissions";
-  }
-  
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/TableCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/TableCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/TableCommand.java
deleted file mode 100644
index d77f6fb..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/TableCommand.java
+++ /dev/null
@@ -1,60 +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.accumulo.core.util.shell.commands;
-
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.TableNotFoundException;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.accumulo.core.util.shell.Token;
-import org.apache.commons.cli.CommandLine;
-
-public class TableCommand extends Command {
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException, TableNotFoundException {
-    final String tableName = cl.getArgs()[0];
-    if (!shellState.getConnector().tableOperations().exists(tableName)) {
-      throw new TableNotFoundException(null, tableName, null);
-    }
-    shellState.setTableName(tableName);
-    return 0;
-  }
-  
-  @Override
-  public String description() {
-    return "switches to the specified table";
-  }
-  
-  @Override
-  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> special) {
-    registerCompletionForTables(root, special);
-  }
-  
-  @Override
-  public String usage() {
-    return getName() + " <tableName>";
-  }
-  
-  @Override
-  public int numArgs() {
-    return 1;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/TableOperation.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/TableOperation.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/TableOperation.java
deleted file mode 100644
index 27946b8..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/TableOperation.java
+++ /dev/null
@@ -1,153 +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.accumulo.core.util.shell.commands;
-
-import java.util.Map;
-import java.util.Set;
-import java.util.SortedSet;
-import java.util.TreeSet;
-
-import org.apache.accumulo.core.client.Instance;
-import org.apache.accumulo.core.client.TableNotFoundException;
-import org.apache.accumulo.core.client.impl.Namespaces;
-import org.apache.accumulo.core.client.impl.Tables;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.accumulo.core.util.shell.Token;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.OptionGroup;
-import org.apache.commons.cli.Options;
-
-public abstract class TableOperation extends Command {
-
-  protected Option optTablePattern, optTableName, optNamespace;
-  private boolean force = true;
-  private boolean useCommandLine = true;
-
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    // populate the tableSet set with the tables you want to operate on
-    final SortedSet<String> tableSet = new TreeSet<String>();
-    if (cl.hasOption(optTablePattern.getOpt())) {
-      for (String table : shellState.getConnector().tableOperations().list())
-        if (table.matches(cl.getOptionValue(optTablePattern.getOpt()))) {
-          tableSet.add(table);
-        }
-    } else if (cl.hasOption(optTableName.getOpt())) {
-      tableSet.add(cl.getOptionValue(optTableName.getOpt()));
-    } else if (cl.hasOption(optNamespace.getOpt())) {
-      Instance instance = shellState.getInstance();
-      String namespaceId = Namespaces.getNamespaceId(instance, cl.getOptionValue(optNamespace.getOpt()));
-      for (String tableId : Namespaces.getTableIds(instance, namespaceId)) {
-        tableSet.add(Tables.getTableName(instance, tableId));
-      }
-    } else if (useCommandLine && cl.getArgs().length > 0) {
-      for (String tableName : cl.getArgs()) {
-        tableSet.add(tableName);
-      }
-    } else {
-      shellState.checkTableState();
-      tableSet.add(shellState.getTableName());
-    }
-
-    if (tableSet.isEmpty())
-      Shell.log.warn("No tables found that match your criteria");
-
-    boolean more = true;
-    // flush the tables
-    for (String tableName : tableSet) {
-      if (!more) {
-        break;
-      }
-      if (!shellState.getConnector().tableOperations().exists(tableName)) {
-        throw new TableNotFoundException(null, tableName, null);
-      }
-      boolean operate = true;
-      if (!force) {
-        shellState.getReader().flush();
-        String line = shellState.getReader().readLine(getName() + " { " + tableName + " } (yes|no)? ");
-        more = line != null;
-        operate = line != null && (line.equalsIgnoreCase("y") || line.equalsIgnoreCase("yes"));
-      }
-      if (operate) {
-        doTableOp(shellState, tableName);
-      }
-    }
-
-    return 0;
-  }
-
-  protected abstract void doTableOp(Shell shellState, String tableName) throws Exception;
-
-  @Override
-  public String description() {
-    return "makes a best effort to flush tables from memory to disk";
-  }
-
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-
-    optTablePattern = new Option("p", "pattern", true, "regex pattern of table names to operate on");
-    optTablePattern.setArgName("pattern");
-
-    optTableName = new Option(Shell.tableOption, "table", true, "name of a table to operate on");
-    optTableName.setArgName("tableName");
-
-    optNamespace = new Option(Shell.namespaceOption, "namespace", true, "name of a namespace to operate on");
-    optNamespace.setArgName("namespace");
-
-    final OptionGroup opg = new OptionGroup();
-
-    opg.addOption(optTablePattern);
-    opg.addOption(optTableName);
-    opg.addOption(optNamespace);
-
-    o.addOptionGroup(opg);
-
-    return o;
-  }
-
-  @Override
-  public int numArgs() {
-    return useCommandLine ? Shell.NO_FIXED_ARG_LENGTH_CHECK : 0;
-  }
-
-  protected void force() {
-    force = true;
-  }
-
-  protected void noForce() {
-    force = false;
-  }
-
-  protected void disableUnflaggedTableOptions() {
-    useCommandLine = false;
-  }
-
-  @Override
-  public String usage() {
-    return getName() + " [<table>{ <table>}]";
-  }
-
-  @Override
-  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> special) {
-    if (useCommandLine)
-      registerCompletionForTables(root, special);
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/TablePermissionsCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/TablePermissionsCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/TablePermissionsCommand.java
deleted file mode 100644
index 1f92f21..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/TablePermissionsCommand.java
+++ /dev/null
@@ -1,44 +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.accumulo.core.util.shell.commands;
-
-import java.io.IOException;
-
-import org.apache.accumulo.core.security.TablePermission;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-
-public class TablePermissionsCommand extends Command {
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws IOException {
-    for (String p : TablePermission.printableValues()) {
-      shellState.getReader().println(p);
-    }
-    return 0;
-  }
-  
-  @Override
-  public String description() {
-    return "displays a list of valid table permissions";
-  }
-  
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/TablesCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/TablesCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/TablesCommand.java
deleted file mode 100644
index a03a986..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/TablesCommand.java
+++ /dev/null
@@ -1,107 +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.accumulo.core.util.shell.commands;
-
-import java.io.IOException;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.TreeMap;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.NamespaceNotFoundException;
-import org.apache.accumulo.core.client.impl.Tables;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-import org.apache.commons.collections.MapUtils;
-
-import com.google.common.base.Function;
-import com.google.common.base.Predicate;
-import com.google.common.collect.Iterators;
-import com.google.common.collect.Maps;
-
-public class TablesCommand extends Command {
-  static final String NAME_AND_ID_FORMAT = "%-20s => %9s%n";
-
-  private Option tableIdOption;
-  private Option sortByTableIdOption;
-  private Option disablePaginationOpt;
-
-  @SuppressWarnings("unchecked")
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException, IOException,
-      NamespaceNotFoundException {
-
-    final String namespace = cl.hasOption(OptUtil.namespaceOpt().getOpt()) ? OptUtil.getNamespaceOpt(cl, shellState) : null;
-    Map<String,String> tables = shellState.getConnector().tableOperations().tableIdMap();
-
-    // filter only specified namespace
-    tables = Maps.filterKeys(tables, new Predicate<String>() {
-      @Override
-      public boolean apply(String tableName) {
-        return namespace == null || Tables.qualify(tableName).getFirst().equals(namespace);
-      }
-    });
-
-    final boolean sortByTableId = cl.hasOption(sortByTableIdOption.getOpt());
-    tables = new TreeMap<String,String>((sortByTableId ? MapUtils.invertMap(tables) : tables));
-
-    Iterator<String> it = Iterators.transform(tables.entrySet().iterator(), new Function<Entry<String,String>,String>() {
-      @Override
-      public String apply(Map.Entry<String,String> entry) {
-        String tableName = String.valueOf(sortByTableId ? entry.getValue() : entry.getKey());
-        String tableId = String.valueOf(sortByTableId ? entry.getKey() : entry.getValue());
-        if (namespace != null)
-          tableName = Tables.qualify(tableName).getSecond();
-        if (cl.hasOption(tableIdOption.getOpt()))
-          return String.format(NAME_AND_ID_FORMAT, tableName, tableId);
-        else
-          return tableName;
-      };
-    });
-
-    shellState.printLines(it, !cl.hasOption(disablePaginationOpt.getOpt()));
-    return 0;
-  }
-
-  @Override
-  public String description() {
-    return "displays a list of all existing tables";
-  }
-
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-    tableIdOption = new Option("l", "list-ids", false, "display internal table ids along with the table name");
-    o.addOption(tableIdOption);
-    sortByTableIdOption = new Option("s", "sort-ids", false, "with -l: sort output by table ids");
-    o.addOption(sortByTableIdOption);
-    disablePaginationOpt = new Option("np", "no-pagination", false, "disable pagination of output");
-    o.addOption(disablePaginationOpt);
-    o.addOption(OptUtil.namespaceOpt("name of namespace to list only its tables"));
-    return o;
-  }
-
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/TraceCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/TraceCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/TraceCommand.java
deleted file mode 100644
index 281a33a..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/TraceCommand.java
+++ /dev/null
@@ -1,101 +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.accumulo.core.util.shell.commands;
-
-import java.io.IOException;
-import java.util.Map;
-
-import org.apache.accumulo.trace.instrument.Trace;
-import org.apache.accumulo.core.client.Scanner;
-import org.apache.accumulo.core.conf.Property;
-import org.apache.accumulo.core.data.Range;
-import org.apache.accumulo.core.security.Authorizations;
-import org.apache.accumulo.core.trace.TraceDump;
-import org.apache.accumulo.core.trace.TraceDump.Printer;
-import org.apache.accumulo.core.util.BadArgumentException;
-import org.apache.accumulo.core.util.UtilWaitThread;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.commons.cli.CommandLine;
-import org.apache.hadoop.io.Text;
-
-public class TraceCommand extends DebugCommand {
-  
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws IOException {
-    if (cl.getArgs().length == 1) {
-      if (cl.getArgs()[0].equalsIgnoreCase("on")) {
-        Trace.on("shell:" + shellState.getPrincipal());
-      } else if (cl.getArgs()[0].equalsIgnoreCase("off")) {
-        if (Trace.isTracing()) {
-          final long trace = Trace.currentTrace().traceId();
-          Trace.off();
-          StringBuffer sb = new StringBuffer();
-          int traceCount = 0;
-          for (int i = 0; i < 30; i++) {
-            sb = new StringBuffer();
-            try {
-              final Map<String,String> properties = shellState.getConnector().instanceOperations().getSystemConfiguration();
-              final String table = properties.get(Property.TRACE_TABLE.getKey());
-              final String user = shellState.getConnector().whoami();
-              final Authorizations auths = shellState.getConnector().securityOperations().getUserAuthorizations(user);
-              final Scanner scanner = shellState.getConnector().createScanner(table, auths);
-              scanner.setRange(new Range(new Text(Long.toHexString(trace))));
-              final StringBuffer finalSB = sb;
-              traceCount = TraceDump.printTrace(scanner, new Printer() {
-                @Override
-                public void print(final String line) {
-                  try {
-                    finalSB.append(line + "\n");
-                  } catch (Exception ex) {
-                    throw new RuntimeException(ex);
-                  }
-                }
-              });
-              if (traceCount > 0) {
-                shellState.getReader().print(sb.toString());
-                break;
-              }
-            } catch (Exception ex) {
-              shellState.printException(ex);
-            }
-            shellState.getReader().println("Waiting for trace information");
-            shellState.getReader().flush();
-            UtilWaitThread.sleep(500);
-          }
-          if (traceCount < 0) {
-            // display the trace even though there are unrooted spans
-            shellState.getReader().print(sb.toString());
-          }
-        } else {
-          shellState.getReader().println("Not tracing");
-        }
-      } else
-        throw new BadArgumentException("Argument must be 'on' or 'off'", fullCommand, fullCommand.indexOf(cl.getArgs()[0]));
-    } else if (cl.getArgs().length == 0) {
-      shellState.getReader().println(Trace.isTracing() ? "on" : "off");
-    } else {
-      shellState.printException(new IllegalArgumentException("Expected 0 or 1 argument. There were " + cl.getArgs().length + "."));
-      printHelp(shellState);
-      return 1;
-    }
-    return 0;
-  }
-  
-  @Override
-  public String description() {
-    return "turns trace logging on or off";
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/UserCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/UserCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/UserCommand.java
deleted file mode 100644
index 07da450..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/UserCommand.java
+++ /dev/null
@@ -1,71 +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.accumulo.core.util.shell.commands;
-
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.security.tokens.PasswordToken;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.accumulo.core.util.shell.Token;
-import org.apache.commons.cli.CommandLine;
-
-public class UserCommand extends Command {
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException, IOException {
-    // save old credentials and connection in case of failure
-    String user = cl.getArgs()[0];
-    byte[] pass;
-    
-    // We can't let the wrapping try around the execute method deal
-    // with the exceptions because we have to do something if one
-    // of these methods fails
-    final String p = shellState.readMaskedLine("Enter password for user " + user + ": ", '*');
-    if (p == null) {
-      shellState.getReader().println();
-      return 0;
-    } // user canceled
-    pass = p.getBytes(StandardCharsets.UTF_8);
-    shellState.updateUser(user, new PasswordToken(pass));
-    return 0;
-  }
-  
-  @Override
-  public String description() {
-    return "switches to the specified user";
-  }
-  
-  @Override
-  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> special) {
-    registerCompletionForUsers(root, special);
-  }
-  
-  @Override
-  public String usage() {
-    return getName() + " <username>";
-  }
-  
-  @Override
-  public int numArgs() {
-    return 1;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/UserPermissionsCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/UserPermissionsCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/UserPermissionsCommand.java
deleted file mode 100644
index a126159..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/UserPermissionsCommand.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.accumulo.core.util.shell.commands;
-
-import java.io.IOException;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.security.NamespacePermission;
-import org.apache.accumulo.core.security.SystemPermission;
-import org.apache.accumulo.core.security.TablePermission;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-
-public class UserPermissionsCommand extends Command {
-  private Option userOpt;
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException, IOException {
-    final String user = cl.getOptionValue(userOpt.getOpt(), shellState.getConnector().whoami());
-
-    String delim = "";
-    shellState.getReader().print("System permissions: ");
-    for (SystemPermission p : SystemPermission.values()) {
-      if (p != null && shellState.getConnector().securityOperations().hasSystemPermission(user, p)) {
-        shellState.getReader().print(delim + "System." + p.name());
-        delim = ", ";
-      }
-    }
-    shellState.getReader().println();
-
-    boolean runOnce = true;
-    for (String n : shellState.getConnector().namespaceOperations().list()) {
-      delim = "";
-      for (NamespacePermission p : NamespacePermission.values()) {
-        if (p != null && shellState.getConnector().securityOperations().hasNamespacePermission(user, n, p)) {
-          if (runOnce) {
-            shellState.getReader().print("\nNamespace permissions (" + n + "): ");
-            runOnce = false;
-          }
-          shellState.getReader().print(delim + "Namespace." + p.name());
-          delim = ", ";
-        }
-      }
-      runOnce = true;
-    }
-    shellState.getReader().println();
-
-    
-    runOnce = true;
-    for (String t : shellState.getConnector().tableOperations().list()) {
-      delim = "";
-      for (TablePermission p : TablePermission.values()) {
-        if (shellState.getConnector().securityOperations().hasTablePermission(user, t, p) && p != null) {
-          if (runOnce) {
-            shellState.getReader().print("\nTable permissions (" + t + "): ");
-            runOnce = false;
-          }
-          shellState.getReader().print(delim + "Table." + p.name());
-          delim = ", ";
-        }
-
-      }
-      runOnce = true;
-    }
-    shellState.getReader().println();
-
-    return 0;
-  }
-
-  @Override
-  public String description() {
-    return "displays a user's system, table, and namespace permissions";
-  }
-
-  @Override
-  public Options getOptions() {
-    Options o = new Options();
-    userOpt = new Option(Shell.userOption, "user", true, "user to operate on");
-    userOpt.setArgName("user");
-    o.addOption(userOpt);
-    return o;
-  }
-
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/UsersCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/UsersCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/UsersCommand.java
deleted file mode 100644
index 023c38b..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/UsersCommand.java
+++ /dev/null
@@ -1,45 +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.accumulo.core.util.shell.commands;
-
-import java.io.IOException;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-
-public class UsersCommand extends Command {
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException, IOException {
-    for (String user : shellState.getConnector().securityOperations().listLocalUsers()) {
-      shellState.getReader().println(user);
-    }
-    return 0;
-  }
-  
-  @Override
-  public String description() {
-    return "displays a list of existing users";
-  }
-  
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/WhoAmICommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/WhoAmICommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/WhoAmICommand.java
deleted file mode 100644
index e7bb29d..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/WhoAmICommand.java
+++ /dev/null
@@ -1,41 +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.accumulo.core.util.shell.commands;
-
-import java.io.IOException;
-
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-
-public class WhoAmICommand extends Command {
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws IOException {
-    shellState.getReader().println(shellState.getConnector().whoami());
-    return 0;
-  }
-  
-  @Override
-  public String description() {
-    return "reports the current user name";
-  }
-  
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/test/java/org/apache/accumulo/core/util/format/DeleterFormatterTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/accumulo/core/util/format/DeleterFormatterTest.java b/core/src/test/java/org/apache/accumulo/core/util/format/DeleterFormatterTest.java
deleted file mode 100644
index 9223166..0000000
--- a/core/src/test/java/org/apache/accumulo/core/util/format/DeleterFormatterTest.java
+++ /dev/null
@@ -1,176 +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.accumulo.core.util.format;
-
-import static org.easymock.EasyMock.anyObject;
-import static org.easymock.EasyMock.createMock;
-import static org.easymock.EasyMock.createNiceMock;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.expectLastCall;
-import static org.easymock.EasyMock.replay;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.charset.StandardCharsets;
-import java.util.Collections;
-import java.util.Map;
-import java.util.TreeMap;
-
-import jline.UnsupportedTerminal;
-import jline.console.ConsoleReader;
-
-import org.apache.accumulo.core.client.BatchWriter;
-import org.apache.accumulo.core.client.MutationsRejectedException;
-import org.apache.accumulo.core.data.Key;
-import org.apache.accumulo.core.data.Mutation;
-import org.apache.accumulo.core.data.Value;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.junit.Before;
-import org.junit.Test;
-
-public class DeleterFormatterTest {
-  DeleterFormatter formatter;
-  Map<Key,Value> data;
-  BatchWriter writer;
-  BatchWriter exceptionWriter;
-  Shell shellState;
-
-  ByteArrayOutputStream baos;
-  ConsoleReader reader;
-
-  SettableInputStream input;
-
-  class SettableInputStream extends InputStream {
-    ByteArrayInputStream bais;
-
-    @Override
-    public int read() throws IOException {
-      return bais.read();
-    }
-
-    public void set(String in) {
-      bais = new ByteArrayInputStream(in.getBytes(StandardCharsets.UTF_8));
-    }
-  };
-
-  @Before
-  public void setUp() throws IOException, MutationsRejectedException {
-    input = new SettableInputStream();
-    baos = new ByteArrayOutputStream();
-
-    MutationsRejectedException mre = createMock(MutationsRejectedException.class);
-
-    writer = createNiceMock(BatchWriter.class);
-    exceptionWriter = createNiceMock(BatchWriter.class);
-    exceptionWriter.close();
-    expectLastCall().andThrow(mre);
-    exceptionWriter.addMutation(anyObject(Mutation.class));
-    expectLastCall().andThrow(mre);
-
-    shellState = createNiceMock(Shell.class);
-
-    reader = new ConsoleReader(input, baos, new UnsupportedTerminal());
-    expect(shellState.getReader()).andReturn(reader).anyTimes();
-
-    replay(writer, exceptionWriter, shellState);
-
-    data = new TreeMap<Key,Value>();
-    data.put(new Key("r", "cf", "cq"), new Value("value".getBytes(StandardCharsets.UTF_8)));
-  }
-
-  @Test
-  public void testEmpty() {
-    formatter = new DeleterFormatter(writer, Collections.<Key,Value> emptyMap().entrySet(), true, shellState, true);
-    assertFalse(formatter.hasNext());
-  }
-
-  @Test
-  public void testSingle() throws IOException {
-    formatter = new DeleterFormatter(writer, data.entrySet(), true, shellState, true);
-
-    assertTrue(formatter.hasNext());
-    assertNull(formatter.next());
-
-    verify("[DELETED]", " r ", "cf", "cq", "value");
-  }
-
-  @Test
-  public void testNo() throws IOException {
-    input.set("no\n");
-    data.put(new Key("z"), new Value("v2".getBytes(StandardCharsets.UTF_8)));
-    formatter = new DeleterFormatter(writer, data.entrySet(), true, shellState, false);
-
-    assertTrue(formatter.hasNext());
-    assertNull(formatter.next());
-
-    verify("[SKIPPED]", " r ", "cf", "cq", "value");
-
-    assertTrue(formatter.hasNext());
-  }
-
-  @Test
-  public void testNoConfirmation() throws IOException {
-    input.set("");
-    data.put(new Key("z"), new Value("v2".getBytes(StandardCharsets.UTF_8)));
-    formatter = new DeleterFormatter(writer, data.entrySet(), true, shellState, false);
-
-    assertTrue(formatter.hasNext());
-    assertNull(formatter.next());
-
-    verify("[SKIPPED]", " r ", "cf", "cq", "value");
-
-    assertFalse(formatter.hasNext());
-  }
-
-  @Test
-  public void testYes() throws IOException {
-    input.set("y\nyes\n");
-    data.put(new Key("z"), new Value("v2".getBytes(StandardCharsets.UTF_8)));
-    formatter = new DeleterFormatter(writer, data.entrySet(), true, shellState, false);
-
-    assertTrue(formatter.hasNext());
-    assertNull(formatter.next());
-    verify("[DELETED]", " r ", "cf", "cq", "value");
-
-    assertTrue(formatter.hasNext());
-    assertNull(formatter.next());
-    verify("[DELETED]", " z ", "v2");
-  }
-
-  @Test
-  public void testMutationException() {
-    formatter = new DeleterFormatter(exceptionWriter, data.entrySet(), true, shellState, true);
-
-    assertTrue(formatter.hasNext());
-    assertNull(formatter.next());
-    assertFalse(formatter.hasNext());
-  }
-
-  private void verify(String... chunks) throws IOException {
-    reader.flush();
-
-    String output = baos.toString();
-    for (String chunk : chunks) {
-      assertTrue(output.contains(chunk));
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/test/java/org/apache/accumulo/core/util/shell/PasswordConverterTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/accumulo/core/util/shell/PasswordConverterTest.java b/core/src/test/java/org/apache/accumulo/core/util/shell/PasswordConverterTest.java
deleted file mode 100644
index d1d24a6..0000000
--- a/core/src/test/java/org/apache/accumulo/core/util/shell/PasswordConverterTest.java
+++ /dev/null
@@ -1,113 +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.accumulo.core.util.shell;
-
-import static org.junit.Assert.assertEquals;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStreamWriter;
-import java.io.PipedInputStream;
-import java.io.PipedOutputStream;
-import java.util.Scanner;
-
-import org.apache.accumulo.core.util.shell.ShellOptionsJC.PasswordConverter;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-
-import com.beust.jcommander.JCommander;
-import com.beust.jcommander.Parameter;
-import com.beust.jcommander.ParameterException;
-
-public class PasswordConverterTest {
-  
-  private class Password {
-    @Parameter(names = "--password", converter = PasswordConverter.class)
-    String password;
-  }
-  
-  private String[] argv;
-  private Password password;
-  private static InputStream realIn;
-  
-  @BeforeClass
-  public static void saveIn() {
-    realIn = System.in;
-  }
-  
-  @Before
-  public void setup() throws IOException {
-    argv = new String[] {"--password", ""};
-    password = new Password();
-    
-    PipedInputStream in = new PipedInputStream();
-    PipedOutputStream out = new PipedOutputStream(in);
-    OutputStreamWriter osw = new OutputStreamWriter(out);
-    osw.write("secret");
-    osw.close();
-    
-    System.setIn(in);
-  }
-  
-  @After
-  public void teardown() {
-    System.setIn(realIn);
-  }
-  
-  @Test
-  public void testPass() {
-    String expected = String.valueOf(Math.random());
-    argv[1] = "pass:" + expected;
-    new JCommander(password, argv);
-    assertEquals(expected, password.password);
-  }
-  
-  @Test
-  public void testEnv() {
-    String name = System.getenv().keySet().iterator().next();
-    argv[1] = "env:" + name;
-    new JCommander(password, argv);
-    assertEquals(System.getenv(name), password.password);
-  }
-  
-  @Test
-  public void testFile() throws FileNotFoundException {
-    argv[1] = "file:pom.xml";
-    Scanner scan = new Scanner(new File("pom.xml"));
-    String expected = scan.nextLine();
-    scan.close();
-    new JCommander(password, argv);
-    assertEquals(expected, password.password);
-  }
-  
-  @Test(expected=ParameterException.class)
-  public void testNoFile() throws FileNotFoundException {
-    argv[1] = "file:doesnotexist";
-    new JCommander(password, argv);
-  }
-
-  @Test
-  public void testStdin() {
-    argv[1] = "stdin";
-    new JCommander(password, argv);
-    assertEquals("stdin", password.password);
-  }
-}


[46/53] [abbrv] git commit: ACCUMULO-1879 Move shell into new package and module

Posted by el...@apache.org.
ACCUMULO-1879 Move shell into new package and module


Project: http://git-wip-us.apache.org/repos/asf/accumulo/repo
Commit: http://git-wip-us.apache.org/repos/asf/accumulo/commit/066043d4
Tree: http://git-wip-us.apache.org/repos/asf/accumulo/tree/066043d4
Diff: http://git-wip-us.apache.org/repos/asf/accumulo/diff/066043d4

Branch: refs/heads/ACCUMULO-378
Commit: 066043d4257718921c229ebe55c43d02c5e37fe1
Parents: b2b985e
Author: Mike Drob <md...@cloudera.com>
Authored: Fri Apr 4 23:41:46 2014 -0700
Committer: Mike Drob <md...@cloudera.com>
Committed: Mon Apr 7 20:36:28 2014 -0400

----------------------------------------------------------------------
 core/pom.xml                                    |   19 -
 .../accumulo/core/client/mock/MockShell.java    |  142 ---
 .../core/util/format/DeleterFormatter.java      |  101 --
 .../apache/accumulo/core/util/shell/Shell.java  | 1168 ------------------
 .../core/util/shell/ShellCommandException.java  |   59 -
 .../core/util/shell/ShellCompletor.java         |  162 ---
 .../core/util/shell/ShellExtension.java         |   27 -
 .../accumulo/core/util/shell/ShellOptions.java  |   33 -
 .../core/util/shell/ShellOptionsJC.java         |  280 -----
 .../accumulo/core/util/shell/ShellUtil.java     |   60 -
 .../apache/accumulo/core/util/shell/Token.java  |  137 --
 .../core/util/shell/commands/AboutCommand.java  |   56 -
 .../commands/ActiveCompactionIterator.java      |  136 --
 .../util/shell/commands/ActiveScanIterator.java |   91 --
 .../util/shell/commands/AddAuthsCommand.java    |   82 --
 .../util/shell/commands/AddSplitsCommand.java   |   88 --
 .../shell/commands/AuthenticateCommand.java     |   66 -
 .../core/util/shell/commands/ByeCommand.java    |   19 -
 .../util/shell/commands/ClasspathCommand.java   |   55 -
 .../core/util/shell/commands/ClearCommand.java  |   52 -
 .../util/shell/commands/CloneTableCommand.java  |  102 --
 .../core/util/shell/commands/ClsCommand.java    |   19 -
 .../util/shell/commands/CompactCommand.java     |  129 --
 .../core/util/shell/commands/ConfigCommand.java |  315 -----
 .../util/shell/commands/ConstraintCommand.java  |  134 --
 .../shell/commands/CreateNamespaceCommand.java  |   99 --
 .../util/shell/commands/CreateTableCommand.java |  203 ---
 .../util/shell/commands/CreateUserCommand.java  |   76 --
 .../core/util/shell/commands/DUCommand.java     |  124 --
 .../core/util/shell/commands/DebugCommand.java  |   71 --
 .../core/util/shell/commands/DeleteCommand.java |  112 --
 .../util/shell/commands/DeleteIterCommand.java  |  114 --
 .../util/shell/commands/DeleteManyCommand.java  |   82 --
 .../shell/commands/DeleteNamespaceCommand.java  |  100 --
 .../util/shell/commands/DeleteRowsCommand.java  |   65 -
 .../shell/commands/DeleteScanIterCommand.java   |  102 --
 .../shell/commands/DeleteShellIterCommand.java  |  100 --
 .../util/shell/commands/DeleteTableCommand.java |   60 -
 .../util/shell/commands/DeleteUserCommand.java  |   19 -
 .../util/shell/commands/DropTableCommand.java   |   19 -
 .../util/shell/commands/DropUserCommand.java    |   61 -
 .../core/util/shell/commands/EGrepCommand.java  |   59 -
 .../util/shell/commands/ExecfileCommand.java    |   67 -
 .../core/util/shell/commands/ExitCommand.java   |   39 -
 .../util/shell/commands/ExportTableCommand.java |   78 --
 .../util/shell/commands/ExtensionCommand.java   |  102 --
 .../core/util/shell/commands/FateCommand.java   |  180 ---
 .../core/util/shell/commands/FlushCommand.java  |   63 -
 .../util/shell/commands/FormatterCommand.java   |   69 --
 .../util/shell/commands/GetAuthsCommand.java    |   67 -
 .../util/shell/commands/GetGroupsCommand.java   |   60 -
 .../util/shell/commands/GetSplitsCommand.java   |  155 ---
 .../core/util/shell/commands/GrantCommand.java  |  133 --
 .../core/util/shell/commands/GrepCommand.java   |  111 --
 .../core/util/shell/commands/HelpCommand.java   |  129 --
 .../core/util/shell/commands/HiddenCommand.java |   62 -
 .../util/shell/commands/HistoryCommand.java     |   82 --
 .../shell/commands/ImportDirectoryCommand.java  |   58 -
 .../util/shell/commands/ImportTableCommand.java |   51 -
 .../core/util/shell/commands/InfoCommand.java   |   19 -
 .../core/util/shell/commands/InsertCommand.java |  148 ---
 .../util/shell/commands/InterpreterCommand.java |   40 -
 .../shell/commands/ListCompactionsCommand.java  |   78 --
 .../util/shell/commands/ListIterCommand.java    |  140 ---
 .../util/shell/commands/ListScansCommand.java   |   78 --
 .../shell/commands/ListShellIterCommand.java    |  105 --
 .../core/util/shell/commands/MaxRowCommand.java |   55 -
 .../core/util/shell/commands/MergeCommand.java  |  111 --
 .../commands/NamespacePermissionsCommand.java   |   44 -
 .../util/shell/commands/NamespacesCommand.java  |   83 --
 .../util/shell/commands/NoTableCommand.java     |   40 -
 .../util/shell/commands/OfflineCommand.java     |   61 -
 .../core/util/shell/commands/OnlineCommand.java |   61 -
 .../core/util/shell/commands/OptUtil.java       |  146 ---
 .../core/util/shell/commands/PasswdCommand.java |   96 --
 .../core/util/shell/commands/PingCommand.java   |   82 --
 .../core/util/shell/commands/PingIterator.java  |   58 -
 .../util/shell/commands/QuestionCommand.java    |   24 -
 .../core/util/shell/commands/QuitCommand.java   |   19 -
 .../shell/commands/QuotedStringTokenizer.java   |  141 ---
 .../shell/commands/RenameNamespaceCommand.java  |   79 --
 .../util/shell/commands/RenameTableCommand.java |   62 -
 .../core/util/shell/commands/RevokeCommand.java |  133 --
 .../core/util/shell/commands/ScanCommand.java   |  334 -----
 .../core/util/shell/commands/ScriptCommand.java |  290 -----
 .../util/shell/commands/SetAuthsCommand.java    |   77 --
 .../util/shell/commands/SetGroupsCommand.java   |   78 --
 .../util/shell/commands/SetIterCommand.java     |  453 -------
 .../util/shell/commands/SetScanIterCommand.java |  127 --
 .../shell/commands/SetShellIterCommand.java     |  131 --
 .../ShellPluginConfigurationCommand.java        |  146 ---
 .../core/util/shell/commands/SleepCommand.java  |   46 -
 .../commands/SystemPermissionsCommand.java      |   44 -
 .../core/util/shell/commands/TableCommand.java  |   60 -
 .../util/shell/commands/TableOperation.java     |  153 ---
 .../shell/commands/TablePermissionsCommand.java |   44 -
 .../core/util/shell/commands/TablesCommand.java |  107 --
 .../core/util/shell/commands/TraceCommand.java  |  101 --
 .../core/util/shell/commands/UserCommand.java   |   71 --
 .../shell/commands/UserPermissionsCommand.java  |  106 --
 .../core/util/shell/commands/UsersCommand.java  |   45 -
 .../core/util/shell/commands/WhoAmICommand.java |   41 -
 .../core/util/format/DeleterFormatterTest.java  |  176 ---
 .../core/util/shell/PasswordConverterTest.java  |  113 --
 .../core/util/shell/ShellConfigTest.java        |   90 --
 .../core/util/shell/ShellSetInstanceTest.java   |  242 ----
 .../accumulo/core/util/shell/ShellTest.java     |  281 -----
 .../accumulo/core/util/shell/ShellUtilTest.java |   66 -
 .../shell/command/FormatterCommandTest.java     |  184 ---
 core/src/test/resources/shelltest.txt           |   16 -
 examples/simple/pom.xml                         |    4 +
 .../examples/simple/shell/DebugCommand.java     |    4 +-
 .../simple/shell/MyAppShellExtension.java       |    4 +-
 pom.xml                                         |    6 +
 server/monitor/pom.xml                          |    4 +
 .../accumulo/monitor/servlets/ShellServlet.java |    2 +-
 shell/pom.xml                                   |  123 ++
 .../java/org/apache/accumulo/shell/Shell.java   | 1168 ++++++++++++++++++
 .../accumulo/shell/ShellCommandException.java   |   59 +
 .../apache/accumulo/shell/ShellCompletor.java   |  162 +++
 .../apache/accumulo/shell/ShellExtension.java   |   27 +
 .../org/apache/accumulo/shell/ShellOptions.java |   33 +
 .../apache/accumulo/shell/ShellOptionsJC.java   |  280 +++++
 .../org/apache/accumulo/shell/ShellUtil.java    |   60 +
 .../java/org/apache/accumulo/shell/Token.java   |  137 ++
 .../accumulo/shell/commands/AboutCommand.java   |   56 +
 .../commands/ActiveCompactionIterator.java      |  136 ++
 .../shell/commands/ActiveScanIterator.java      |   91 ++
 .../shell/commands/AddAuthsCommand.java         |   82 ++
 .../shell/commands/AddSplitsCommand.java        |   88 ++
 .../shell/commands/AuthenticateCommand.java     |   66 +
 .../accumulo/shell/commands/ByeCommand.java     |   19 +
 .../shell/commands/ClasspathCommand.java        |   55 +
 .../accumulo/shell/commands/ClearCommand.java   |   52 +
 .../shell/commands/CloneTableCommand.java       |  102 ++
 .../accumulo/shell/commands/ClsCommand.java     |   19 +
 .../accumulo/shell/commands/CompactCommand.java |  129 ++
 .../accumulo/shell/commands/ConfigCommand.java  |  315 +++++
 .../shell/commands/ConstraintCommand.java       |  134 ++
 .../shell/commands/CreateNamespaceCommand.java  |   99 ++
 .../shell/commands/CreateTableCommand.java      |  203 +++
 .../shell/commands/CreateUserCommand.java       |   76 ++
 .../accumulo/shell/commands/DUCommand.java      |  124 ++
 .../accumulo/shell/commands/DebugCommand.java   |   71 ++
 .../accumulo/shell/commands/DeleteCommand.java  |  112 ++
 .../shell/commands/DeleteIterCommand.java       |  114 ++
 .../shell/commands/DeleteManyCommand.java       |   82 ++
 .../shell/commands/DeleteNamespaceCommand.java  |  100 ++
 .../shell/commands/DeleteRowsCommand.java       |   65 +
 .../shell/commands/DeleteScanIterCommand.java   |  102 ++
 .../shell/commands/DeleteShellIterCommand.java  |  100 ++
 .../shell/commands/DeleteTableCommand.java      |   60 +
 .../shell/commands/DeleteUserCommand.java       |   19 +
 .../shell/commands/DropTableCommand.java        |   19 +
 .../shell/commands/DropUserCommand.java         |   61 +
 .../accumulo/shell/commands/EGrepCommand.java   |   59 +
 .../shell/commands/ExecfileCommand.java         |   67 +
 .../accumulo/shell/commands/ExitCommand.java    |   39 +
 .../shell/commands/ExportTableCommand.java      |   78 ++
 .../shell/commands/ExtensionCommand.java        |  102 ++
 .../accumulo/shell/commands/FateCommand.java    |  180 +++
 .../accumulo/shell/commands/FlushCommand.java   |   63 +
 .../shell/commands/FormatterCommand.java        |   69 ++
 .../shell/commands/GetAuthsCommand.java         |   67 +
 .../shell/commands/GetGroupsCommand.java        |   60 +
 .../shell/commands/GetSplitsCommand.java        |  155 +++
 .../accumulo/shell/commands/GrantCommand.java   |  133 ++
 .../accumulo/shell/commands/GrepCommand.java    |  111 ++
 .../accumulo/shell/commands/HelpCommand.java    |  129 ++
 .../accumulo/shell/commands/HiddenCommand.java  |   62 +
 .../accumulo/shell/commands/HistoryCommand.java |   82 ++
 .../shell/commands/ImportDirectoryCommand.java  |   58 +
 .../shell/commands/ImportTableCommand.java      |   51 +
 .../accumulo/shell/commands/InfoCommand.java    |   19 +
 .../accumulo/shell/commands/InsertCommand.java  |  148 +++
 .../shell/commands/InterpreterCommand.java      |   40 +
 .../shell/commands/ListCompactionsCommand.java  |   78 ++
 .../shell/commands/ListIterCommand.java         |  140 +++
 .../shell/commands/ListScansCommand.java        |   78 ++
 .../shell/commands/ListShellIterCommand.java    |  105 ++
 .../accumulo/shell/commands/MaxRowCommand.java  |   55 +
 .../accumulo/shell/commands/MergeCommand.java   |  111 ++
 .../commands/NamespacePermissionsCommand.java   |   44 +
 .../shell/commands/NamespacesCommand.java       |   83 ++
 .../accumulo/shell/commands/NoTableCommand.java |   40 +
 .../accumulo/shell/commands/OfflineCommand.java |   61 +
 .../accumulo/shell/commands/OnlineCommand.java  |   61 +
 .../apache/accumulo/shell/commands/OptUtil.java |  146 +++
 .../accumulo/shell/commands/PasswdCommand.java  |   96 ++
 .../accumulo/shell/commands/PingCommand.java    |   82 ++
 .../accumulo/shell/commands/PingIterator.java   |   58 +
 .../shell/commands/QuestionCommand.java         |   24 +
 .../accumulo/shell/commands/QuitCommand.java    |   19 +
 .../shell/commands/QuotedStringTokenizer.java   |  141 +++
 .../shell/commands/RenameNamespaceCommand.java  |   79 ++
 .../shell/commands/RenameTableCommand.java      |   62 +
 .../accumulo/shell/commands/RevokeCommand.java  |  133 ++
 .../accumulo/shell/commands/ScanCommand.java    |  334 +++++
 .../accumulo/shell/commands/ScriptCommand.java  |  290 +++++
 .../shell/commands/SetAuthsCommand.java         |   77 ++
 .../shell/commands/SetGroupsCommand.java        |   78 ++
 .../accumulo/shell/commands/SetIterCommand.java |  453 +++++++
 .../shell/commands/SetScanIterCommand.java      |  127 ++
 .../shell/commands/SetShellIterCommand.java     |  131 ++
 .../ShellPluginConfigurationCommand.java        |  146 +++
 .../accumulo/shell/commands/SleepCommand.java   |   46 +
 .../commands/SystemPermissionsCommand.java      |   44 +
 .../accumulo/shell/commands/TableCommand.java   |   60 +
 .../accumulo/shell/commands/TableOperation.java |  153 +++
 .../shell/commands/TablePermissionsCommand.java |   44 +
 .../accumulo/shell/commands/TablesCommand.java  |  107 ++
 .../accumulo/shell/commands/TraceCommand.java   |  101 ++
 .../accumulo/shell/commands/UserCommand.java    |   71 ++
 .../shell/commands/UserPermissionsCommand.java  |  106 ++
 .../accumulo/shell/commands/UsersCommand.java   |   45 +
 .../accumulo/shell/commands/WhoAmICommand.java  |   41 +
 .../accumulo/shell/format/DeleterFormatter.java |  102 ++
 .../apache/accumulo/shell/mock/MockShell.java   |  143 +++
 shell/src/main/resources/.gitignore             |    0
 .../accumulo/shell/PasswordConverterTest.java   |  113 ++
 .../apache/accumulo/shell/ShellConfigTest.java  |   91 ++
 .../accumulo/shell/ShellSetInstanceTest.java    |  244 ++++
 .../org/apache/accumulo/shell/ShellTest.java    |  282 +++++
 .../apache/accumulo/shell/ShellUtilTest.java    |   67 +
 .../shell/command/FormatterCommandTest.java     |  184 +++
 .../shell/format/DeleterFormatterTest.java      |  177 +++
 shell/src/test/resources/log4j.properties       |   28 +
 shell/src/test/resources/shelltest.txt          |   16 +
 .../java/org/apache/accumulo/start/Main.java    |    2 +-
 .../org/apache/accumulo/test/ShellServerIT.java |    2 +-
 230 files changed, 12190 insertions(+), 12036 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/pom.xml
----------------------------------------------------------------------
diff --git a/core/pom.xml b/core/pom.xml
index a89846c..2572fc1 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -35,10 +35,6 @@
       <artifactId>guava</artifactId>
     </dependency>
     <dependency>
-      <groupId>commons-cli</groupId>
-      <artifactId>commons-cli</artifactId>
-    </dependency>
-    <dependency>
       <groupId>commons-codec</groupId>
       <artifactId>commons-codec</artifactId>
     </dependency>
@@ -122,21 +118,6 @@
       <scope>test</scope>
     </dependency>
     <dependency>
-      <groupId>org.powermock</groupId>
-      <artifactId>powermock-api-easymock</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.powermock</groupId>
-      <artifactId>powermock-core</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.powermock</groupId>
-      <artifactId>powermock-module-junit4</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
       <groupId>org.slf4j</groupId>
       <artifactId>slf4j-log4j12</artifactId>
       <scope>test</scope>

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/client/mock/MockShell.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/client/mock/MockShell.java b/core/src/main/java/org/apache/accumulo/core/client/mock/MockShell.java
deleted file mode 100644
index a8061f7..0000000
--- a/core/src/main/java/org/apache/accumulo/core/client/mock/MockShell.java
+++ /dev/null
@@ -1,142 +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.accumulo.core.client.mock;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.nio.charset.StandardCharsets;
-
-import jline.console.ConsoleReader;
-
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.ShellOptionsJC;
-
-/**
- * An Accumulo Shell implementation that allows a developer to attach an InputStream and Writer to the Shell for testing purposes.
- */
-public class MockShell extends Shell {
-  private static final String NEWLINE = "\n";
-  
-  protected InputStream in;
-  protected OutputStream out;
-  
-  public MockShell(InputStream in, OutputStream out) throws IOException {
-    super();
-    this.in = in;
-    this.out = out;
-  }
-  
-  public boolean config(String... args) {
-    configError = super.config(args);
-    
-    // Update the ConsoleReader with the input and output "redirected"
-    try {
-      this.reader = new ConsoleReader(in, out);
-    } catch (Exception e) {
-      printException(e);
-      configError = true;
-    }
-    
-    // Don't need this for testing purposes
-    this.reader.setHistoryEnabled(false);
-    this.reader.setPaginationEnabled(false);
-    
-    // Make the parsing from the client easier;
-    this.verbose = false;
-    return configError;
-  }
-  
-  @Override
-  protected void setInstance(ShellOptionsJC options) {
-    // We always want a MockInstance for this test
-    instance = new MockInstance();
-  }
-  
-  public int start() throws IOException {
-    if (configError)
-      return 1;
-    
-    String input;
-    if (isVerbose())
-      printInfo();
-    
-    if (execFile != null) {
-      java.util.Scanner scanner = new java.util.Scanner(execFile, StandardCharsets.UTF_8.name());
-      try {
-        while (scanner.hasNextLine() && !hasExited()) {
-          execCommand(scanner.nextLine(), true, isVerbose());
-        }
-      } finally {
-        scanner.close();
-      }
-    } else if (execCommand != null) {
-      for (String command : execCommand.split("\n")) {
-        execCommand(command, true, isVerbose());
-      }
-      return exitCode;
-    }
-    
-    while (true) {
-      if (hasExited())
-        return exitCode;
-      
-      reader.setPrompt(getDefaultPrompt());
-      input = reader.readLine();
-      if (input == null) {
-        reader.println();
-        return exitCode;
-      } // user canceled
-      
-      execCommand(input, false, false);
-    }
-  }
-  
-  /**
-   * @param in
-   *          the in to set
-   */
-  public void setConsoleInputStream(InputStream in) {
-    this.in = in;
-  }
-  
-  /**
-   * @param out
-   *          the output stream to set
-   */
-  public void setConsoleWriter(OutputStream out) {
-    this.out = out;
-  }
-  
-  /**
-   * Convenience method to create the byte-array to hand to the console
-   * 
-   * @param commands
-   *          An array of commands to run
-   * @return A byte[] input stream which can be handed to the console.
-   */
-  public static ByteArrayInputStream makeCommands(String... commands) {
-    StringBuilder sb = new StringBuilder(commands.length * 8);
-    
-    for (String command : commands) {
-      sb.append(command).append(NEWLINE);
-    }
-    
-    return new ByteArrayInputStream(sb.toString().getBytes(StandardCharsets.UTF_8));
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/format/DeleterFormatter.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/format/DeleterFormatter.java b/core/src/main/java/org/apache/accumulo/core/util/format/DeleterFormatter.java
deleted file mode 100644
index 7ac0510..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/format/DeleterFormatter.java
+++ /dev/null
@@ -1,101 +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.accumulo.core.util.format;
-
-import java.io.IOException;
-import java.util.Map.Entry;
-
-import org.apache.accumulo.core.client.BatchWriter;
-import org.apache.accumulo.core.client.MutationsRejectedException;
-import org.apache.accumulo.core.data.ConstraintViolationSummary;
-import org.apache.accumulo.core.data.Key;
-import org.apache.accumulo.core.data.Mutation;
-import org.apache.accumulo.core.data.Value;
-import org.apache.accumulo.core.security.ColumnVisibility;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.log4j.Logger;
-
-public class DeleterFormatter extends DefaultFormatter {
-  
-  private static final Logger log = Logger.getLogger(DeleterFormatter.class);
-  private BatchWriter writer;
-  private Shell shellState;
-  private boolean printTimestamps;
-  private boolean force;
-  private boolean more;
-  
-  public DeleterFormatter(BatchWriter writer, Iterable<Entry<Key,Value>> scanner, boolean printTimestamps, Shell shellState, boolean force) {
-    super.initialize(scanner, printTimestamps);
-    this.writer = writer;
-    this.shellState = shellState;
-    this.printTimestamps = printTimestamps;
-    this.force = force;
-    this.more = true;
-  }
-  
-  @Override
-  public boolean hasNext() {
-    if (!getScannerIterator().hasNext() || !more) {
-      try {
-        writer.close();
-      } catch (MutationsRejectedException e) {
-        log.error(e.toString());
-        if (Shell.isDebuggingEnabled())
-          for (ConstraintViolationSummary cvs : e.getConstraintViolationSummaries())
-            log.trace(cvs.toString());
-      }
-      return false;
-    }
-    return true;
-  }
-  
-  /**
-   * @return null, because the iteration will provide prompts and handle deletes internally.
-   */
-  @Override
-  public String next() {
-    Entry<Key,Value> next = getScannerIterator().next();
-    Key key = next.getKey();
-    Mutation m = new Mutation(key.getRow());
-    String entryStr = formatEntry(next, printTimestamps);
-    boolean delete = force;
-    try {
-      if (!force) {
-        shellState.getReader().flush();
-        String line = shellState.getReader().readLine("Delete { " + entryStr + " } ? ");
-        more = line != null;
-        delete = line != null && (line.equalsIgnoreCase("y") || line.equalsIgnoreCase("yes"));
-      }
-      if (delete) {
-        m.putDelete(key.getColumnFamily(), key.getColumnQualifier(), new ColumnVisibility(key.getColumnVisibility()), key.getTimestamp());
-        try {
-          writer.addMutation(m);
-        } catch (MutationsRejectedException e) {
-          log.error(e.toString());
-          if (Shell.isDebuggingEnabled())
-            for (ConstraintViolationSummary cvs : e.getConstraintViolationSummaries())
-              log.trace(cvs.toString());
-        }
-      }
-      shellState.getReader().print(String.format("[%s] %s%n", delete ? "DELETED" : "SKIPPED", entryStr));
-    } catch (IOException e) {
-      log.error("Cannot write to console", e);
-      throw new RuntimeException(e);
-    }
-    return null;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/Shell.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/Shell.java b/core/src/main/java/org/apache/accumulo/core/util/shell/Shell.java
deleted file mode 100644
index f481395..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/Shell.java
+++ /dev/null
@@ -1,1168 +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.accumulo.core.util.shell;
-
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.OutputStreamWriter;
-import java.io.PrintWriter;
-import java.net.InetAddress;
-import java.nio.charset.StandardCharsets;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.TreeMap;
-import java.util.UUID;
-
-import jline.console.ConsoleReader;
-import jline.console.UserInterruptException;
-import jline.console.history.FileHistory;
-
-import org.apache.accumulo.core.Constants;
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.ClientConfiguration;
-import org.apache.accumulo.core.client.ClientConfiguration.ClientProperty;
-import org.apache.accumulo.core.client.Connector;
-import org.apache.accumulo.core.client.Instance;
-import org.apache.accumulo.core.client.IteratorSetting;
-import org.apache.accumulo.core.client.TableNotFoundException;
-import org.apache.accumulo.core.client.ZooKeeperInstance;
-import org.apache.accumulo.core.client.impl.ServerConfigurationUtil;
-import org.apache.accumulo.core.client.impl.Tables;
-import org.apache.accumulo.core.client.mock.MockInstance;
-import org.apache.accumulo.core.client.security.tokens.AuthenticationToken;
-import org.apache.accumulo.core.client.security.tokens.PasswordToken;
-import org.apache.accumulo.core.conf.AccumuloConfiguration;
-import org.apache.accumulo.core.conf.DefaultConfiguration;
-import org.apache.accumulo.core.conf.Property;
-import org.apache.accumulo.core.conf.SiteConfiguration;
-import org.apache.accumulo.core.data.Key;
-import org.apache.accumulo.core.data.Value;
-import org.apache.accumulo.core.data.thrift.TConstraintViolationSummary;
-import org.apache.accumulo.core.tabletserver.thrift.ConstraintViolationException;
-import org.apache.accumulo.core.trace.DistributedTrace;
-import org.apache.accumulo.core.util.BadArgumentException;
-import org.apache.accumulo.core.util.format.BinaryFormatter;
-import org.apache.accumulo.core.util.format.DefaultFormatter;
-import org.apache.accumulo.core.util.format.Formatter;
-import org.apache.accumulo.core.util.format.FormatterFactory;
-import org.apache.accumulo.core.util.shell.commands.AboutCommand;
-import org.apache.accumulo.core.util.shell.commands.AddAuthsCommand;
-import org.apache.accumulo.core.util.shell.commands.AddSplitsCommand;
-import org.apache.accumulo.core.util.shell.commands.AuthenticateCommand;
-import org.apache.accumulo.core.util.shell.commands.ByeCommand;
-import org.apache.accumulo.core.util.shell.commands.ClasspathCommand;
-import org.apache.accumulo.core.util.shell.commands.ClearCommand;
-import org.apache.accumulo.core.util.shell.commands.CloneTableCommand;
-import org.apache.accumulo.core.util.shell.commands.ClsCommand;
-import org.apache.accumulo.core.util.shell.commands.CompactCommand;
-import org.apache.accumulo.core.util.shell.commands.ConfigCommand;
-import org.apache.accumulo.core.util.shell.commands.ConstraintCommand;
-import org.apache.accumulo.core.util.shell.commands.CreateNamespaceCommand;
-import org.apache.accumulo.core.util.shell.commands.CreateTableCommand;
-import org.apache.accumulo.core.util.shell.commands.CreateUserCommand;
-import org.apache.accumulo.core.util.shell.commands.DUCommand;
-import org.apache.accumulo.core.util.shell.commands.DebugCommand;
-import org.apache.accumulo.core.util.shell.commands.DeleteCommand;
-import org.apache.accumulo.core.util.shell.commands.DeleteIterCommand;
-import org.apache.accumulo.core.util.shell.commands.DeleteManyCommand;
-import org.apache.accumulo.core.util.shell.commands.DeleteNamespaceCommand;
-import org.apache.accumulo.core.util.shell.commands.DeleteRowsCommand;
-import org.apache.accumulo.core.util.shell.commands.DeleteScanIterCommand;
-import org.apache.accumulo.core.util.shell.commands.DeleteShellIterCommand;
-import org.apache.accumulo.core.util.shell.commands.DeleteTableCommand;
-import org.apache.accumulo.core.util.shell.commands.DeleteUserCommand;
-import org.apache.accumulo.core.util.shell.commands.DropTableCommand;
-import org.apache.accumulo.core.util.shell.commands.DropUserCommand;
-import org.apache.accumulo.core.util.shell.commands.EGrepCommand;
-import org.apache.accumulo.core.util.shell.commands.ExecfileCommand;
-import org.apache.accumulo.core.util.shell.commands.ExitCommand;
-import org.apache.accumulo.core.util.shell.commands.ExportTableCommand;
-import org.apache.accumulo.core.util.shell.commands.ExtensionCommand;
-import org.apache.accumulo.core.util.shell.commands.FateCommand;
-import org.apache.accumulo.core.util.shell.commands.FlushCommand;
-import org.apache.accumulo.core.util.shell.commands.FormatterCommand;
-import org.apache.accumulo.core.util.shell.commands.GetAuthsCommand;
-import org.apache.accumulo.core.util.shell.commands.GetGroupsCommand;
-import org.apache.accumulo.core.util.shell.commands.GetSplitsCommand;
-import org.apache.accumulo.core.util.shell.commands.GrantCommand;
-import org.apache.accumulo.core.util.shell.commands.GrepCommand;
-import org.apache.accumulo.core.util.shell.commands.HelpCommand;
-import org.apache.accumulo.core.util.shell.commands.HiddenCommand;
-import org.apache.accumulo.core.util.shell.commands.HistoryCommand;
-import org.apache.accumulo.core.util.shell.commands.ImportDirectoryCommand;
-import org.apache.accumulo.core.util.shell.commands.ImportTableCommand;
-import org.apache.accumulo.core.util.shell.commands.InfoCommand;
-import org.apache.accumulo.core.util.shell.commands.InsertCommand;
-import org.apache.accumulo.core.util.shell.commands.InterpreterCommand;
-import org.apache.accumulo.core.util.shell.commands.ListCompactionsCommand;
-import org.apache.accumulo.core.util.shell.commands.ListIterCommand;
-import org.apache.accumulo.core.util.shell.commands.ListScansCommand;
-import org.apache.accumulo.core.util.shell.commands.ListShellIterCommand;
-import org.apache.accumulo.core.util.shell.commands.MaxRowCommand;
-import org.apache.accumulo.core.util.shell.commands.MergeCommand;
-import org.apache.accumulo.core.util.shell.commands.NamespacePermissionsCommand;
-import org.apache.accumulo.core.util.shell.commands.NamespacesCommand;
-import org.apache.accumulo.core.util.shell.commands.NoTableCommand;
-import org.apache.accumulo.core.util.shell.commands.OfflineCommand;
-import org.apache.accumulo.core.util.shell.commands.OnlineCommand;
-import org.apache.accumulo.core.util.shell.commands.PasswdCommand;
-import org.apache.accumulo.core.util.shell.commands.PingCommand;
-import org.apache.accumulo.core.util.shell.commands.QuestionCommand;
-import org.apache.accumulo.core.util.shell.commands.QuitCommand;
-import org.apache.accumulo.core.util.shell.commands.QuotedStringTokenizer;
-import org.apache.accumulo.core.util.shell.commands.RenameNamespaceCommand;
-import org.apache.accumulo.core.util.shell.commands.RenameTableCommand;
-import org.apache.accumulo.core.util.shell.commands.RevokeCommand;
-import org.apache.accumulo.core.util.shell.commands.ScanCommand;
-import org.apache.accumulo.core.util.shell.commands.ScriptCommand;
-import org.apache.accumulo.core.util.shell.commands.SetAuthsCommand;
-import org.apache.accumulo.core.util.shell.commands.SetGroupsCommand;
-import org.apache.accumulo.core.util.shell.commands.SetIterCommand;
-import org.apache.accumulo.core.util.shell.commands.SetScanIterCommand;
-import org.apache.accumulo.core.util.shell.commands.SetShellIterCommand;
-import org.apache.accumulo.core.util.shell.commands.SleepCommand;
-import org.apache.accumulo.core.util.shell.commands.SystemPermissionsCommand;
-import org.apache.accumulo.core.util.shell.commands.TableCommand;
-import org.apache.accumulo.core.util.shell.commands.TablePermissionsCommand;
-import org.apache.accumulo.core.util.shell.commands.TablesCommand;
-import org.apache.accumulo.core.util.shell.commands.TraceCommand;
-import org.apache.accumulo.core.util.shell.commands.UserCommand;
-import org.apache.accumulo.core.util.shell.commands.UserPermissionsCommand;
-import org.apache.accumulo.core.util.shell.commands.UsersCommand;
-import org.apache.accumulo.core.util.shell.commands.WhoAmICommand;
-import org.apache.accumulo.core.volume.VolumeConfiguration;
-import org.apache.accumulo.core.zookeeper.ZooUtil;
-import org.apache.accumulo.fate.zookeeper.ZooReader;
-import org.apache.commons.cli.BasicParser;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.HelpFormatter;
-import org.apache.commons.cli.MissingOptionException;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-import org.apache.commons.cli.ParseException;
-import org.apache.hadoop.fs.Path;
-import org.apache.log4j.Level;
-import org.apache.log4j.Logger;
-
-import com.beust.jcommander.JCommander;
-import com.beust.jcommander.ParameterException;
-
-/**
- * A convenient console interface to perform basic accumulo functions Includes auto-complete, help, and quoted strings with escape sequences
- */
-public class Shell extends ShellOptions {
-  public static final Logger log = Logger.getLogger(Shell.class);
-  private static final Logger audit = Logger.getLogger(Shell.class.getName() + ".audit");
-
-  public static final String CHARSET = "ISO-8859-1";
-  public static final int NO_FIXED_ARG_LENGTH_CHECK = -1;
-  public static final String COMMENT_PREFIX = "#";
-  public static final String HISTORY_DIR_NAME = ".accumulo";
-  public static final String HISTORY_FILE_NAME = "shell_history.txt";
-  private static final String SHELL_DESCRIPTION = "Shell - Apache Accumulo Interactive Shell";
-
-  protected int exitCode = 0;
-  private String tableName;
-  protected Instance instance;
-  private Connector connector;
-  protected ConsoleReader reader;
-  private String principal;
-  private AuthenticationToken token;
-  private final Class<? extends Formatter> defaultFormatterClass = DefaultFormatter.class;
-  private final Class<? extends Formatter> binaryFormatterClass = BinaryFormatter.class;
-  public Map<String,List<IteratorSetting>> scanIteratorOptions = new HashMap<String,List<IteratorSetting>>();
-  public Map<String,List<IteratorSetting>> iteratorProfiles = new HashMap<String,List<IteratorSetting>>();
-
-  private Token rootToken;
-  public final Map<String,Command> commandFactory = new TreeMap<String,Command>();
-  public final Map<String,Command[]> commandGrouping = new TreeMap<String,Command[]>();
-  protected boolean configError = false;
-
-  // exit if true
-  private boolean exit = false;
-
-  // file to execute commands from
-  protected File execFile = null;
-  // single command to execute from the command line
-  protected String execCommand = null;
-  protected boolean verbose = true;
-
-  private boolean tabCompletion;
-  private boolean disableAuthTimeout;
-  private long authTimeout;
-  private long lastUserActivity = System.currentTimeMillis();
-  private boolean logErrorsToConsole = false;
-  private PrintWriter writer = null;
-  private boolean masking = false;
-
-  public Shell() throws IOException {
-    this(new ConsoleReader(), new PrintWriter(
-        new OutputStreamWriter(System.out,
-        System.getProperty("jline.WindowsTerminal.output.encoding", System.getProperty("file.encoding")))));
-  }
-
-  public Shell(ConsoleReader reader, PrintWriter writer) {
-    super();
-    this.reader = reader;
-    this.writer = writer;
-  }
-
-  // Not for client use
-  public boolean config(String... args) {
-    ShellOptionsJC options = new ShellOptionsJC();
-    JCommander jc = new JCommander();
-
-    jc.setProgramName("accumulo shell");
-    jc.addObject(options);
-    try {
-      jc.parse(args);
-    } catch (ParameterException e) {
-      configError = true;
-    }
-
-    if (options.isHelpEnabled()) {
-      configError = true;
-    }
-
-    if (!configError && options.getUnrecognizedOptions() != null) {
-      configError = true;
-      logError("Unrecognized Options: " + options.getUnrecognizedOptions().toString());
-    }
-
-    if (configError) {
-      jc.usage();
-      return true;
-    }
-
-    setDebugging(options.isDebugEnabled());
-    authTimeout = options.getAuthTimeout() * 60 * 1000; // convert minutes to milliseconds
-    disableAuthTimeout = options.isAuthTimeoutDisabled();
-
-    // get the options that were parsed
-    String user = options.getUsername();
-    String password = options.getPassword();
-
-    tabCompletion = !options.isTabCompletionDisabled();
-
-    // Use a fake (Mock), ZK, or HdfsZK Accumulo instance
-    setInstance(options);
-
-    // AuthenticationToken options
-    token = options.getAuthenticationToken();
-    Map<String,String> loginOptions = options.getTokenProperties();
-
-    // process default parameters if unspecified
-    try {
-      boolean hasToken = (token != null);
-      boolean hasTokenOptions = !loginOptions.isEmpty();
-
-      if (hasToken && password != null) {
-        throw new ParameterException("Can not supply '--pass' option with '--tokenClass' option");
-      }
-
-      Runtime.getRuntime().addShutdownHook(new Thread() {
-        @Override
-        public void run() {
-          reader.getTerminal().setEchoEnabled(true);
-        }
-      });
-
-      // Need either both a token and options, or neither, but not just one.
-      if (hasToken != hasTokenOptions) {
-        throw new ParameterException("Must supply either both or neither of '--tokenClass' and '--tokenProperty'");
-      } else if (hasToken) { // implied hasTokenOptions
-        // Fully qualified name so we don't shadow java.util.Properties
-        org.apache.accumulo.core.client.security.tokens.AuthenticationToken.Properties props;
-        // and line wrap it because the package name is so long
-        props = new org.apache.accumulo.core.client.security.tokens.AuthenticationToken.Properties();
-
-        props.putAllStrings(loginOptions);
-        token.init(props);
-      } else {
-        // Read password if the user explicitly asked for it, or didn't specify anything at all
-        if ("stdin".equals(password) || password == null) {
-          password = reader.readLine("Password: ", '*');
-        }
-
-        if (password == null) {
-          // User cancel, e.g. Ctrl-D pressed
-          throw new ParameterException("No password or token option supplied");
-        } else {
-          this.token = new PasswordToken(password);
-        }
-      }
-
-      if (!options.isFake()) {
-        ZooReader zr = new ZooReader(instance.getZooKeepers(), instance.getZooKeepersSessionTimeOut());
-        DistributedTrace.enable(instance, zr, "shell", InetAddress.getLocalHost().getHostName());
-      }
-
-      this.setTableName("");
-      this.principal = user;
-      connector = instance.getConnector(this.principal, token);
-
-    } catch (Exception e) {
-      printException(e);
-      configError = true;
-    }
-
-    // decide whether to execute commands from a file and quit
-    if (options.getExecFile() != null) {
-      execFile = options.getExecFile();
-      verbose = false;
-    } else if (options.getExecFileVerbose() != null) {
-      execFile = options.getExecFileVerbose();
-      verbose = true;
-    }
-    execCommand = options.getExecCommand();
-    if (execCommand != null) {
-      verbose = false;
-    }
-
-    rootToken = new Token();
-
-    Command[] dataCommands = {new DeleteCommand(), new DeleteManyCommand(), new DeleteRowsCommand(), new EGrepCommand(), new FormatterCommand(),
-        new InterpreterCommand(), new GrepCommand(), new ImportDirectoryCommand(), new InsertCommand(), new MaxRowCommand(), new ScanCommand()};
-    Command[] debuggingCommands = {new ClasspathCommand(), new DebugCommand(), new ListScansCommand(), new ListCompactionsCommand(), new TraceCommand(),
-        new PingCommand()};
-    Command[] execCommands = {new ExecfileCommand(), new HistoryCommand(), new ExtensionCommand(), new ScriptCommand()};
-    Command[] exitCommands = {new ByeCommand(), new ExitCommand(), new QuitCommand()};
-    Command[] helpCommands = {new AboutCommand(), new HelpCommand(), new InfoCommand(), new QuestionCommand()};
-    Command[] iteratorCommands = {new DeleteIterCommand(), new DeleteScanIterCommand(), new ListIterCommand(), new SetIterCommand(), new SetScanIterCommand(),
-        new SetShellIterCommand(), new ListShellIterCommand(), new DeleteShellIterCommand()};
-    Command[] otherCommands = {new HiddenCommand()};
-    Command[] permissionsCommands = {new GrantCommand(), new RevokeCommand(), new SystemPermissionsCommand(), new TablePermissionsCommand(),
-        new UserPermissionsCommand(), new NamespacePermissionsCommand()};
-    Command[] stateCommands = {new AuthenticateCommand(), new ClsCommand(), new ClearCommand(), new FateCommand(), new NoTableCommand(), new SleepCommand(),
-        new TableCommand(), new UserCommand(), new WhoAmICommand()};
-    Command[] tableCommands = {new CloneTableCommand(), new ConfigCommand(), new CreateTableCommand(), new DeleteTableCommand(), new DropTableCommand(),
-        new DUCommand(), new ExportTableCommand(), new ImportTableCommand(), new OfflineCommand(), new OnlineCommand(), new RenameTableCommand(),
-        new TablesCommand(), new NamespacesCommand(), new CreateNamespaceCommand(), new DeleteNamespaceCommand(), new RenameNamespaceCommand()};
-    Command[] tableControlCommands = {new AddSplitsCommand(), new CompactCommand(), new ConstraintCommand(), new FlushCommand(), new GetGroupsCommand(),
-        new GetSplitsCommand(), new MergeCommand(), new SetGroupsCommand()};
-    Command[] userCommands = {new AddAuthsCommand(), new CreateUserCommand(), new DeleteUserCommand(), new DropUserCommand(), new GetAuthsCommand(),
-        new PasswdCommand(), new SetAuthsCommand(), new UsersCommand()};
-    commandGrouping.put("-- Writing, Reading, and Removing Data --", dataCommands);
-    commandGrouping.put("-- Debugging Commands -------------------", debuggingCommands);
-    commandGrouping.put("-- Shell Execution Commands -------------", execCommands);
-    commandGrouping.put("-- Exiting Commands ---------------------", exitCommands);
-    commandGrouping.put("-- Help Commands ------------------------", helpCommands);
-    commandGrouping.put("-- Iterator Configuration ---------------", iteratorCommands);
-    commandGrouping.put("-- Permissions Administration Commands --", permissionsCommands);
-    commandGrouping.put("-- Shell State Commands -----------------", stateCommands);
-    commandGrouping.put("-- Table Administration Commands --------", tableCommands);
-    commandGrouping.put("-- Table Control Commands ---------------", tableControlCommands);
-    commandGrouping.put("-- User Administration Commands ---------", userCommands);
-
-    for (Command[] cmds : commandGrouping.values()) {
-      for (Command cmd : cmds)
-        commandFactory.put(cmd.getName(), cmd);
-    }
-    for (Command cmd : otherCommands) {
-      commandFactory.put(cmd.getName(), cmd);
-    }
-    return configError;
-  }
-
-  /**
-   * Sets the instance used by the shell based on the given options.
-   * 
-   * @param options
-   *          shell options
-   */
-  protected void setInstance(ShellOptionsJC options) {
-    // should only be one set of instance options set
-    instance = null;
-    if (options.isFake()) {
-      instance = new MockInstance("fake");
-    } else {
-      String instanceName, hosts;
-      if (options.isHdfsZooInstance()) {
-        instanceName = hosts = null;
-      } else if (options.getZooKeeperInstance().size() > 0) {
-        List<String> zkOpts = options.getZooKeeperInstance();
-        instanceName = zkOpts.get(0);
-        hosts = zkOpts.get(1);
-      } else {
-        instanceName = options.getZooKeeperInstanceName();
-        hosts = options.getZooKeeperHosts();
-      }
-      try {
-        instance = getZooInstance(instanceName, hosts, options.getClientConfiguration());
-      } catch (Exception e) {
-        throw new IllegalArgumentException("Unable to load client config from " + options.getClientConfigFile(), e);
-      }
-    }
-  }
-
-  /*
-   * Takes instanceName and keepers as separate arguments, rather than just packaged into the clientConfig, so that we can fail over to accumulo-site.xml or
-   * HDFS config if they're unspecified.
-   */
-  private static Instance getZooInstance(String instanceName, String keepers, ClientConfiguration clientConfig) {
-    UUID instanceId = null;
-    if (instanceName == null) {
-      instanceName = clientConfig.get(ClientProperty.INSTANCE_NAME);
-    }
-    if (instanceName == null || keepers == null) {
-      AccumuloConfiguration conf = SiteConfiguration.getInstance(ServerConfigurationUtil.convertClientConfig(DefaultConfiguration.getInstance(), clientConfig));
-      if (instanceName == null) {
-        Path instanceDir = new Path(VolumeConfiguration.getVolumeUris(conf)[0], "instance_id");
-        instanceId = UUID.fromString(ZooUtil.getInstanceIDFromHdfs(instanceDir, conf));
-      }
-      if (keepers == null) {
-        keepers = conf.get(Property.INSTANCE_ZK_HOST);
-      }
-    }
-    if (instanceId != null) {
-      return new ZooKeeperInstance(clientConfig.withInstance(instanceId).withZkHosts(keepers));
-    } else {
-      return new ZooKeeperInstance(clientConfig.withInstance(instanceName).withZkHosts(keepers));
-    }
-  }
-
-  public Connector getConnector() {
-    return connector;
-  }
-
-  public Instance getInstance() {
-    return instance;
-  }
-
-  public static void main(String args[]) throws IOException {
-    Shell shell = new Shell();
-    try {
-      shell.config(args);
-
-      System.exit(shell.start());
-    } finally {
-      shell.shutdown();
-    }
-  }
-
-  public int start() throws IOException {
-    if (configError)
-      return 1;
-
-    String input;
-    if (isVerbose())
-      printInfo();
-
-    String home = System.getProperty("HOME");
-    if (home == null)
-      home = System.getenv("HOME");
-    String configDir = home + "/" + HISTORY_DIR_NAME;
-    String historyPath = configDir + "/" + HISTORY_FILE_NAME;
-    File accumuloDir = new File(configDir);
-    if (!accumuloDir.exists() && !accumuloDir.mkdirs())
-      log.warn("Unable to make directory for history at " + accumuloDir);
-    try {
-      final FileHistory history = new FileHistory(new File(historyPath));
-      reader.setHistory(history);
-      // Add shutdown hook to flush file history, per jline javadocs
-      Runtime.getRuntime().addShutdownHook(new Thread() {
-        @Override
-        public void run() {
-          try {
-            history.flush();
-          } catch (IOException e) {
-            log.warn("Could not flush history to file.");
-          }
-        }
-      });
-    } catch (IOException e) {
-      log.warn("Unable to load history file at " + historyPath);
-    }
-
-    // Turn Ctrl+C into Exception instead of JVM exit
-    reader.setHandleUserInterrupt(true);
-
-    ShellCompletor userCompletor = null;
-
-    if (execFile != null) {
-      java.util.Scanner scanner = new java.util.Scanner(execFile, StandardCharsets.UTF_8.name());
-      try {
-        while (scanner.hasNextLine() && !hasExited()) {
-          execCommand(scanner.nextLine(), true, isVerbose());
-        }
-      } finally {
-        scanner.close();
-      }
-    } else if (execCommand != null) {
-      for (String command : execCommand.split("\n")) {
-        execCommand(command, true, isVerbose());
-      }
-      return exitCode;
-    }
-
-    while (true) {
-      try {
-        if (hasExited())
-          return exitCode;
-
-        // If tab completion is true we need to reset
-        if (tabCompletion) {
-          if (userCompletor != null)
-            reader.removeCompleter(userCompletor);
-
-          userCompletor = setupCompletion();
-          reader.addCompleter(userCompletor);
-        }
-
-        reader.setPrompt(getDefaultPrompt());
-        input = reader.readLine();
-        if (input == null) {
-          reader.println();
-          return exitCode;
-        } // User Canceled (Ctrl+D)
-
-        execCommand(input, disableAuthTimeout, false);
-      } catch (UserInterruptException uie) {
-        // User Cancelled (Ctrl+C)
-        reader.println();
-
-        String partialLine = uie.getPartialLine();
-        if (partialLine == null || "".equals(uie.getPartialLine().trim())) {
-          // No content, actually exit
-          return exitCode;
-        }
-      } finally {
-        reader.flush();
-      }
-    }
-  }
-
-  public void shutdown() {
-    if (reader != null) {
-      reader.shutdown();
-    }
-  }
-
-  public void printInfo() throws IOException {
-    reader.print("\n" + SHELL_DESCRIPTION + "\n" + "- \n" + "- version: " + Constants.VERSION + "\n" + "- instance name: "
-        + connector.getInstance().getInstanceName() + "\n" + "- instance id: " + connector.getInstance().getInstanceID() + "\n" + "- \n"
-        + "- type 'help' for a list of available commands\n" + "- \n");
-    reader.flush();
-  }
-
-  public void printVerboseInfo() throws IOException {
-    StringBuilder sb = new StringBuilder("-\n");
-    sb.append("- Current user: ").append(connector.whoami()).append("\n");
-    if (execFile != null)
-      sb.append("- Executing commands from: ").append(execFile).append("\n");
-    if (disableAuthTimeout)
-      sb.append("- Authorization timeout: disabled\n");
-    else
-      sb.append("- Authorization timeout: ").append(String.format("%.2fs%n", authTimeout / 1000.0));
-    sb.append("- Debug: ").append(isDebuggingEnabled() ? "on" : "off").append("\n");
-    if (!scanIteratorOptions.isEmpty()) {
-      for (Entry<String,List<IteratorSetting>> entry : scanIteratorOptions.entrySet()) {
-        sb.append("- Session scan iterators for table ").append(entry.getKey()).append(":\n");
-        for (IteratorSetting setting : entry.getValue()) {
-          sb.append("-    Iterator ").append(setting.getName()).append(" options:\n");
-          sb.append("-        ").append("iteratorPriority").append(" = ").append(setting.getPriority()).append("\n");
-          sb.append("-        ").append("iteratorClassName").append(" = ").append(setting.getIteratorClass()).append("\n");
-          for (Entry<String,String> optEntry : setting.getOptions().entrySet()) {
-            sb.append("-        ").append(optEntry.getKey()).append(" = ").append(optEntry.getValue()).append("\n");
-          }
-        }
-      }
-    }
-    sb.append("-\n");
-    reader.print(sb.toString());
-  }
-
-  public String getDefaultPrompt() {
-    return connector.whoami() + "@" + connector.getInstance().getInstanceName() + (getTableName().isEmpty() ? "" : " ") + getTableName() + "> ";
-  }
-
-  public void execCommand(String input, boolean ignoreAuthTimeout, boolean echoPrompt) throws IOException {
-    audit.log(Level.INFO, getDefaultPrompt() + input);
-    if (echoPrompt) {
-      reader.print(getDefaultPrompt());
-      reader.println(input);
-    }
-
-    if (input.startsWith(COMMENT_PREFIX)) {
-      return;
-    }
-
-    String fields[];
-    try {
-      fields = new QuotedStringTokenizer(input).getTokens();
-    } catch (BadArgumentException e) {
-      printException(e);
-      ++exitCode;
-      return;
-    }
-    if (fields.length == 0)
-      return;
-
-    String command = fields[0];
-    fields = fields.length > 1 ? Arrays.copyOfRange(fields, 1, fields.length) : new String[] {};
-
-    Command sc = null;
-    if (command.length() > 0) {
-      try {
-        // Obtain the command from the command table
-        sc = commandFactory.get(command);
-        if (sc == null) {
-          reader.println(String.format("Unknown command \"%s\".  Enter \"help\" for a list possible commands.", command));
-          reader.flush();
-          return;
-        }
-
-        if (!(sc instanceof ExitCommand) && !ignoreAuthTimeout && System.currentTimeMillis() - lastUserActivity > authTimeout) {
-          reader.println("Shell has been idle for too long. Please re-authenticate.");
-          boolean authFailed = true;
-          do {
-            String pwd = readMaskedLine("Enter current password for '" + connector.whoami() + "': ", '*');
-            if (pwd == null) {
-              reader.println();
-              return;
-            } // user canceled
-
-            try {
-              authFailed = !connector.securityOperations().authenticateUser(connector.whoami(), new PasswordToken(pwd));
-            } catch (Exception e) {
-              ++exitCode;
-              printException(e);
-            }
-
-            if (authFailed)
-              reader.print("Invalid password. ");
-          } while (authFailed);
-          lastUserActivity = System.currentTimeMillis();
-        }
-
-        // Get the options from the command on how to parse the string
-        Options parseOpts = sc.getOptionsWithHelp();
-
-        // Parse the string using the given options
-        CommandLine cl = new BasicParser().parse(parseOpts, fields);
-
-        int actualArgLen = cl.getArgs().length;
-        int expectedArgLen = sc.numArgs();
-        if (cl.hasOption(helpOption)) {
-          // Display help if asked to; otherwise execute the command
-          sc.printHelp(this);
-        } else if (expectedArgLen != NO_FIXED_ARG_LENGTH_CHECK && actualArgLen != expectedArgLen) {
-          ++exitCode;
-          // Check for valid number of fixed arguments (if not
-          // negative; negative means it is not checked, for
-          // vararg-like commands)
-          printException(new IllegalArgumentException(String.format("Expected %d argument%s. There %s %d.", expectedArgLen, expectedArgLen == 1 ? "" : "s",
-              actualArgLen == 1 ? "was" : "were", actualArgLen)));
-          sc.printHelp(this);
-        } else {
-          int tmpCode = sc.execute(input, cl, this);
-          exitCode += tmpCode;
-          reader.flush();
-        }
-
-      } catch (ConstraintViolationException e) {
-        ++exitCode;
-        printConstraintViolationException(e);
-      } catch (TableNotFoundException e) {
-        ++exitCode;
-        if (getTableName().equals(e.getTableName()))
-          setTableName("");
-        printException(e);
-      } catch (ParseException e) {
-        // not really an error if the exception is a missing required
-        // option when the user is asking for help
-        if (!(e instanceof MissingOptionException && (Arrays.asList(fields).contains("-" + helpOption) || Arrays.asList(fields).contains("--" + helpLongOption)))) {
-          ++exitCode;
-          printException(e);
-        }
-        if (sc != null)
-          sc.printHelp(this);
-      } catch (UserInterruptException e) {
-        ++exitCode;
-      } catch (Exception e) {
-        ++exitCode;
-        printException(e);
-      }
-    } else {
-      ++exitCode;
-      printException(new BadArgumentException("Unrecognized empty command", command, -1));
-    }
-    reader.flush();
-  }
-
-  /**
-   * The command tree is built in reverse so that the references are more easily linked up. There is some code in token to allow forward building of the command
-   * tree.
-   */
-  private ShellCompletor setupCompletion() {
-    rootToken = new Token();
-
-    Set<String> tableNames = null;
-    try {
-      tableNames = connector.tableOperations().list();
-    } catch (Exception e) {
-      log.debug("Unable to obtain list of tables", e);
-      tableNames = Collections.emptySet();
-    }
-
-    Set<String> userlist = null;
-    try {
-      userlist = connector.securityOperations().listLocalUsers();
-    } catch (Exception e) {
-      log.debug("Unable to obtain list of users", e);
-      userlist = Collections.emptySet();
-    }
-
-    Set<String> namespaces = null;
-    try {
-      namespaces = connector.namespaceOperations().list();
-    } catch (Exception e) {
-      log.debug("Unable to obtain list of namespaces", e);
-      namespaces = Collections.emptySet();
-    }
-
-    Map<Command.CompletionSet,Set<String>> options = new HashMap<Command.CompletionSet,Set<String>>();
-
-    Set<String> commands = new HashSet<String>();
-    for (String a : commandFactory.keySet())
-      commands.add(a);
-
-    Set<String> modifiedUserlist = new HashSet<String>();
-    Set<String> modifiedTablenames = new HashSet<String>();
-    Set<String> modifiedNamespaces = new HashSet<String>();
-
-    for (String a : tableNames)
-      modifiedTablenames.add(a.replaceAll("([\\s'\"])", "\\\\$1"));
-    for (String a : userlist)
-      modifiedUserlist.add(a.replaceAll("([\\s'\"])", "\\\\$1"));
-    for (String a : namespaces) {
-      String b = a.replaceAll("([\\s'\"])", "\\\\$1");
-      modifiedNamespaces.add(b.isEmpty() ? "\"\"" : b);
-    }
-
-    options.put(Command.CompletionSet.USERNAMES, modifiedUserlist);
-    options.put(Command.CompletionSet.TABLENAMES, modifiedTablenames);
-    options.put(Command.CompletionSet.NAMESPACES, modifiedNamespaces);
-    options.put(Command.CompletionSet.COMMANDS, commands);
-
-    for (Command[] cmdGroup : commandGrouping.values()) {
-      for (Command c : cmdGroup) {
-        c.getOptionsWithHelp(); // prep the options for the command
-        // so that the completion can
-        // include them
-        c.registerCompletion(rootToken, options);
-      }
-    }
-    return new ShellCompletor(rootToken, options);
-  }
-
-  /**
-   * The Command class represents a command to be run in the shell. It contains the methods to execute along with some methods to help tab completion, and
-   * return the command name, help, and usage.
-   */
-  public static abstract class Command {
-    // Helper methods for completion
-    public enum CompletionSet {
-      TABLENAMES, USERNAMES, COMMANDS, NAMESPACES
-    }
-
-    static Set<String> getCommandNames(Map<CompletionSet,Set<String>> objects) {
-      return objects.get(CompletionSet.COMMANDS);
-    }
-
-    static Set<String> getTableNames(Map<CompletionSet,Set<String>> objects) {
-      return objects.get(CompletionSet.TABLENAMES);
-    }
-
-    static Set<String> getUserNames(Map<CompletionSet,Set<String>> objects) {
-      return objects.get(CompletionSet.USERNAMES);
-    }
-
-    static Set<String> getNamespaces(Map<CompletionSet,Set<String>> objects) {
-      return objects.get(CompletionSet.NAMESPACES);
-    }
-
-    public void registerCompletionGeneral(Token root, Set<String> args, boolean caseSens) {
-      Token t = new Token(args);
-      t.setCaseSensitive(caseSens);
-
-      Token command = new Token(getName());
-      command.addSubcommand(t);
-
-      root.addSubcommand(command);
-    }
-
-    public void registerCompletionForTables(Token root, Map<CompletionSet,Set<String>> completionSet) {
-      registerCompletionGeneral(root, completionSet.get(CompletionSet.TABLENAMES), true);
-    }
-
-    public void registerCompletionForUsers(Token root, Map<CompletionSet,Set<String>> completionSet) {
-      registerCompletionGeneral(root, completionSet.get(CompletionSet.USERNAMES), true);
-    }
-
-    public void registerCompletionForCommands(Token root, Map<CompletionSet,Set<String>> completionSet) {
-      registerCompletionGeneral(root, completionSet.get(CompletionSet.COMMANDS), false);
-    }
-
-    public void registerCompletionForNamespaces(Token root, Map<CompletionSet,Set<String>> completionSet) {
-      registerCompletionGeneral(root, completionSet.get(CompletionSet.NAMESPACES), true);
-    }
-
-    // abstract methods to override
-    public abstract int execute(String fullCommand, CommandLine cl, Shell shellState) throws Exception;
-
-    public abstract String description();
-
-    /**
-     * If the number of arguments is not always zero (not including those arguments handled through Options), make sure to override the {@link #usage()} method.
-     * Otherwise, {@link #usage()} does need to be overridden.
-     */
-    public abstract int numArgs();
-
-    // OPTIONAL methods to override:
-
-    // the general version of getname uses reflection to get the class name
-    // and then cuts off the suffix -Command to get the name of the command
-    public String getName() {
-      String s = this.getClass().getName();
-      int st = Math.max(s.lastIndexOf('$'), s.lastIndexOf('.'));
-      int i = s.indexOf("Command");
-      return i > 0 ? s.substring(st + 1, i).toLowerCase(Locale.ENGLISH) : null;
-    }
-
-    // The general version of this method adds the name
-    // of the command to the completion tree
-    public void registerCompletion(Token root, Map<CompletionSet,Set<String>> completion_set) {
-      root.addSubcommand(new Token(getName()));
-    }
-
-    // The general version of this method uses the HelpFormatter
-    // that comes with the apache Options package to print out the help
-    public final void printHelp(Shell shellState) {
-      shellState.printHelp(usage(), "description: " + this.description(), getOptionsWithHelp());
-    }
-
-    public final void printHelp(Shell shellState, int width) {
-      shellState.printHelp(usage(), "description: " + this.description(), getOptionsWithHelp(), width);
-    }
-
-    // Get options with help
-    public final Options getOptionsWithHelp() {
-      Options opts = getOptions();
-      opts.addOption(new Option(helpOption, helpLongOption, false, "display this help"));
-      return opts;
-    }
-
-    // General usage is just the command
-    public String usage() {
-      return getName();
-    }
-
-    // General Options are empty
-    public Options getOptions() {
-      return new Options();
-    }
-  }
-
-  public interface PrintLine {
-    void print(String s);
-
-    void close();
-  }
-
-  public static class PrintShell implements PrintLine {
-    ConsoleReader reader;
-
-    public PrintShell(ConsoleReader reader) {
-      this.reader = reader;
-    }
-
-    @Override
-    public void print(String s) {
-      try {
-        reader.println(s);
-      } catch (Exception ex) {
-        throw new RuntimeException(ex);
-      }
-    }
-
-    @Override
-    public void close() {}
-  };
-
-  public static class PrintFile implements PrintLine {
-    PrintWriter writer;
-
-    public PrintFile(String filename) throws FileNotFoundException {
-      writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(filename), StandardCharsets.UTF_8)));
-    }
-
-    @Override
-    public void print(String s) {
-      writer.println(s);
-    }
-
-    @Override
-    public void close() {
-      writer.close();
-    }
-  };
-
-  public final void printLines(Iterator<String> lines, boolean paginate) throws IOException {
-    printLines(lines, paginate, null);
-  }
-
-  public final void printLines(Iterator<String> lines, boolean paginate, PrintLine out) throws IOException {
-    int linesPrinted = 0;
-    String prompt = "-- hit any key to continue or 'q' to quit --";
-    int lastPromptLength = prompt.length();
-    int termWidth = reader.getTerminal().getWidth();
-    int maxLines = reader.getTerminal().getHeight();
-
-    String peek = null;
-    while (lines.hasNext()) {
-      String nextLine = lines.next();
-      if (nextLine == null)
-        continue;
-      for (String line : nextLine.split("\\n")) {
-        if (out == null) {
-          if (peek != null) {
-            reader.println(peek);
-            if (paginate) {
-              linesPrinted += peek.length() == 0 ? 0 : Math.ceil(peek.length() * 1.0 / termWidth);
-
-              // check if displaying the next line would result in
-              // scrolling off the screen
-              if (linesPrinted + Math.ceil(lastPromptLength * 1.0 / termWidth) + Math.ceil(prompt.length() * 1.0 / termWidth)
-                  + Math.ceil(line.length() * 1.0 / termWidth) > maxLines) {
-                linesPrinted = 0;
-                int numdashes = (termWidth - prompt.length()) / 2;
-                String nextPrompt = repeat("-", numdashes) + prompt + repeat("-", numdashes);
-                lastPromptLength = nextPrompt.length();
-                reader.print(nextPrompt);
-                reader.flush();
-
-                if (Character.toUpperCase((char) reader.readCharacter()) == 'Q') {
-                  reader.println();
-                  return;
-                }
-                reader.println();
-                termWidth = reader.getTerminal().getWidth();
-                maxLines = reader.getTerminal().getHeight();
-              }
-            }
-          }
-          peek = line;
-        } else {
-          out.print(line);
-        }
-      }
-    }
-    if (out == null && peek != null) {
-      reader.println(peek);
-    }
-  }
-
-  public final void printRecords(Iterable<Entry<Key,Value>> scanner, boolean printTimestamps, boolean paginate, Class<? extends Formatter> formatterClass,
-      PrintLine outFile) throws IOException {
-    printLines(FormatterFactory.getFormatter(formatterClass, scanner, printTimestamps), paginate, outFile);
-  }
-
-  public final void printRecords(Iterable<Entry<Key,Value>> scanner, boolean printTimestamps, boolean paginate, Class<? extends Formatter> formatterClass)
-      throws IOException {
-    printLines(FormatterFactory.getFormatter(formatterClass, scanner, printTimestamps), paginate);
-  }
-
-  public final void printBinaryRecords(Iterable<Entry<Key,Value>> scanner, boolean printTimestamps, boolean paginate, PrintLine outFile) throws IOException {
-    printLines(FormatterFactory.getFormatter(binaryFormatterClass, scanner, printTimestamps), paginate, outFile);
-  }
-
-  public final void printBinaryRecords(Iterable<Entry<Key,Value>> scanner, boolean printTimestamps, boolean paginate) throws IOException {
-    printLines(FormatterFactory.getFormatter(binaryFormatterClass, scanner, printTimestamps), paginate);
-  }
-
-  public static String repeat(String s, int c) {
-    StringBuilder sb = new StringBuilder();
-    for (int i = 0; i < c; i++)
-      sb.append(s);
-    return sb.toString();
-  }
-
-  public void checkTableState() {
-    if (getTableName().isEmpty())
-      throw new IllegalStateException(
-          "Not in a table context. Please use 'table <tableName>' to switch to a table, or use '-t' to specify a table if option is available.");
-  }
-
-  private final void printConstraintViolationException(ConstraintViolationException cve) {
-    printException(cve, "");
-    int COL1 = 50, COL2 = 14;
-    int col3 = Math.max(1, Math.min(Integer.MAX_VALUE, reader.getTerminal().getWidth() - COL1 - COL2 - 6));
-    logError(String.format("%" + COL1 + "s-+-%" + COL2 + "s-+-%" + col3 + "s%n", repeat("-", COL1), repeat("-", COL2), repeat("-", col3)));
-    logError(String.format("%-" + COL1 + "s | %" + COL2 + "s | %-" + col3 + "s%n", "Constraint class", "Violation code", "Violation Description"));
-    logError(String.format("%" + COL1 + "s-+-%" + COL2 + "s-+-%" + col3 + "s%n", repeat("-", COL1), repeat("-", COL2), repeat("-", col3)));
-    for (TConstraintViolationSummary cvs : cve.violationSummaries)
-      logError(String.format("%-" + COL1 + "s | %" + COL2 + "d | %-" + col3 + "s%n", cvs.constrainClass, cvs.violationCode, cvs.violationDescription));
-    logError(String.format("%" + COL1 + "s-+-%" + COL2 + "s-+-%" + col3 + "s%n", repeat("-", COL1), repeat("-", COL2), repeat("-", col3)));
-  }
-
-  public final void printException(Exception e) {
-    printException(e, e.getMessage());
-  }
-
-  private final void printException(Exception e, String msg) {
-    logError(e.getClass().getName() + (msg != null ? ": " + msg : ""));
-    log.debug(e.getClass().getName() + (msg != null ? ": " + msg : ""), e);
-  }
-
-  public static final void setDebugging(boolean debuggingEnabled) {
-    Logger.getLogger(Constants.CORE_PACKAGE_NAME).setLevel(debuggingEnabled ? Level.TRACE : Level.INFO);
-  }
-
-  public static final boolean isDebuggingEnabled() {
-    return Logger.getLogger(Constants.CORE_PACKAGE_NAME).isTraceEnabled();
-  }
-
-  private final void printHelp(String usage, String description, Options opts) {
-    printHelp(usage, description, opts, Integer.MAX_VALUE);
-  }
-
-  private final void printHelp(String usage, String description, Options opts, int width) {
-    // TODO Use the OutputStream from the JLine ConsoleReader if we can ever get access to it
-    new HelpFormatter().printHelp(writer, width, usage, description, opts, 2, 5, null, true);
-    writer.flush();
-  }
-
-  public int getExitCode() {
-    return exitCode;
-  }
-
-  public void resetExitCode() {
-    exitCode = 0;
-  }
-
-  public void setExit(boolean exit) {
-    this.exit = exit;
-  }
-
-  public boolean getExit() {
-    return this.exit;
-  }
-
-  public boolean isVerbose() {
-    return verbose;
-  }
-
-  public void setTableName(String tableName) {
-    this.tableName = (tableName == null || tableName.isEmpty()) ? "" : Tables.qualified(tableName);
-  }
-
-  public String getTableName() {
-    return tableName;
-  }
-
-  public ConsoleReader getReader() {
-    return reader;
-  }
-
-  public void updateUser(String principal, AuthenticationToken token) throws AccumuloException, AccumuloSecurityException {
-    connector = instance.getConnector(principal, token);
-    this.principal = principal;
-    this.token = token;
-  }
-
-  public String getPrincipal() {
-    return principal;
-  }
-
-  public AuthenticationToken getToken() {
-    return token;
-  }
-
-  /**
-   * Return the formatter for the current table.
-   * 
-   * @return the formatter class for the current table
-   */
-  public Class<? extends Formatter> getFormatter() {
-    return getFormatter(this.tableName);
-  }
-
-  /**
-   * Return the formatter for the given table.
-   * 
-   * @param tableName
-   *          the table name
-   * @return the formatter class for the given table
-   */
-  public Class<? extends Formatter> getFormatter(String tableName) {
-    Class<? extends Formatter> formatter = FormatterCommand.getCurrentFormatter(tableName, this);
-
-    if (null == formatter) {
-      logError("Could not load the specified formatter. Using the DefaultFormatter");
-      return this.defaultFormatterClass;
-    } else {
-      return formatter;
-    }
-  }
-
-  public void setLogErrorsToConsole() {
-    this.logErrorsToConsole = true;
-  }
-
-  private void logError(String s) {
-    log.error(s);
-    if (logErrorsToConsole) {
-      try {
-        reader.println("ERROR: " + s);
-        reader.flush();
-      } catch (IOException e) {}
-    }
-  }
-
-  public String readMaskedLine(String prompt, Character mask) throws IOException {
-    this.masking = true;
-    String s = reader.readLine(prompt, mask);
-    this.masking = false;
-    return s;
-  }
-
-  public boolean isMasking() {
-    return masking;
-  }
-
-  public boolean hasExited() {
-    return exit;
-  }
-
-  public boolean isTabCompletion() {
-    return tabCompletion;
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/ShellCommandException.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/ShellCommandException.java b/core/src/main/java/org/apache/accumulo/core/util/shell/ShellCommandException.java
deleted file mode 100644
index 6bef379..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/ShellCommandException.java
+++ /dev/null
@@ -1,59 +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.accumulo.core.util.shell;
-
-public class ShellCommandException extends Exception {
-  private static final long serialVersionUID = 1L;
-  
-  public enum ErrorCode {
-    UNKNOWN_ERROR("Unknown error"),
-    UNSUPPORTED_LANGUAGE("Programming language used is not supported"),
-    UNRECOGNIZED_COMMAND("Command is not supported"),
-    INITIALIZATION_FAILURE("Command could not be initialized"),
-    XML_PARSING_ERROR("Failed to parse the XML file");
-    
-    private String description;
-    
-    private ErrorCode(String description) {
-      this.description = description;
-    }
-    
-    public String getDescription() {
-      return this.description;
-    }
-    
-    public String toString() {
-      return getDescription();
-    }
-  }
-  
-  private ErrorCode code;
-  private String command;
-  
-  public ShellCommandException(ErrorCode code) {
-    this(code, null);
-  }
-  
-  public ShellCommandException(ErrorCode code, String command) {
-    this.code = code;
-    this.command = command;
-  }
-  
-  public String getMessage() {
-    return code + (command != null ? " (" + command + ")" : "");
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/ShellCompletor.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/ShellCompletor.java b/core/src/main/java/org/apache/accumulo/core/util/shell/ShellCompletor.java
deleted file mode 100644
index c64e0c7..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/ShellCompletor.java
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.accumulo.core.util.shell;
-
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import jline.console.completer.Completer;
-
-import org.apache.accumulo.core.util.shell.Shell.Command.CompletionSet;
-import org.apache.accumulo.core.util.shell.commands.QuotedStringTokenizer;
-
-public class ShellCompletor implements Completer {
-
-  // private static final Logger log = Logger.getLogger(ShellCompletor.class);
-
-  Map<CompletionSet,Set<String>> options;
-  Token root = null;
-
-  public ShellCompletor() {}
-
-  public ShellCompletor(Token root) {
-    this.root = root;
-  }
-
-  public ShellCompletor(Token rootToken, Map<CompletionSet,Set<String>> options) {
-    this.root = rootToken;
-    this.options = options;
-  }
-
-  @Override
-  @SuppressWarnings({"unchecked", "rawtypes"})
-  public int complete(String buffer, int cursor, List candidates) {
-    try {
-      return _complete(buffer, cursor, candidates);
-    } catch (Exception e) {
-      candidates.add("");
-      candidates.add(e.getMessage());
-      return cursor;
-    }
-  }
-
-  private int _complete(String fullBuffer, int cursor, List<String> candidates) {
-    boolean inTableFlag = false, inUserFlag = false, inNamespaceFlag = false;
-    // Only want to grab the buffer up to the cursor because
-    // the user could be trying to tab complete in the middle
-    // of the line
-    String buffer = fullBuffer.substring(0, cursor);
-
-    Token current_command_token = root;
-    String current_string_token = null;
-    boolean end_space = buffer.endsWith(" ");
-
-    // tabbing with no text
-    if (buffer.length() == 0) {
-      candidates.addAll(root.getSubcommandNames());
-      return 0;
-    }
-
-    String prefix = "";
-
-    QuotedStringTokenizer qst = new QuotedStringTokenizer(buffer);
-
-    Iterator<String> iter = qst.iterator();
-    while (iter.hasNext()) {
-      current_string_token = iter.next();
-      current_string_token = current_string_token.replaceAll("([\\s'\"])", "\\\\$1");
-
-      if (!iter.hasNext()) {
-        // if we end in a space and that space isn't part of the last token
-        // (which would be the case at the start of a quote) OR the buffer
-        // ends with a " indicating that we need to start on the next command
-        // and not complete the current command.
-        if (end_space && !current_string_token.endsWith(" ") || buffer.endsWith("\"")) {
-          // match subcommands
-
-          // we're in a subcommand so try to match the universal
-          // option flags if we're there
-          if (current_string_token.trim().equals("-" + Shell.tableOption)) {
-            candidates.addAll(options.get(Shell.Command.CompletionSet.TABLENAMES));
-            prefix += "-" + Shell.tableOption + " ";
-          } else if (current_string_token.trim().equals("-" + Shell.userOption)) {
-            candidates.addAll(options.get(Shell.Command.CompletionSet.USERNAMES));
-            prefix += "-" + Shell.userOption + " ";
-          } else if (current_string_token.trim().equals("-" + Shell.namespaceOption)) {
-            candidates.addAll(options.get(Shell.Command.CompletionSet.NAMESPACES));
-            prefix += "-" + Shell.namespaceOption + " ";
-          } else if (current_command_token != null) {
-            Token next = current_command_token.getSubcommand(current_string_token);
-            if (next != null) {
-              current_command_token = next;
-
-              if (current_command_token.getCaseSensitive())
-                prefix += current_string_token + " ";
-              else
-                prefix += current_string_token.toUpperCase() + " ";
-
-              candidates.addAll(current_command_token.getSubcommandNames());
-            }
-          }
-          Collections.sort(candidates);
-          return (prefix.length());
-        }
-        // need to match current command
-        // if we're in -t <table>, -u <user>, or -tn <namespace> complete those
-        if (inTableFlag) {
-          for (String a : options.get(Shell.Command.CompletionSet.TABLENAMES))
-            if (a.startsWith(current_string_token))
-              candidates.add(a);
-        } else if (inUserFlag) {
-          for (String a : options.get(Shell.Command.CompletionSet.USERNAMES))
-            if (a.startsWith(current_string_token))
-              candidates.add(a);
-        } else if (inNamespaceFlag) {
-          for (String a : options.get(Shell.Command.CompletionSet.NAMESPACES))
-            if (a.startsWith(current_string_token))
-              candidates.add(a);
-        } else if (current_command_token != null)
-          candidates.addAll(current_command_token.getSubcommandNames(current_string_token));
-
-        Collections.sort(candidates);
-        return (prefix.length());
-      }
-
-      if (current_string_token.trim().equals("-" + Shell.tableOption))
-        inTableFlag = true;
-      else if (current_string_token.trim().equals("-" + Shell.userOption))
-        inUserFlag = true;
-      else if (current_string_token.trim().equals("-" + Shell.namespaceOption))
-        inNamespaceFlag = true;
-      else
-        inUserFlag = inTableFlag = inNamespaceFlag = false;
-
-      if (current_command_token != null && current_command_token.getCaseSensitive())
-        prefix += current_string_token + " ";
-      else
-        prefix += current_string_token.toUpperCase() + " ";
-
-      if (current_command_token != null && current_command_token.getSubcommandNames().contains(current_string_token))
-        current_command_token = current_command_token.getSubcommand(current_string_token);
-
-    }
-    return 0;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/ShellExtension.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/ShellExtension.java b/core/src/main/java/org/apache/accumulo/core/util/shell/ShellExtension.java
deleted file mode 100644
index 5deccef..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/ShellExtension.java
+++ /dev/null
@@ -1,27 +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.accumulo.core.util.shell;
-
-import org.apache.accumulo.core.util.shell.Shell.Command;
-
-public abstract class ShellExtension {
-    
-    public abstract String getExtensionName();
-
-    public abstract Command[] getCommands();
-    
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/ShellOptions.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/ShellOptions.java b/core/src/main/java/org/apache/accumulo/core/util/shell/ShellOptions.java
deleted file mode 100644
index 4e573ed..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/ShellOptions.java
+++ /dev/null
@@ -1,33 +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.accumulo.core.util.shell;
-
-import org.apache.commons.cli.Option;
-
-/**
- * Abstract class to encompass the Options available on the Accumulo Shell
- */
-public abstract class ShellOptions {
-  // Global options flags
-  public static final String userOption = "u";
-  public static final String tableOption = "t";
-  public static final String namespaceOption = "ns";
-  public static final String helpOption = "?";
-  public static final String helpLongOption = "help";
-
-  final Option helpOpt = new Option(helpOption, helpLongOption, false, "display this help");
-}


[53/53] [abbrv] git commit: Merge branch 'master' into ACCUMULO-378

Posted by el...@apache.org.
Merge branch 'master' into ACCUMULO-378


Project: http://git-wip-us.apache.org/repos/asf/accumulo/repo
Commit: http://git-wip-us.apache.org/repos/asf/accumulo/commit/5fd07ec0
Tree: http://git-wip-us.apache.org/repos/asf/accumulo/tree/5fd07ec0
Diff: http://git-wip-us.apache.org/repos/asf/accumulo/diff/5fd07ec0

Branch: refs/heads/ACCUMULO-378
Commit: 5fd07ec03059daa21758404de0c059a2dd5c395a
Parents: e01c8d9 1b4c49c
Author: Josh Elser <el...@apache.org>
Authored: Mon Apr 7 23:02:05 2014 -0400
Committer: Josh Elser <el...@apache.org>
Committed: Mon Apr 7 23:02:05 2014 -0400

----------------------------------------------------------------------
 README                                          |   40 +-
 assemble/build.sh                               |    8 +-
 assemble/src/main/assemblies/component.xml      |    3 +
 bin/bootstrap_config.sh                         |  321 ++++-
 conf/templates/accumulo-env.sh                  |   66 +
 conf/templates/accumulo-metrics.xml             |   60 +
 conf/templates/accumulo-site.xml                |  132 ++
 conf/templates/accumulo.policy.example          |  143 +++
 conf/templates/auditLog.xml                     |   35 +
 conf/templates/gc                               |   16 +
 conf/templates/generic_logger.xml               |   83 ++
 conf/templates/log4j.properties                 |   41 +
 conf/templates/masters                          |   16 +
 conf/templates/monitor                          |   16 +
 conf/templates/monitor_logger.xml               |   64 +
 conf/templates/slaves                           |   16 +
 conf/templates/tracers                          |   16 +
 core/pom.xml                                    |   19 -
 .../core/client/mapred/InputFormatBase.java     |    1 +
 .../client/mapreduce/AccumuloInputFormat.java   |    2 +-
 .../core/client/mapreduce/InputFormatBase.java  |    1 +
 .../accumulo/core/client/mock/MockShell.java    |  142 ---
 .../core/util/format/DeleterFormatter.java      |  101 --
 .../apache/accumulo/core/util/shell/Shell.java  | 1168 ------------------
 .../core/util/shell/ShellCommandException.java  |   59 -
 .../core/util/shell/ShellCompletor.java         |  162 ---
 .../core/util/shell/ShellExtension.java         |   27 -
 .../accumulo/core/util/shell/ShellOptions.java  |   33 -
 .../core/util/shell/ShellOptionsJC.java         |  280 -----
 .../accumulo/core/util/shell/ShellUtil.java     |   60 -
 .../apache/accumulo/core/util/shell/Token.java  |  137 --
 .../core/util/shell/commands/AboutCommand.java  |   56 -
 .../commands/ActiveCompactionIterator.java      |  136 --
 .../util/shell/commands/ActiveScanIterator.java |   91 --
 .../util/shell/commands/AddAuthsCommand.java    |   82 --
 .../util/shell/commands/AddSplitsCommand.java   |   88 --
 .../shell/commands/AuthenticateCommand.java     |   66 -
 .../core/util/shell/commands/ByeCommand.java    |   19 -
 .../util/shell/commands/ClasspathCommand.java   |   55 -
 .../core/util/shell/commands/ClearCommand.java  |   52 -
 .../util/shell/commands/CloneTableCommand.java  |  102 --
 .../core/util/shell/commands/ClsCommand.java    |   19 -
 .../util/shell/commands/CompactCommand.java     |  129 --
 .../core/util/shell/commands/ConfigCommand.java |  315 -----
 .../util/shell/commands/ConstraintCommand.java  |  134 --
 .../shell/commands/CreateNamespaceCommand.java  |   99 --
 .../util/shell/commands/CreateTableCommand.java |  203 ---
 .../util/shell/commands/CreateUserCommand.java  |   76 --
 .../core/util/shell/commands/DUCommand.java     |  124 --
 .../core/util/shell/commands/DebugCommand.java  |   71 --
 .../core/util/shell/commands/DeleteCommand.java |  112 --
 .../util/shell/commands/DeleteIterCommand.java  |  114 --
 .../util/shell/commands/DeleteManyCommand.java  |   82 --
 .../shell/commands/DeleteNamespaceCommand.java  |  100 --
 .../util/shell/commands/DeleteRowsCommand.java  |   65 -
 .../shell/commands/DeleteScanIterCommand.java   |  102 --
 .../shell/commands/DeleteShellIterCommand.java  |  100 --
 .../util/shell/commands/DeleteTableCommand.java |   60 -
 .../util/shell/commands/DeleteUserCommand.java  |   19 -
 .../util/shell/commands/DropTableCommand.java   |   19 -
 .../util/shell/commands/DropUserCommand.java    |   61 -
 .../core/util/shell/commands/EGrepCommand.java  |   59 -
 .../util/shell/commands/ExecfileCommand.java    |   67 -
 .../core/util/shell/commands/ExitCommand.java   |   39 -
 .../util/shell/commands/ExportTableCommand.java |   78 --
 .../util/shell/commands/ExtensionCommand.java   |  102 --
 .../core/util/shell/commands/FateCommand.java   |  180 ---
 .../core/util/shell/commands/FlushCommand.java  |   63 -
 .../util/shell/commands/FormatterCommand.java   |   69 --
 .../util/shell/commands/GetAuthsCommand.java    |   67 -
 .../util/shell/commands/GetGroupsCommand.java   |   60 -
 .../util/shell/commands/GetSplitsCommand.java   |  155 ---
 .../core/util/shell/commands/GrantCommand.java  |  133 --
 .../core/util/shell/commands/GrepCommand.java   |  111 --
 .../core/util/shell/commands/HelpCommand.java   |  129 --
 .../core/util/shell/commands/HiddenCommand.java |   62 -
 .../util/shell/commands/HistoryCommand.java     |   82 --
 .../shell/commands/ImportDirectoryCommand.java  |   58 -
 .../util/shell/commands/ImportTableCommand.java |   51 -
 .../core/util/shell/commands/InfoCommand.java   |   19 -
 .../core/util/shell/commands/InsertCommand.java |  148 ---
 .../util/shell/commands/InterpreterCommand.java |   40 -
 .../shell/commands/ListCompactionsCommand.java  |   78 --
 .../util/shell/commands/ListIterCommand.java    |  140 ---
 .../util/shell/commands/ListScansCommand.java   |   78 --
 .../shell/commands/ListShellIterCommand.java    |  105 --
 .../core/util/shell/commands/MaxRowCommand.java |   55 -
 .../core/util/shell/commands/MergeCommand.java  |  111 --
 .../commands/NamespacePermissionsCommand.java   |   44 -
 .../util/shell/commands/NamespacesCommand.java  |   83 --
 .../util/shell/commands/NoTableCommand.java     |   40 -
 .../util/shell/commands/OfflineCommand.java     |   61 -
 .../core/util/shell/commands/OnlineCommand.java |   61 -
 .../core/util/shell/commands/OptUtil.java       |  146 ---
 .../core/util/shell/commands/PasswdCommand.java |   96 --
 .../core/util/shell/commands/PingCommand.java   |   82 --
 .../core/util/shell/commands/PingIterator.java  |   58 -
 .../util/shell/commands/QuestionCommand.java    |   24 -
 .../core/util/shell/commands/QuitCommand.java   |   19 -
 .../shell/commands/QuotedStringTokenizer.java   |  141 ---
 .../shell/commands/RenameNamespaceCommand.java  |   79 --
 .../util/shell/commands/RenameTableCommand.java |   62 -
 .../core/util/shell/commands/RevokeCommand.java |  133 --
 .../core/util/shell/commands/ScanCommand.java   |  334 -----
 .../core/util/shell/commands/ScriptCommand.java |  290 -----
 .../util/shell/commands/SetAuthsCommand.java    |   77 --
 .../util/shell/commands/SetGroupsCommand.java   |   78 --
 .../util/shell/commands/SetIterCommand.java     |  453 -------
 .../util/shell/commands/SetScanIterCommand.java |  127 --
 .../shell/commands/SetShellIterCommand.java     |  131 --
 .../ShellPluginConfigurationCommand.java        |  146 ---
 .../core/util/shell/commands/SleepCommand.java  |   46 -
 .../commands/SystemPermissionsCommand.java      |   44 -
 .../core/util/shell/commands/TableCommand.java  |   60 -
 .../util/shell/commands/TableOperation.java     |  153 ---
 .../shell/commands/TablePermissionsCommand.java |   44 -
 .../core/util/shell/commands/TablesCommand.java |  107 --
 .../core/util/shell/commands/TraceCommand.java  |  101 --
 .../core/util/shell/commands/UserCommand.java   |   71 --
 .../shell/commands/UserPermissionsCommand.java  |  106 --
 .../core/util/shell/commands/UsersCommand.java  |   45 -
 .../core/util/shell/commands/WhoAmICommand.java |   41 -
 .../EmptySplitsAccumuloInputFormat.java         |   10 +-
 .../core/util/format/DeleterFormatterTest.java  |  176 ---
 .../core/util/shell/PasswordConverterTest.java  |  113 --
 .../core/util/shell/ShellConfigTest.java        |   90 --
 .../core/util/shell/ShellSetInstanceTest.java   |  242 ----
 .../accumulo/core/util/shell/ShellTest.java     |  281 -----
 .../accumulo/core/util/shell/ShellUtilTest.java |   66 -
 .../shell/command/FormatterCommandTest.java     |  184 ---
 core/src/test/resources/shelltest.txt           |   16 -
 .../chapters/administration.tex                 |   37 +
 examples/simple/pom.xml                         |    4 +
 .../examples/simple/shell/DebugCommand.java     |    4 +-
 .../simple/shell/MyAppShellExtension.java       |    4 +-
 fate/pom.xml                                    |    9 +
 .../org/apache/accumulo/fate/AdminUtil.java     |   14 +-
 .../java/org/apache/accumulo/fate/Fate.java     |    2 +-
 .../org/apache/accumulo/fate/ReadOnlyRepo.java  |   32 +
 .../org/apache/accumulo/fate/ReadOnlyStore.java |  111 ++
 .../apache/accumulo/fate/ReadOnlyTStore.java    |  125 ++
 .../java/org/apache/accumulo/fate/Repo.java     |    5 +-
 .../java/org/apache/accumulo/fate/TStore.java   |   78 +-
 .../apache/accumulo/fate/AgeOffStoreTest.java   |    2 +-
 .../apache/accumulo/fate/ReadOnlyStoreTest.java |   72 ++
 .../org/apache/accumulo/fate/SimpleStore.java   |    2 +-
 pom.xml                                         |    8 +-
 .../org/apache/accumulo/server/Accumulo.java    |   33 +-
 .../accumulo/server/util/MetadataTableUtil.java |    3 +
 server/gc/pom.xml                               |    5 +
 .../gc/GarbageCollectWriteAheadLogs.java        |   89 +-
 .../accumulo/gc/SimpleGarbageCollector.java     |  134 +-
 .../gc/GarbageCollectWriteAheadLogsTest.java    |  264 ++++
 .../gc/SimpleGarbageCollectorOptsTest.java      |   37 +
 .../accumulo/gc/SimpleGarbageCollectorTest.java |  146 +++
 .../accumulo/master/FateServiceHandler.java     |    2 +-
 .../java/org/apache/accumulo/master/Master.java |   77 +-
 .../apache/accumulo/master/util/FateAdmin.java  |   24 +-
 server/monitor/pom.xml                          |    4 +
 .../accumulo/monitor/servlets/ShellServlet.java |    2 +-
 .../monitor/servlets/trace/Summary.java         |   21 +-
 .../monitor/servlets/trace/SummaryTest.java     |   42 +
 shell/pom.xml                                   |  123 ++
 .../java/org/apache/accumulo/shell/Shell.java   | 1168 ++++++++++++++++++
 .../accumulo/shell/ShellCommandException.java   |   59 +
 .../apache/accumulo/shell/ShellCompletor.java   |  162 +++
 .../apache/accumulo/shell/ShellExtension.java   |   27 +
 .../org/apache/accumulo/shell/ShellOptions.java |   33 +
 .../apache/accumulo/shell/ShellOptionsJC.java   |  280 +++++
 .../org/apache/accumulo/shell/ShellUtil.java    |   60 +
 .../java/org/apache/accumulo/shell/Token.java   |  137 ++
 .../accumulo/shell/commands/AboutCommand.java   |   56 +
 .../commands/ActiveCompactionIterator.java      |  136 ++
 .../shell/commands/ActiveScanIterator.java      |   91 ++
 .../shell/commands/AddAuthsCommand.java         |   82 ++
 .../shell/commands/AddSplitsCommand.java        |   88 ++
 .../shell/commands/AuthenticateCommand.java     |   66 +
 .../accumulo/shell/commands/ByeCommand.java     |   19 +
 .../shell/commands/ClasspathCommand.java        |   55 +
 .../accumulo/shell/commands/ClearCommand.java   |   52 +
 .../shell/commands/CloneTableCommand.java       |  102 ++
 .../accumulo/shell/commands/ClsCommand.java     |   19 +
 .../accumulo/shell/commands/CompactCommand.java |  129 ++
 .../accumulo/shell/commands/ConfigCommand.java  |  315 +++++
 .../shell/commands/ConstraintCommand.java       |  134 ++
 .../shell/commands/CreateNamespaceCommand.java  |   99 ++
 .../shell/commands/CreateTableCommand.java      |  203 +++
 .../shell/commands/CreateUserCommand.java       |   76 ++
 .../accumulo/shell/commands/DUCommand.java      |  124 ++
 .../accumulo/shell/commands/DebugCommand.java   |   71 ++
 .../accumulo/shell/commands/DeleteCommand.java  |  112 ++
 .../shell/commands/DeleteIterCommand.java       |  114 ++
 .../shell/commands/DeleteManyCommand.java       |   82 ++
 .../shell/commands/DeleteNamespaceCommand.java  |  100 ++
 .../shell/commands/DeleteRowsCommand.java       |   65 +
 .../shell/commands/DeleteScanIterCommand.java   |  102 ++
 .../shell/commands/DeleteShellIterCommand.java  |  100 ++
 .../shell/commands/DeleteTableCommand.java      |   60 +
 .../shell/commands/DeleteUserCommand.java       |   19 +
 .../shell/commands/DropTableCommand.java        |   19 +
 .../shell/commands/DropUserCommand.java         |   61 +
 .../accumulo/shell/commands/EGrepCommand.java   |   59 +
 .../shell/commands/ExecfileCommand.java         |   67 +
 .../accumulo/shell/commands/ExitCommand.java    |   39 +
 .../shell/commands/ExportTableCommand.java      |   78 ++
 .../shell/commands/ExtensionCommand.java        |  102 ++
 .../accumulo/shell/commands/FateCommand.java    |  180 +++
 .../accumulo/shell/commands/FlushCommand.java   |   63 +
 .../shell/commands/FormatterCommand.java        |   69 ++
 .../shell/commands/GetAuthsCommand.java         |   67 +
 .../shell/commands/GetGroupsCommand.java        |   60 +
 .../shell/commands/GetSplitsCommand.java        |  155 +++
 .../accumulo/shell/commands/GrantCommand.java   |  133 ++
 .../accumulo/shell/commands/GrepCommand.java    |  111 ++
 .../accumulo/shell/commands/HelpCommand.java    |  129 ++
 .../accumulo/shell/commands/HiddenCommand.java  |   62 +
 .../accumulo/shell/commands/HistoryCommand.java |   82 ++
 .../shell/commands/ImportDirectoryCommand.java  |   58 +
 .../shell/commands/ImportTableCommand.java      |   51 +
 .../accumulo/shell/commands/InfoCommand.java    |   19 +
 .../accumulo/shell/commands/InsertCommand.java  |  148 +++
 .../shell/commands/InterpreterCommand.java      |   40 +
 .../shell/commands/ListCompactionsCommand.java  |   78 ++
 .../shell/commands/ListIterCommand.java         |  140 +++
 .../shell/commands/ListScansCommand.java        |   78 ++
 .../shell/commands/ListShellIterCommand.java    |  105 ++
 .../accumulo/shell/commands/MaxRowCommand.java  |   55 +
 .../accumulo/shell/commands/MergeCommand.java   |  111 ++
 .../commands/NamespacePermissionsCommand.java   |   44 +
 .../shell/commands/NamespacesCommand.java       |   83 ++
 .../accumulo/shell/commands/NoTableCommand.java |   40 +
 .../accumulo/shell/commands/OfflineCommand.java |   61 +
 .../accumulo/shell/commands/OnlineCommand.java  |   61 +
 .../apache/accumulo/shell/commands/OptUtil.java |  146 +++
 .../accumulo/shell/commands/PasswdCommand.java  |   96 ++
 .../accumulo/shell/commands/PingCommand.java    |   82 ++
 .../accumulo/shell/commands/PingIterator.java   |   58 +
 .../shell/commands/QuestionCommand.java         |   24 +
 .../accumulo/shell/commands/QuitCommand.java    |   19 +
 .../shell/commands/QuotedStringTokenizer.java   |  141 +++
 .../shell/commands/RenameNamespaceCommand.java  |   79 ++
 .../shell/commands/RenameTableCommand.java      |   62 +
 .../accumulo/shell/commands/RevokeCommand.java  |  133 ++
 .../accumulo/shell/commands/ScanCommand.java    |  334 +++++
 .../accumulo/shell/commands/ScriptCommand.java  |  290 +++++
 .../shell/commands/SetAuthsCommand.java         |   77 ++
 .../shell/commands/SetGroupsCommand.java        |   78 ++
 .../accumulo/shell/commands/SetIterCommand.java |  453 +++++++
 .../shell/commands/SetScanIterCommand.java      |  127 ++
 .../shell/commands/SetShellIterCommand.java     |  131 ++
 .../ShellPluginConfigurationCommand.java        |  146 +++
 .../accumulo/shell/commands/SleepCommand.java   |   46 +
 .../commands/SystemPermissionsCommand.java      |   44 +
 .../accumulo/shell/commands/TableCommand.java   |   60 +
 .../accumulo/shell/commands/TableOperation.java |  153 +++
 .../shell/commands/TablePermissionsCommand.java |   44 +
 .../accumulo/shell/commands/TablesCommand.java  |  107 ++
 .../accumulo/shell/commands/TraceCommand.java   |  101 ++
 .../accumulo/shell/commands/UserCommand.java    |   71 ++
 .../shell/commands/UserPermissionsCommand.java  |  106 ++
 .../accumulo/shell/commands/UsersCommand.java   |   45 +
 .../accumulo/shell/commands/WhoAmICommand.java  |   41 +
 .../accumulo/shell/format/DeleterFormatter.java |  102 ++
 .../apache/accumulo/shell/mock/MockShell.java   |  143 +++
 shell/src/main/resources/.gitignore             |    0
 .../accumulo/shell/PasswordConverterTest.java   |  113 ++
 .../apache/accumulo/shell/ShellConfigTest.java  |   91 ++
 .../accumulo/shell/ShellSetInstanceTest.java    |  244 ++++
 .../org/apache/accumulo/shell/ShellTest.java    |  282 +++++
 .../apache/accumulo/shell/ShellUtilTest.java    |   67 +
 .../shell/command/FormatterCommandTest.java     |  184 +++
 .../shell/format/DeleterFormatterTest.java      |  177 +++
 shell/src/test/resources/log4j.properties       |   28 +
 shell/src/test/resources/shelltest.txt          |   16 +
 .../java/org/apache/accumulo/start/Main.java    |    2 +-
 .../org/apache/accumulo/test/ShellServerIT.java |    2 +-
 276 files changed, 14442 insertions(+), 12242 deletions(-)
----------------------------------------------------------------------



[23/53] [abbrv] Revert "ACCUMULO-1897 Move shell into new package and module"

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/ImportDirectoryCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/ImportDirectoryCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/ImportDirectoryCommand.java
deleted file mode 100644
index 56c27c2..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/ImportDirectoryCommand.java
+++ /dev/null
@@ -1,58 +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.accumulo.shell.commands;
-
-import java.io.IOException;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.TableNotFoundException;
-import org.apache.accumulo.shell.Shell;
-import org.apache.accumulo.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-
-public class ImportDirectoryCommand extends Command {
-  
-  @Override
-  public String description() {
-    return "bulk imports an entire directory of data files to the current table.  The boolean argument determines if accumulo sets the time.";
-  }
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws IOException, AccumuloException, AccumuloSecurityException,
-      TableNotFoundException {
-    shellState.checkTableState();
-    
-    String dir = cl.getArgs()[0];
-    String failureDir = cl.getArgs()[1];
-    final boolean setTime = Boolean.parseBoolean(cl.getArgs()[2]);
-
-    shellState.getConnector().tableOperations().importDirectory(shellState.getTableName(), dir, failureDir, setTime);
-    return 0;
-  }
-  
-  @Override
-  public int numArgs() {
-    return 3;
-  }
-  
-  @Override
-  public String usage() {
-    return getName() + " <directory> <failureDirectory> true|false";
-  }
-  
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/ImportTableCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/ImportTableCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/ImportTableCommand.java
deleted file mode 100644
index 46c941f..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/ImportTableCommand.java
+++ /dev/null
@@ -1,51 +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.accumulo.shell.commands;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.TableExistsException;
-import org.apache.accumulo.core.client.TableNotFoundException;
-import org.apache.accumulo.shell.Shell;
-import org.apache.accumulo.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-
-public class ImportTableCommand extends Command {
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException, TableNotFoundException,
-      TableExistsException {
-    
-    shellState.getConnector().tableOperations().importTable(cl.getArgs()[0], cl.getArgs()[1]);
-    return 0;
-  }
-  
-  @Override
-  public String usage() {
-    return getName() + " <table name> <import dir>";
-  }
-  
-  @Override
-  public String description() {
-    return "imports a table";
-  }
-  
-  @Override
-  public int numArgs() {
-    return 2;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/InfoCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/InfoCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/InfoCommand.java
deleted file mode 100644
index df5cfbb..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/InfoCommand.java
+++ /dev/null
@@ -1,19 +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.accumulo.shell.commands;
-
-public class InfoCommand extends AboutCommand {}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/InsertCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/InsertCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/InsertCommand.java
deleted file mode 100644
index 19ae5b8..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/InsertCommand.java
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.accumulo.shell.commands;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.concurrent.TimeUnit;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.BatchWriter;
-import org.apache.accumulo.core.client.BatchWriterConfig;
-import org.apache.accumulo.core.client.MutationsRejectedException;
-import org.apache.accumulo.core.client.TableNotFoundException;
-import org.apache.accumulo.core.client.security.SecurityErrorCode;
-import org.apache.accumulo.core.conf.AccumuloConfiguration;
-import org.apache.accumulo.core.data.ConstraintViolationSummary;
-import org.apache.accumulo.core.data.KeyExtent;
-import org.apache.accumulo.core.data.Mutation;
-import org.apache.accumulo.core.data.Value;
-import org.apache.accumulo.core.security.ColumnVisibility;
-import org.apache.accumulo.core.tabletserver.thrift.ConstraintViolationException;
-import org.apache.accumulo.shell.Shell;
-import org.apache.accumulo.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-import org.apache.hadoop.io.Text;
-
-public class InsertCommand extends Command {
-  private Option insertOptAuths, timestampOpt;
-  private Option timeoutOption;
-  
-  protected long getTimeout(final CommandLine cl) {
-    if (cl.hasOption(timeoutOption.getLongOpt())) {
-      return AccumuloConfiguration.getTimeInMillis(cl.getOptionValue(timeoutOption.getLongOpt()));
-    }
-    
-    return Long.MAX_VALUE;
-  }
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException,
-      TableNotFoundException, IOException, ConstraintViolationException {
-    shellState.checkTableState();
-    
-    final Mutation m = new Mutation(new Text(cl.getArgs()[0].getBytes(Shell.CHARSET)));
-    final Text colf = new Text(cl.getArgs()[1].getBytes(Shell.CHARSET));
-    final Text colq = new Text(cl.getArgs()[2].getBytes(Shell.CHARSET));
-    final Value val = new Value(cl.getArgs()[3].getBytes(Shell.CHARSET));
-    
-    if (cl.hasOption(insertOptAuths.getOpt())) {
-      final ColumnVisibility le = new ColumnVisibility(cl.getOptionValue(insertOptAuths.getOpt()));
-      Shell.log.debug("Authorization label will be set to: " + le.toString());
-      
-      if (cl.hasOption(timestampOpt.getOpt()))
-        m.put(colf, colq, le, Long.parseLong(cl.getOptionValue(timestampOpt.getOpt())), val);
-      else
-        m.put(colf, colq, le, val);
-    } else if (cl.hasOption(timestampOpt.getOpt()))
-      m.put(colf, colq, Long.parseLong(cl.getOptionValue(timestampOpt.getOpt())), val);
-    else
-      m.put(colf, colq, val);
-    
-    final BatchWriter bw = shellState.getConnector().createBatchWriter(shellState.getTableName(),
-        new BatchWriterConfig().setMaxMemory(Math.max(m.estimatedMemoryUsed(), 1024)).setMaxWriteThreads(1).setTimeout(getTimeout(cl), TimeUnit.MILLISECONDS));
-    bw.addMutation(m);
-    try {
-      bw.close();
-    } catch (MutationsRejectedException e) {
-      final ArrayList<String> lines = new ArrayList<String>();
-      if (e.getAuthorizationFailuresMap().isEmpty() == false) {
-        lines.add("	Authorization Failures:");
-      }
-      for (Entry<KeyExtent,Set<SecurityErrorCode>> entry : e.getAuthorizationFailuresMap().entrySet()) {
-        lines.add("		" + entry);
-      }
-      if (e.getConstraintViolationSummaries().isEmpty() == false) {
-        lines.add("	Constraint Failures:");
-      }
-      for (ConstraintViolationSummary cvs : e.getConstraintViolationSummaries()) {
-        lines.add("		" + cvs.toString());
-      }
-      
-      if (lines.size() == 0 || e.getUnknownExceptions() > 0) {
-        // must always print something
-        lines.add(" " + e.getClass().getName() + " : " + e.getMessage());
-        if (e.getCause() != null)
-          lines.add("   Caused by : " + e.getCause().getClass().getName() + " : " + e.getCause().getMessage());
-      }
-      
-      shellState.printLines(lines.iterator(), false);
-      
-      return 1;
-    }
-    return 0;
-  }
-  
-  @Override
-  public String description() {
-    return "inserts a record";
-  }
-  
-  @Override
-  public String usage() {
-    return getName() + " <row> <colfamily> <colqualifier> <value>";
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-    insertOptAuths = new Option("l", "visibility-label", true, "formatted visibility");
-    insertOptAuths.setArgName("expression");
-    o.addOption(insertOptAuths);
-    
-    timestampOpt = new Option("ts", "timestamp", true, "timestamp to use for insert");
-    timestampOpt.setArgName("timestamp");
-    o.addOption(timestampOpt);
-    
-    timeoutOption = new Option(null, "timeout", true,
-        "time before insert should fail if no data is written. If no unit is given assumes seconds.  Units d,h,m,s,and ms are supported.  e.g. 30s or 100ms");
-    timeoutOption.setArgName("timeout");
-    o.addOption(timeoutOption);
-    
-    return o;
-  }
-  
-  @Override
-  public int numArgs() {
-    return 4;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/InterpreterCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/InterpreterCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/InterpreterCommand.java
deleted file mode 100644
index 9d79601..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/InterpreterCommand.java
+++ /dev/null
@@ -1,40 +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.accumulo.shell.commands;
-
-import org.apache.accumulo.core.conf.Property;
-import org.apache.accumulo.core.util.interpret.ScanInterpreter;
-import org.apache.accumulo.shell.Shell;
-
-/**
- * 
- */
-public class InterpreterCommand extends ShellPluginConfigurationCommand {
-  
-  public InterpreterCommand() {
-    super("interpreter", Property.TABLE_INTERPRETER_CLASS, "i");
-  }
-  
-  @Override
-  public String description() {
-    return "specifies a scan interpreter to interpret scan range and column arguments";
-  }
-  
-  public static Class<? extends ScanInterpreter> getCurrentInterpreter(final String tableName, final Shell shellState) {
-    return ShellPluginConfigurationCommand.getPluginClass(tableName, shellState, ScanInterpreter.class, Property.TABLE_INTERPRETER_CLASS);
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/ListCompactionsCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/ListCompactionsCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/ListCompactionsCommand.java
deleted file mode 100644
index 809ef8c..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/ListCompactionsCommand.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.accumulo.shell.commands;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.accumulo.core.client.admin.InstanceOperations;
-import org.apache.accumulo.shell.Shell;
-import org.apache.accumulo.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-
-public class ListCompactionsCommand extends Command {
-  
-  private Option tserverOption, disablePaginationOpt;
-  
-  @Override
-  public String description() {
-    return "lists what compactions are currently running in accumulo. See the accumulo.core.client.admin.ActiveCompaciton javadoc for more information about columns.";
-  }
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    
-    List<String> tservers;
-    
-    final InstanceOperations instanceOps = shellState.getConnector().instanceOperations();
-    
-    final boolean paginate = !cl.hasOption(disablePaginationOpt.getOpt());
-    
-    if (cl.hasOption(tserverOption.getOpt())) {
-      tservers = new ArrayList<String>();
-      tservers.add(cl.getOptionValue(tserverOption.getOpt()));
-    } else {
-      tservers = instanceOps.getTabletServers();
-    }
-    
-    shellState.printLines(new ActiveCompactionIterator(tservers, instanceOps), paginate);
-    
-    return 0;
-  }
-  
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options opts = new Options();
-    
-    tserverOption = new Option("ts", "tabletServer", true, "tablet server to list compactions for");
-    tserverOption.setArgName("tablet server");
-    opts.addOption(tserverOption);
-    
-    disablePaginationOpt = new Option("np", "no-pagination", false, "disable pagination of output");
-    opts.addOption(disablePaginationOpt);
-    
-    return opts;
-  }
-  
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/ListIterCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/ListIterCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/ListIterCommand.java
deleted file mode 100644
index fcebd1f..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/ListIterCommand.java
+++ /dev/null
@@ -1,140 +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.accumulo.shell.commands;
-
-import java.util.EnumMap;
-import java.util.EnumSet;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-
-import org.apache.accumulo.core.client.IteratorSetting;
-import org.apache.accumulo.core.iterators.IteratorUtil.IteratorScope;
-import org.apache.accumulo.shell.Shell;
-import org.apache.accumulo.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.OptionGroup;
-import org.apache.commons.cli.Options;
-
-public class ListIterCommand extends Command {
-  private Option nameOpt, allScopesOpt;
-  private Map<IteratorScope,Option> scopeOpts;
-
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-
-    boolean tables = cl.hasOption(OptUtil.tableOpt().getOpt()) || !shellState.getTableName().isEmpty();
-    boolean namespaces = cl.hasOption(OptUtil.namespaceOpt().getOpt());
-
-    final Map<String,EnumSet<IteratorScope>> iterators;
-    if (namespaces) {
-      iterators = shellState.getConnector().namespaceOperations().listIterators(OptUtil.getNamespaceOpt(cl, shellState));
-    } else if (tables) {
-      iterators = shellState.getConnector().tableOperations().listIterators(OptUtil.getTableOpt(cl, shellState));
-    } else {
-      throw new IllegalArgumentException("No table or namespace specified");
-    }
-
-    if (cl.hasOption(nameOpt.getOpt())) {
-      final String name = cl.getOptionValue(nameOpt.getOpt());
-      if (!iterators.containsKey(name)) {
-        Shell.log.warn("no iterators found that match your criteria");
-        return 0;
-      }
-      final EnumSet<IteratorScope> scopes = iterators.get(name);
-      iterators.clear();
-      iterators.put(name, scopes);
-    }
-
-    final boolean allScopes = cl.hasOption(allScopesOpt.getOpt());
-    Set<IteratorScope> desiredScopes = new HashSet<IteratorScope>();
-    for (IteratorScope scope : IteratorScope.values()) {
-      if (allScopes || cl.hasOption(scopeOpts.get(scope).getOpt()))
-        desiredScopes.add(scope);
-    }
-    if (desiredScopes.isEmpty()) {
-      throw new IllegalArgumentException("You must select at least one scope to configure");
-    }
-    final StringBuilder sb = new StringBuilder("-\n");
-    for (Entry<String,EnumSet<IteratorScope>> entry : iterators.entrySet()) {
-      final String name = entry.getKey();
-      final EnumSet<IteratorScope> scopes = entry.getValue();
-      for (IteratorScope scope : scopes) {
-        if (desiredScopes.contains(scope)) {
-          IteratorSetting setting;
-          if (namespaces) {
-            setting = shellState.getConnector().namespaceOperations().getIteratorSetting(OptUtil.getNamespaceOpt(cl, shellState), name, scope);
-          } else if (tables) {
-            setting = shellState.getConnector().tableOperations().getIteratorSetting(OptUtil.getTableOpt(cl, shellState), name, scope);
-          } else {
-            throw new IllegalArgumentException("No table or namespace specified");
-          }
-          sb.append("-    Iterator ").append(setting.getName()).append(", ").append(scope).append(" scope options:\n");
-          sb.append("-        ").append("iteratorPriority").append(" = ").append(setting.getPriority()).append("\n");
-          sb.append("-        ").append("iteratorClassName").append(" = ").append(setting.getIteratorClass()).append("\n");
-          for (Entry<String,String> optEntry : setting.getOptions().entrySet()) {
-            sb.append("-        ").append(optEntry.getKey()).append(" = ").append(optEntry.getValue()).append("\n");
-          }
-        }
-      }
-    }
-    sb.append("-");
-    shellState.getReader().println(sb.toString());
-
-    return 0;
-  }
-
-  @Override
-  public String description() {
-    return "lists table-specific or namespace-specific iterators configured in this shell session";
-  }
-
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-
-    nameOpt = new Option("n", "name", true, "iterator to list");
-    nameOpt.setArgName("itername");
-
-    allScopesOpt = new Option("all", "all-scopes", false, "list from all scopes");
-    o.addOption(allScopesOpt);
-    
-    scopeOpts = new EnumMap<IteratorScope,Option>(IteratorScope.class);
-    scopeOpts.put(IteratorScope.minc, new Option(IteratorScope.minc.name(), "minor-compaction", false, "list iterator for minor compaction scope"));
-    scopeOpts.put(IteratorScope.majc, new Option(IteratorScope.majc.name(), "major-compaction", false, "list iterator for major compaction scope"));
-    scopeOpts.put(IteratorScope.scan, new Option(IteratorScope.scan.name(), "scan-time", false, "list iterator for scan scope"));
-
-    OptionGroup grp = new OptionGroup();
-    grp.addOption(OptUtil.tableOpt("table to list the configured iterators on"));
-    grp.addOption(OptUtil.namespaceOpt("namespace to list the configured iterators on"));
-    o.addOptionGroup(grp);
-    o.addOption(nameOpt);
-
-    for (Option opt : scopeOpts.values()) {
-      o.addOption(opt);
-    }
-
-    return o;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/ListScansCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/ListScansCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/ListScansCommand.java
deleted file mode 100644
index 598503e..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/ListScansCommand.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.accumulo.shell.commands;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.accumulo.core.client.admin.InstanceOperations;
-import org.apache.accumulo.shell.Shell;
-import org.apache.accumulo.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-
-public class ListScansCommand extends Command {
-  
-  private Option tserverOption, disablePaginationOpt;
-  
-  @Override
-  public String description() {
-    return "lists what scans are currently running in accumulo. See the accumulo.core.client.admin.ActiveScan javadoc for more information about columns.";
-  }
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    
-    List<String> tservers;
-    
-    final InstanceOperations instanceOps = shellState.getConnector().instanceOperations();
-    
-    final boolean paginate = !cl.hasOption(disablePaginationOpt.getOpt());
-    
-    if (cl.hasOption(tserverOption.getOpt())) {
-      tservers = new ArrayList<String>();
-      tservers.add(cl.getOptionValue(tserverOption.getOpt()));
-    } else {
-      tservers = instanceOps.getTabletServers();
-    }
-    
-    shellState.printLines(new ActiveScanIterator(tservers, instanceOps), paginate);
-    
-    return 0;
-  }
-  
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options opts = new Options();
-    
-    tserverOption = new Option("ts", "tabletServer", true, "tablet server to list scans for");
-    tserverOption.setArgName("tablet server");
-    opts.addOption(tserverOption);
-    
-    disablePaginationOpt = new Option("np", "no-pagination", false, "disable pagination of output");
-    opts.addOption(disablePaginationOpt);
-    
-    return opts;
-  }
-  
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/ListShellIterCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/ListShellIterCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/ListShellIterCommand.java
deleted file mode 100644
index 59f8f46..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/ListShellIterCommand.java
+++ /dev/null
@@ -1,105 +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.accumulo.shell.commands;
-
-import java.util.List;
-import java.util.Map.Entry;
-import java.util.Set;
-
-import org.apache.accumulo.core.client.IteratorSetting;
-import org.apache.accumulo.shell.Shell;
-import org.apache.accumulo.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-
-/**
- * 
- */
-public class ListShellIterCommand extends Command {
-  
-  private Option nameOpt, profileOpt;
-
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    if (shellState.iteratorProfiles.size() == 0)
-      return 0;
-    
-    final StringBuilder sb = new StringBuilder();
-
-    String profile = null;
-    if (cl.hasOption(profileOpt.getOpt()))
-      profile = cl.getOptionValue(profileOpt.getOpt());
-
-    String name = null;
-    if (cl.hasOption(nameOpt.getOpt()))
-      name = cl.getOptionValue(nameOpt.getOpt());
-
-    Set<Entry<String,List<IteratorSetting>>> es = shellState.iteratorProfiles.entrySet();
-    for (Entry<String,List<IteratorSetting>> entry : es) {
-      if (profile != null && !profile.equals(entry.getKey()))
-        continue;
-
-      sb.append("-\n");
-      sb.append("- Profile : " + entry.getKey() + "\n");
-      for (IteratorSetting setting : entry.getValue()) {
-        if (name != null && !name.equals(setting.getName()))
-          continue;
-
-        sb.append("-    Iterator ").append(setting.getName()).append(", ").append(" options:\n");
-        sb.append("-        ").append("iteratorPriority").append(" = ").append(setting.getPriority()).append("\n");
-        sb.append("-        ").append("iteratorClassName").append(" = ").append(setting.getIteratorClass()).append("\n");
-        for (Entry<String,String> optEntry : setting.getOptions().entrySet()) {
-          sb.append("-        ").append(optEntry.getKey()).append(" = ").append(optEntry.getValue()).append("\n");
-        }
-      }
-    }
-    
-    if (sb.length() > 0) {
-      sb.append("-\n");
-    }
-
-    shellState.getReader().print(sb.toString());
-
-    return 0;
-  }
-  
-  public String description() {
-    return "lists iterators profiles configured in shell";
-  }
-  
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-    
-    profileOpt = new Option("pn", "profile", true, "iterator profile name");
-    profileOpt.setArgName("profile");
-
-    nameOpt = new Option("n", "name", true, "iterator to list");
-    nameOpt.setArgName("itername");
-    
-    o.addOption(profileOpt);
-    o.addOption(nameOpt);
-
-    return o;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/MaxRowCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/MaxRowCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/MaxRowCommand.java
deleted file mode 100644
index 1794b57..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/MaxRowCommand.java
+++ /dev/null
@@ -1,55 +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.accumulo.shell.commands;
-
-import org.apache.accumulo.core.data.Range;
-import org.apache.accumulo.core.security.Authorizations;
-import org.apache.accumulo.core.util.interpret.ScanInterpreter;
-import org.apache.accumulo.shell.Shell;
-import org.apache.commons.cli.CommandLine;
-import org.apache.hadoop.io.Text;
-
-public class MaxRowCommand extends ScanCommand {
-  
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    final String tableName = OptUtil.getTableOpt(cl, shellState);
-    
-    final ScanInterpreter interpeter = getInterpreter(cl, tableName, shellState);
-    
-    final Range range = getRange(cl, interpeter);
-    final Authorizations auths = getAuths(cl, shellState);
-    final Text startRow = range.getStartKey() == null ? null : range.getStartKey().getRow();
-    final Text endRow = range.getEndKey() == null ? null : range.getEndKey().getRow();
-    
-    try {
-      final Text max = shellState.getConnector().tableOperations()
-          .getMaxRow(tableName, auths, startRow, range.isStartKeyInclusive(), endRow, range.isEndKeyInclusive());
-      if (max != null) {
-        shellState.getReader().println(max.toString());
-      }
-    } catch (Exception e) {
-      e.printStackTrace();
-    }
-    
-    return 0;
-  }
-  
-  @Override
-  public String description() {
-    return "finds the max row in a table within a given range";
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/MergeCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/MergeCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/MergeCommand.java
deleted file mode 100644
index 33d63fa..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/MergeCommand.java
+++ /dev/null
@@ -1,111 +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.accumulo.shell.commands;
-
-import java.io.IOException;
-
-import org.apache.accumulo.core.conf.AccumuloConfiguration;
-import org.apache.accumulo.core.util.Merge;
-import org.apache.accumulo.shell.Shell;
-import org.apache.accumulo.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-import org.apache.hadoop.io.Text;
-
-public class MergeCommand extends Command {
-  private Option verboseOpt, forceOpt, sizeOpt, allOpt;
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    boolean verbose = shellState.isVerbose();
-    boolean force = false;
-    boolean all = false;
-    long size = -1;
-    final String tableName = OptUtil.getTableOpt(cl, shellState);
-    final Text startRow = OptUtil.getStartRow(cl);
-    final Text endRow = OptUtil.getEndRow(cl);
-    if (cl.hasOption(verboseOpt.getOpt())) {
-      verbose = true;
-    }
-    if (cl.hasOption(forceOpt.getOpt())) {
-      force = true;
-    }
-    if (cl.hasOption(allOpt.getOpt())) {
-      all = true;
-    }
-    if (cl.hasOption(sizeOpt.getOpt())) {
-      size = AccumuloConfiguration.getMemoryInBytes(cl.getOptionValue(sizeOpt.getOpt()));
-    }
-    if (startRow == null && endRow == null && size < 0 && !all) {
-      shellState.getReader().flush();
-      String line = shellState.getReader().readLine("Merge the entire table { " + tableName + " } into one tablet (yes|no)? ");
-      if (line == null)
-        return 0;
-      if (!line.equalsIgnoreCase("y") && !line.equalsIgnoreCase("yes"))
-        return 0;
-    }
-    if (size < 0) {
-      shellState.getConnector().tableOperations().merge(tableName, startRow, endRow);
-    } else {
-      final boolean finalVerbose = verbose;
-      final Merge merge = new Merge() {
-        protected void message(String fmt, Object... args) {
-          if (finalVerbose) {
-            try {
-              shellState.getReader().println(String.format(fmt, args));
-            } catch (IOException ex) {
-              throw new RuntimeException(ex);
-            }
-          }
-        }
-      };
-      merge.mergomatic(shellState.getConnector(), tableName, startRow, endRow, size, force);
-    }
-    return 0;
-  }
-  
-  @Override
-  public String description() {
-    return "merges tablets in a table";
-  }
-  
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-    verboseOpt = new Option("v", "verbose", false, "verbose output during merge");
-    sizeOpt = new Option("s", "size", true, "merge tablets to the given size over the entire table");
-    forceOpt = new Option("f", "force", false, "merge small tablets to large tablets, even if it goes over the given size");
-    allOpt = new Option("", "all", false, "allow an entire table to be merged into one tablet without prompting the user for confirmation");
-    Option startRowOpt = OptUtil.startRowOpt();
-    startRowOpt.setDescription("begin row (NOT inclusive)");
-    o.addOption(startRowOpt);
-    o.addOption(OptUtil.endRowOpt());
-    o.addOption(OptUtil.tableOpt("table to be merged"));
-    o.addOption(verboseOpt);
-    o.addOption(sizeOpt);
-    o.addOption(forceOpt);
-    o.addOption(allOpt);
-    return o;
-  }
-  
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/NamespacePermissionsCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/NamespacePermissionsCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/NamespacePermissionsCommand.java
deleted file mode 100644
index 99ba6ad..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/NamespacePermissionsCommand.java
+++ /dev/null
@@ -1,44 +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.accumulo.shell.commands;
-
-import java.io.IOException;
-
-import org.apache.accumulo.core.security.NamespacePermission;
-import org.apache.accumulo.shell.Shell;
-import org.apache.accumulo.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-
-public class NamespacePermissionsCommand extends Command {
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws IOException {
-    for (String p : NamespacePermission.printableValues()) {
-      shellState.getReader().println(p);
-    }
-    return 0;
-  }
-
-  @Override
-  public String description() {
-    return "displays a list of valid namespace permissions";
-  }
-
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/NamespacesCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/NamespacesCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/NamespacesCommand.java
deleted file mode 100644
index d822cf6..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/NamespacesCommand.java
+++ /dev/null
@@ -1,83 +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.accumulo.shell.commands;
-
-import java.io.IOException;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.TreeMap;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.impl.Namespaces;
-import org.apache.accumulo.shell.Shell;
-import org.apache.accumulo.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-
-import com.google.common.base.Function;
-import com.google.common.collect.Iterators;
-
-public class NamespacesCommand extends Command {
-  private Option disablePaginationOpt, namespaceIdOption;
-
-  private static final String DEFAULT_NAMESPACE_DISPLAY_NAME = "\"\"";
-
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException, IOException {
-    Map<String,String> namespaces = new TreeMap<String,String>(shellState.getConnector().namespaceOperations().namespaceIdMap());
-
-    Iterator<String> it = Iterators.transform(namespaces.entrySet().iterator(), new Function<Entry<String,String>,String>() {
-      @Override
-      public String apply(Map.Entry<String,String> entry) {
-        String name = entry.getKey();
-        if (Namespaces.DEFAULT_NAMESPACE.equals(name))
-          name = DEFAULT_NAMESPACE_DISPLAY_NAME;
-        String id = entry.getValue();
-        if (cl.hasOption(namespaceIdOption.getOpt()))
-          return String.format(TablesCommand.NAME_AND_ID_FORMAT, name, id);
-        else
-          return name;
-      };
-    });
-
-    shellState.printLines(it, !cl.hasOption(disablePaginationOpt.getOpt()));
-    return 0;
-  }
-
-  @Override
-  public String description() {
-    return "displays a list of all existing namespaces";
-  }
-
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-    namespaceIdOption = new Option("l", "list-ids", false, "display internal namespace ids along with the name");
-    o.addOption(namespaceIdOption);
-    disablePaginationOpt = new Option("np", "no-pagination", false, "disable pagination of output");
-    o.addOption(disablePaginationOpt);
-    return o;
-  }
-
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/NoTableCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/NoTableCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/NoTableCommand.java
deleted file mode 100644
index 7ff6358..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/NoTableCommand.java
+++ /dev/null
@@ -1,40 +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.accumulo.shell.commands;
-
-import org.apache.accumulo.shell.Shell;
-import org.apache.accumulo.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-
-public class NoTableCommand extends Command {
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    shellState.setTableName("");
-    
-    return 0;
-  }
-  
-  @Override
-  public String description() {
-    return "returns to a tableless shell state";
-  }
-  
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/OfflineCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/OfflineCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/OfflineCommand.java
deleted file mode 100644
index 6ac397c..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/OfflineCommand.java
+++ /dev/null
@@ -1,61 +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.accumulo.shell.commands;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.TableNotFoundException;
-import org.apache.accumulo.core.metadata.MetadataTable;
-import org.apache.accumulo.shell.Shell;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-
-public class OfflineCommand extends TableOperation {
-  
-  private boolean wait;
-  private Option waitOpt;
-  
-  @Override
-  public String description() {
-    return "starts the process of taking table offline";
-  }
-  
-  protected void doTableOp(final Shell shellState, final String tableName) throws AccumuloException, AccumuloSecurityException, TableNotFoundException {
-    if (tableName.equals(MetadataTable.NAME)) {
-      Shell.log.info("  You cannot take the " + MetadataTable.NAME + " offline.");
-    } else {
-      shellState.getConnector().tableOperations().offline(tableName, wait);
-      Shell.log.info("Offline of table " + tableName + (wait ? " completed." : " initiated..."));
-    }
-  }
-  
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    wait = cl.hasOption(waitOpt.getLongOpt());
-    return super.execute(fullCommand, cl, shellState);
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options opts = super.getOptions();
-    waitOpt = new Option("w", "wait", false, "wait for offline to finish");
-    opts.addOption(waitOpt); 
-    return opts;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/OnlineCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/OnlineCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/OnlineCommand.java
deleted file mode 100644
index ace069f..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/OnlineCommand.java
+++ /dev/null
@@ -1,61 +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.accumulo.shell.commands;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.TableNotFoundException;
-import org.apache.accumulo.core.metadata.RootTable;
-import org.apache.accumulo.shell.Shell;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-
-public class OnlineCommand extends TableOperation {
-  
-  private boolean wait;
-  private Option waitOpt;
-  
-  @Override
-  public String description() {
-    return "starts the process of putting a table online";
-  }
-  
-  @Override
-  protected void doTableOp(final Shell shellState, final String tableName) throws AccumuloException, AccumuloSecurityException, TableNotFoundException {
-    if (tableName.equals(RootTable.NAME)) {
-      Shell.log.info("  The " + RootTable.NAME + " is always online.");
-    } else {
-      shellState.getConnector().tableOperations().online(tableName, wait);
-      Shell.log.info("Online of table " + tableName + (wait ? " completed." : " initiated..."));
-    }
-  }
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    wait = cl.hasOption(waitOpt.getLongOpt());
-    return super.execute(fullCommand, cl, shellState);
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options opts = super.getOptions();
-    waitOpt = new Option("w", "wait", false, "wait for online to finish");
-    opts.addOption(waitOpt); 
-    return opts;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/OptUtil.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/OptUtil.java b/shell/src/main/java/org/apache/accumulo/shell/commands/OptUtil.java
deleted file mode 100644
index 6243761..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/OptUtil.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.accumulo.shell.commands;
-
-import java.io.UnsupportedEncodingException;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.NamespaceNotFoundException;
-import org.apache.accumulo.core.client.TableNotFoundException;
-import org.apache.accumulo.shell.Shell;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.OptionGroup;
-import org.apache.hadoop.io.Text;
-
-public abstract class OptUtil {
-  public static final String START_ROW_OPT = "b";
-  public static final String END_ROW_OPT = "e";
-
-  public static String getTableOpt(final CommandLine cl, final Shell shellState) throws TableNotFoundException {
-    String tableName;
-
-    if (cl.hasOption(Shell.tableOption)) {
-      tableName = cl.getOptionValue(Shell.tableOption);
-      if (!shellState.getConnector().tableOperations().exists(tableName)) {
-        throw new TableNotFoundException(tableName, tableName, "specified table that doesn't exist");
-      }
-    } else {
-      shellState.checkTableState();
-      tableName = shellState.getTableName();
-    }
-
-    return tableName;
-  }
-
-  public static String getNamespaceOpt(final CommandLine cl, final Shell shellState) throws NamespaceNotFoundException, AccumuloException,
-      AccumuloSecurityException {
-    String namespace = null;
-    if (cl.hasOption(Shell.namespaceOption)) {
-      namespace = cl.getOptionValue(Shell.namespaceOption);
-      if (!shellState.getConnector().namespaceOperations().exists(namespace)) {
-        throw new NamespaceNotFoundException(namespace, namespace, "specified namespace that doesn't exist");
-      }
-    } else {
-      throw new NamespaceNotFoundException(null, null, "no namespace specified");
-    }
-    return namespace;
-  }
-
-  public static Option tableOpt() {
-    return tableOpt("tableName");
-  }
-
-  public static Option tableOpt(final String description) {
-    final Option tableOpt = new Option(Shell.tableOption, "table", true, description);
-    tableOpt.setArgName("table");
-    tableOpt.setRequired(false);
-    return tableOpt;
-  }
-
-  public static Option namespaceOpt() {
-    return namespaceOpt("namespace");
-  }
-
-  public static Option namespaceOpt(final String description) {
-    final Option namespaceOpt = new Option(Shell.namespaceOption, "namespace", true, description);
-    namespaceOpt.setArgName("namespace");
-    namespaceOpt.setRequired(false);
-    return namespaceOpt;
-  }
-
-  public static enum AdlOpt {
-    ADD("a"), DELETE("d"), LIST("l");
-
-    public final String opt;
-
-    private AdlOpt(String opt) {
-      this.opt = opt;
-    }
-  }
-
-  public static AdlOpt getAldOpt(final CommandLine cl) {
-    if (cl.hasOption(AdlOpt.ADD.opt)) {
-      return AdlOpt.ADD;
-    } else if (cl.hasOption(AdlOpt.DELETE.opt)) {
-      return AdlOpt.DELETE;
-    } else {
-      return AdlOpt.LIST;
-    }
-  }
-
-  public static OptionGroup addListDeleteGroup(final String name) {
-    final Option addOpt = new Option(AdlOpt.ADD.opt, "add", false, "add " + name);
-    final Option deleteOpt = new Option(AdlOpt.DELETE.opt, "delete", false, "delete " + name);
-    final Option listOpt = new Option(AdlOpt.LIST.opt, "list", false, "list " + name + "(s)");
-    final OptionGroup og = new OptionGroup();
-    og.addOption(addOpt);
-    og.addOption(deleteOpt);
-    og.addOption(listOpt);
-    og.setRequired(true);
-    return og;
-  }
-
-  public static Option startRowOpt() {
-    final Option o = new Option(START_ROW_OPT, "begin-row", true, "begin row (inclusive)");
-    o.setArgName("begin-row");
-    return o;
-  }
-
-  public static Option endRowOpt() {
-    final Option o = new Option(END_ROW_OPT, "end-row", true, "end row (inclusive)");
-    o.setArgName("end-row");
-    return o;
-  }
-
-  public static Text getStartRow(final CommandLine cl) throws UnsupportedEncodingException {
-    if (cl.hasOption(START_ROW_OPT)) {
-      return new Text(cl.getOptionValue(START_ROW_OPT).getBytes(Shell.CHARSET));
-    } else {
-      return null;
-    }
-  }
-
-  public static Text getEndRow(final CommandLine cl) throws UnsupportedEncodingException {
-    if (cl.hasOption(END_ROW_OPT)) {
-      return new Text(cl.getOptionValue(END_ROW_OPT).getBytes(Shell.CHARSET));
-    } else {
-      return null;
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/PasswdCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/PasswdCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/PasswdCommand.java
deleted file mode 100644
index c1ef990..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/PasswdCommand.java
+++ /dev/null
@@ -1,96 +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.accumulo.shell.commands;
-
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.impl.thrift.SecurityErrorCode;
-import org.apache.accumulo.core.client.security.tokens.PasswordToken;
-import org.apache.accumulo.shell.Shell;
-import org.apache.accumulo.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-
-public class PasswdCommand extends Command {
-  private Option userOpt;
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException, IOException {
-    final String currentUser = shellState.getConnector().whoami();
-    final String user = cl.getOptionValue(userOpt.getOpt(), currentUser);
-    
-    String password = null;
-    String passwordConfirm = null;
-    String oldPassword = null;
-    
-    oldPassword = shellState.readMaskedLine("Enter current password for '" + currentUser + "': ", '*');
-    if (oldPassword == null) {
-      shellState.getReader().println();
-      return 0;
-    } // user canceled
-    
-    if (!shellState.getConnector().securityOperations().authenticateUser(currentUser, new PasswordToken(oldPassword)))
-      throw new AccumuloSecurityException(user, SecurityErrorCode.BAD_CREDENTIALS);
-    
-    password = shellState.readMaskedLine("Enter new password for '" + user + "': ", '*');
-    if (password == null) {
-      shellState.getReader().println();
-      return 0;
-    } // user canceled
-    passwordConfirm = shellState.readMaskedLine("Please confirm new password for '" + user + "': ", '*');
-    if (passwordConfirm == null) {
-      shellState.getReader().println();
-      return 0;
-    } // user canceled
-    
-    if (!password.equals(passwordConfirm)) {
-      throw new IllegalArgumentException("Passwords do not match");
-    }
-    byte[] pass = password.getBytes(StandardCharsets.UTF_8);
-    shellState.getConnector().securityOperations().changeLocalUserPassword(user, new PasswordToken(pass));
-    // update the current credentials if the password changed was for
-    // the current user
-    if (shellState.getConnector().whoami().equals(user)) {
-      shellState.updateUser(user, new PasswordToken(pass));
-    }
-    Shell.log.debug("Changed password for user " + user);
-    return 0;
-  }
-  
-  @Override
-  public String description() {
-    return "changes a user's password";
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-    userOpt = new Option(Shell.userOption, "user", true, "user to operate on");
-    userOpt.setArgName("user");
-    o.addOption(userOpt);
-    return o;
-  }
-  
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/PingCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/PingCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/PingCommand.java
deleted file mode 100644
index ef7a9e4..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/PingCommand.java
+++ /dev/null
@@ -1,82 +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.accumulo.shell.commands;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.accumulo.core.client.admin.InstanceOperations;
-import org.apache.accumulo.shell.Shell;
-import org.apache.accumulo.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-
-/**
- * 
- */
-public class PingCommand extends Command {
-  
-  private Option tserverOption, disablePaginationOpt;
-  
-  @Override
-  public String description() {
-    return "ping tablet servers";
-  }
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    
-    List<String> tservers;
-    
-    final InstanceOperations instanceOps = shellState.getConnector().instanceOperations();
-    
-    final boolean paginate = !cl.hasOption(disablePaginationOpt.getOpt());
-    
-    if (cl.hasOption(tserverOption.getOpt())) {
-      tservers = new ArrayList<String>();
-      tservers.add(cl.getOptionValue(tserverOption.getOpt()));
-    } else {
-      tservers = instanceOps.getTabletServers();
-    }
-    
-    shellState.printLines(new PingIterator(tservers, instanceOps), paginate);
-    
-    return 0;
-  }
-  
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options opts = new Options();
-    
-    tserverOption = new Option("ts", "tabletServer", true, "tablet server to ping");
-    tserverOption.setArgName("tablet server");
-    opts.addOption(tserverOption);
-    
-    disablePaginationOpt = new Option("np", "no-pagination", false, "disable pagination of output");
-    opts.addOption(disablePaginationOpt);
-    
-    return opts;
-  }
-  
-}
-

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/PingIterator.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/PingIterator.java b/shell/src/main/java/org/apache/accumulo/shell/commands/PingIterator.java
deleted file mode 100644
index e414ed4..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/PingIterator.java
+++ /dev/null
@@ -1,58 +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.accumulo.shell.commands;
-
-import java.util.Iterator;
-import java.util.List;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.admin.InstanceOperations;
-
-class PingIterator implements Iterator<String> {
-  
-  private Iterator<String> iter;
-  private InstanceOperations instanceOps;
-
-  PingIterator(List<String> tservers, InstanceOperations instanceOps) {
-    iter = tservers.iterator();
-    this.instanceOps = instanceOps;
-  }
-  
-  @Override
-  public boolean hasNext() {
-    return iter.hasNext();
-  }
-  
-  @Override
-  public String next() {
-    String tserver = iter.next();
-    
-    try {
-      instanceOps.ping(tserver);
-    } catch (AccumuloException e) {
-      return tserver + " ERROR " + e.getMessage();
-    }
-    
-    return tserver + " OK";
-  }
-  
-  @Override
-  public void remove() {
-    throw new UnsupportedOperationException();
-  }
-  
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/QuestionCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/QuestionCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/QuestionCommand.java
deleted file mode 100644
index ae6b0a1..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/QuestionCommand.java
+++ /dev/null
@@ -1,24 +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.accumulo.shell.commands;
-
-public class QuestionCommand extends HelpCommand {
-  @Override
-  public String getName() {
-    return "?";
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/QuitCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/QuitCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/QuitCommand.java
deleted file mode 100644
index 3ad2274..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/QuitCommand.java
+++ /dev/null
@@ -1,19 +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.accumulo.shell.commands;
-
-public class QuitCommand extends ExitCommand {}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/QuotedStringTokenizer.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/QuotedStringTokenizer.java b/shell/src/main/java/org/apache/accumulo/shell/commands/QuotedStringTokenizer.java
deleted file mode 100644
index ecc51eb..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/QuotedStringTokenizer.java
+++ /dev/null
@@ -1,141 +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.accumulo.shell.commands;
-
-import java.io.UnsupportedEncodingException;
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.Iterator;
-
-import org.apache.accumulo.core.util.BadArgumentException;
-import org.apache.accumulo.shell.Shell;
-
-/**
- * A basic tokenizer for generating tokens from a string. It understands quoted strings and escaped quote characters.
- * 
- * You can use the escape sequence '\' to escape single quotes, double quotes, and spaces only, in addition to the escape character itself.
- * 
- * The behavior is the same for single and double quoted strings. (i.e. '\'' is the same as "\'")
- */
-
-public class QuotedStringTokenizer implements Iterable<String> {
-  private ArrayList<String> tokens;
-  private String input;
-  
-  public QuotedStringTokenizer(final String t) throws BadArgumentException {
-    tokens = new ArrayList<String>();
-    this.input = t;
-    try {
-      createTokens();
-    } catch (UnsupportedEncodingException e) {
-      throw new IllegalArgumentException(e.getMessage());
-    }
-  }
-  
-  public String[] getTokens() {
-    return tokens.toArray(new String[tokens.size()]);
-  }
-  
-  private void createTokens() throws BadArgumentException, UnsupportedEncodingException {
-    boolean inQuote = false;
-    boolean inEscapeSequence = false;
-    String hexChars = null;
-    char inQuoteChar = '"';
-    
-    final byte[] token = new byte[input.length()];
-    int tokenLength = 0;
-    final byte[] inputBytes = input.getBytes(StandardCharsets.UTF_8);
-    for (int i = 0; i < input.length(); ++i) {
-      final char ch = input.charAt(i);
-      
-      // if I ended up in an escape sequence, check for valid escapable character, and add it as a literal
-      if (inEscapeSequence) {
-        inEscapeSequence = false;
-        if (ch == 'x') {
-          hexChars = "";
-        } else if (ch == ' ' || ch == '\'' || ch == '"' || ch == '\\') {
-          token[tokenLength++] = inputBytes[i];
-        } else {
-          throw new BadArgumentException("can only escape single quotes, double quotes, the space character, the backslash, and hex input", input, i);
-        }
-      }
-      // in a hex escape sequence
-      else if (hexChars != null) {
-        final int digit = Character.digit(ch, 16);
-        if (digit < 0) {
-          throw new BadArgumentException("expected hex character", input, i);
-        }
-        hexChars += ch;
-        if (hexChars.length() == 2) {
-          byte b;
-          try {
-            b = (byte) (0xff & Short.parseShort(hexChars, 16));
-            if (!Character.isValidCodePoint(0xff & b))
-              throw new NumberFormatException();
-          } catch (NumberFormatException e) {
-            throw new BadArgumentException("unsupported non-ascii character", input, i);
-          }
-          token[tokenLength++] = b;
-          hexChars = null;
-        }
-      }
-      // in a quote, either end the quote, start escape, or continue a token
-      else if (inQuote) {
-        if (ch == inQuoteChar) {
-          inQuote = false;
-          tokens.add(new String(token, 0, tokenLength, Shell.CHARSET));
-          tokenLength = 0;
-        } else if (ch == '\\') {
-          inEscapeSequence = true;
-        } else {
-          token[tokenLength++] = inputBytes[i];
-        }
-      }
-      // not in a quote, either enter a quote, end a token, start escape, or continue a token
-      else {
-        if (ch == '\'' || ch == '"') {
-          if (tokenLength > 0) {
-            tokens.add(new String(token, 0, tokenLength, Shell.CHARSET));
-            tokenLength = 0;
-          }
-          inQuote = true;
-          inQuoteChar = ch;
-        } else if (ch == ' ' && tokenLength > 0) {
-          tokens.add(new String(token, 0, tokenLength, Shell.CHARSET));
-          tokenLength = 0;
-        } else if (ch == '\\') {
-          inEscapeSequence = true;
-        } else if (ch != ' ') {
-          token[tokenLength++] = inputBytes[i];
-        }
-      }
-    }
-    if (inQuote) {
-      throw new BadArgumentException("missing terminating quote", input, input.length());
-    } else if (inEscapeSequence || hexChars != null) {
-      throw new BadArgumentException("escape sequence not complete", input, input.length());
-    }
-    if (tokenLength > 0) {
-      tokens.add(new String(token, 0, tokenLength, Shell.CHARSET));
-    }
-  }
-  
-  @Override
-  public Iterator<String> iterator() {
-    return tokens.iterator();
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/RenameNamespaceCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/RenameNamespaceCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/RenameNamespaceCommand.java
deleted file mode 100644
index f456a30..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/RenameNamespaceCommand.java
+++ /dev/null
@@ -1,79 +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.accumulo.shell.commands;
-
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.NamespaceExistsException;
-import org.apache.accumulo.core.client.NamespaceNotFoundException;
-import org.apache.accumulo.core.client.TableExistsException;
-import org.apache.accumulo.core.client.TableNotFoundException;
-import org.apache.accumulo.core.client.impl.Namespaces;
-import org.apache.accumulo.core.client.impl.Tables;
-import org.apache.accumulo.shell.Shell;
-import org.apache.accumulo.shell.Token;
-import org.apache.accumulo.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-
-public class RenameNamespaceCommand extends Command {
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException,
-      TableNotFoundException, TableExistsException, NamespaceNotFoundException, NamespaceExistsException {
-    String old = cl.getArgs()[0];
-    String newer = cl.getArgs()[1];
-    boolean resetContext = false;
-    String currentTableId = "";
-    if (!(shellState.getTableName() == null) && !shellState.getTableName().isEmpty()) {
-      String namespaceId = Namespaces.getNamespaceId(shellState.getInstance(), old);
-      List<String> tableIds = Namespaces.getTableIds(shellState.getInstance(), namespaceId);
-      currentTableId = Tables.getTableId(shellState.getInstance(), shellState.getTableName());
-      resetContext = tableIds.contains(currentTableId);
-    }
-
-    shellState.getConnector().namespaceOperations().rename(old, newer);
-
-    if (resetContext) {
-      shellState.setTableName(Tables.getTableName(shellState.getInstance(), currentTableId));
-    }
-
-    return 0;
-  }
-
-  @Override
-  public String usage() {
-    return getName() + " <current namespace> <new namespace>";
-  }
-
-  @Override
-  public String description() {
-    return "renames a namespace";
-  }
-
-  @Override
-  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> special) {
-    registerCompletionForNamespaces(root, special);
-  }
-
-  @Override
-  public int numArgs() {
-    return 2;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/RenameTableCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/RenameTableCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/RenameTableCommand.java
deleted file mode 100644
index a810320..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/RenameTableCommand.java
+++ /dev/null
@@ -1,62 +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.accumulo.shell.commands;
-
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.TableExistsException;
-import org.apache.accumulo.core.client.TableNotFoundException;
-import org.apache.accumulo.core.client.impl.Tables;
-import org.apache.accumulo.shell.Shell;
-import org.apache.accumulo.shell.Token;
-import org.apache.accumulo.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-
-public class RenameTableCommand extends Command {
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException,
-      TableNotFoundException, TableExistsException {
-    shellState.getConnector().tableOperations().rename(cl.getArgs()[0], cl.getArgs()[1]);
-    if (shellState.getTableName().equals(Tables.qualified(cl.getArgs()[0]))) {
-      shellState.setTableName(cl.getArgs()[1]);
-    }
-    return 0;
-  }
-
-  @Override
-  public String usage() {
-    return getName() + " <current table name> <new table name>";
-  }
-
-  @Override
-  public String description() {
-    return "renames a table";
-  }
-
-  @Override
-  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> completionSet) {
-    registerCompletionForTables(root, completionSet);
-  }
-
-  @Override
-  public int numArgs() {
-    return 2;
-  }
-}


[24/53] [abbrv] Revert "ACCUMULO-1897 Move shell into new package and module"

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteNamespaceCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteNamespaceCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteNamespaceCommand.java
deleted file mode 100644
index faf1147..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteNamespaceCommand.java
+++ /dev/null
@@ -1,100 +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.accumulo.shell.commands;
-
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.accumulo.core.client.NamespaceNotFoundException;
-import org.apache.accumulo.core.client.impl.Namespaces;
-import org.apache.accumulo.shell.Shell;
-import org.apache.accumulo.shell.Token;
-import org.apache.accumulo.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-
-public class DeleteNamespaceCommand extends Command {
-  private Option forceOpt;
-
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    boolean force = false;
-    boolean operate = true;
-    if (cl.hasOption(forceOpt.getOpt())) {
-      force = true;
-    }
-    String namespace = cl.getArgs()[0];
-
-    if (!force) {
-      shellState.getReader().flush();
-      String line = shellState.getReader().readLine(getName() + " { " + namespace + " } (yes|no)? ");
-      operate = line != null && (line.equalsIgnoreCase("y") || line.equalsIgnoreCase("yes"));
-    }
-    if (operate) {
-      doTableOp(shellState, namespace, force);
-    }
-    return 0;
-  }
-
-  @Override
-  public String description() {
-    return "deletes a namespace";
-  }
-
-  protected void doTableOp(final Shell shellState, final String namespace, boolean force) throws Exception {
-    boolean resetContext = false;
-    String currentTable = shellState.getTableName();
-    if (!Namespaces.getNameToIdMap(shellState.getInstance()).containsKey(namespace)) {
-      throw new NamespaceNotFoundException(null, namespace, null);
-    }
-
-    String namespaceId = Namespaces.getNamespaceId(shellState.getInstance(), namespace);
-    List<String> tables = Namespaces.getTableNames(shellState.getInstance(), namespaceId);
-    resetContext = tables.contains(currentTable);
-
-    if (force)
-      for (String table : shellState.getConnector().tableOperations().list())
-        if (table.startsWith(namespace + "."))
-          shellState.getConnector().tableOperations().delete(table);
-
-    shellState.getConnector().namespaceOperations().delete(namespace);
-    if (resetContext) {
-      shellState.setTableName("");
-    }
-  }
-
-  @Override
-  public Options getOptions() {
-    forceOpt = new Option("f", "force", false, "force deletion without prompting");
-    final Options opts = super.getOptions();
-
-    opts.addOption(forceOpt);
-    return opts;
-  }
-
-  @Override
-  public int numArgs() {
-    return 1;
-  }
-
-  @Override
-  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> special) {
-    registerCompletionForNamespaces(root, special);
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteRowsCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteRowsCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteRowsCommand.java
deleted file mode 100644
index 09f2938..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteRowsCommand.java
+++ /dev/null
@@ -1,65 +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.accumulo.shell.commands;
-
-import org.apache.accumulo.shell.Shell;
-import org.apache.accumulo.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-import org.apache.hadoop.io.Text;
-
-public class DeleteRowsCommand extends Command {
-  private Option forceOpt;
-  private Option startRowOptExclusive;
- 
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    final String tableName = OptUtil.getTableOpt(cl, shellState);
-    final Text startRow = OptUtil.getStartRow(cl);
-    final Text endRow = OptUtil.getEndRow(cl);
-    if (!cl.hasOption(forceOpt.getOpt()) && (startRow == null || endRow == null)) {
-      shellState.getReader().println("Not deleting unbounded range. Specify both ends, or use --force");
-      return 1;
-    }
-    shellState.getConnector().tableOperations().deleteRows(tableName, startRow, endRow);
-    return 0;
-  }
-  
-  @Override
-  public String description() {
-    return "deletes a range of rows in a table.  Note that rows matching the start row ARE NOT deleted, but rows matching the end row ARE deleted.";
-  }
-  
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-    forceOpt = new Option("f", "force", false, "delete data even if start or end are not specified");
-    startRowOptExclusive = new Option(OptUtil.START_ROW_OPT, "begin-row", true, "begin row (exclusive)");
-    startRowOptExclusive.setArgName("begin-row");
-    o.addOption(startRowOptExclusive);
-    o.addOption(OptUtil.endRowOpt());
-    o.addOption(OptUtil.tableOpt("table to delete a row range from"));
-    o.addOption(forceOpt);
-    return o;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteScanIterCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteScanIterCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteScanIterCommand.java
deleted file mode 100644
index f3c9823..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteScanIterCommand.java
+++ /dev/null
@@ -1,102 +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.accumulo.shell.commands;
-
-import java.util.Iterator;
-import java.util.List;
-
-import org.apache.accumulo.core.client.IteratorSetting;
-import org.apache.accumulo.shell.Shell;
-import org.apache.accumulo.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.OptionGroup;
-import org.apache.commons.cli.Options;
-
-public class DeleteScanIterCommand extends Command {
-  private Option nameOpt, allOpt;
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    final String tableName = OptUtil.getTableOpt(cl, shellState);
-    
-    if (cl.hasOption(allOpt.getOpt())) {
-      final List<IteratorSetting> tableScanIterators = shellState.scanIteratorOptions.remove(tableName);
-      if (tableScanIterators == null) {
-        Shell.log.info("No scan iterators set on table " + tableName);
-      } else {
-        Shell.log.info("Removed the following scan iterators from table " + tableName + ":" + tableScanIterators);
-      }
-    } else if (cl.hasOption(nameOpt.getOpt())) {
-      final String name = cl.getOptionValue(nameOpt.getOpt());
-      final List<IteratorSetting> tableScanIterators = shellState.scanIteratorOptions.get(tableName);
-      if (tableScanIterators != null) {
-        boolean found = false;
-        for (Iterator<IteratorSetting> iter = tableScanIterators.iterator(); iter.hasNext();) {
-          if (iter.next().getName().equals(name)) {
-            iter.remove();
-            found = true;
-            break;
-          }
-        }
-        if (!found) {
-          Shell.log.info("No iterator named " + name + " found for table " + tableName);
-        } else {
-          Shell.log.info("Removed scan iterator " + name + " from table " + tableName + " (" + shellState.scanIteratorOptions.get(tableName).size() + " left)");
-          if (shellState.scanIteratorOptions.get(tableName).size() == 0) {
-            shellState.scanIteratorOptions.remove(tableName);
-          }
-        }
-      } else {
-        Shell.log.info("No iterator named " + name + " found for table " + tableName);
-      }
-    }
-    
-    return 0;
-  }
-  
-  @Override
-  public String description() {
-    return "deletes a table-specific scan iterator so it is no longer used during this shell session";
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-    
-    OptionGroup nameGroup = new OptionGroup();
-    
-    nameOpt = new Option("n", "name", true, "iterator to delete");
-    nameOpt.setArgName("itername");
-    
-    allOpt = new Option("a", "all", false, "delete all scan iterators");
-    allOpt.setArgName("all");
-    
-    nameGroup.addOption(nameOpt);
-    nameGroup.addOption(allOpt);
-    nameGroup.setRequired(true);
-    o.addOptionGroup(nameGroup);
-    o.addOption(OptUtil.tableOpt("table to delete scan iterators from"));
-    
-    return o;
-  }
-  
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteShellIterCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteShellIterCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteShellIterCommand.java
deleted file mode 100644
index 3010f0b..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteShellIterCommand.java
+++ /dev/null
@@ -1,100 +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.accumulo.shell.commands;
-
-import java.util.Iterator;
-import java.util.List;
-
-import org.apache.accumulo.core.client.IteratorSetting;
-import org.apache.accumulo.shell.Shell;
-import org.apache.accumulo.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.OptionGroup;
-import org.apache.commons.cli.Options;
-
-public class DeleteShellIterCommand extends Command {
-  private Option nameOpt, allOpt, profileOpt;
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-
-    String profile = cl.getOptionValue(profileOpt.getOpt());
-    if (shellState.iteratorProfiles.containsKey(profile)) {
-      if (cl.hasOption(allOpt.getOpt())) {
-        shellState.iteratorProfiles.remove(profile);
-        Shell.log.info("Removed profile " + profile);
-      } else {
-        List<IteratorSetting> iterSettings = shellState.iteratorProfiles.get(profile);
-        String name = cl.getOptionValue(nameOpt.getOpt());
-        boolean found = false;
-        for (Iterator<IteratorSetting> iter = iterSettings.iterator(); iter.hasNext();) {
-          if (iter.next().getName().equals(name)) {
-            iter.remove();
-            found = true;
-            break;
-          }
-        }
-        if (!found) {
-          Shell.log.info("No iterator named " + name + " found");
-        } else {
-          Shell.log.info("Removed iterator " + name + " from profile " + profile + " (" + iterSettings.size() + " left)");
-        }
-      }
-      
-    } else {
-      Shell.log.info("No profile named " + profile);
-    }
-    
-    return 0;
-  }
-  
-  @Override
-  public String description() {
-    return "deletes iterators profiles configured in this shell session";
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-    
-    OptionGroup nameGroup = new OptionGroup();
-    
-    nameOpt = new Option("n", "name", true, "iterator to delete");
-    nameOpt.setArgName("itername");
-    
-    allOpt = new Option("a", "all", false, "delete all scan iterators");
-    allOpt.setArgName("all");
-    
-    nameGroup.addOption(nameOpt);
-    nameGroup.addOption(allOpt);
-    nameGroup.setRequired(true);
-    o.addOptionGroup(nameGroup);
-    
-    profileOpt = new Option("pn", "profile", true, "iterator profile name");
-    profileOpt.setRequired(true);
-    profileOpt.setArgName("profile");
-    o.addOption(profileOpt);
-
-    return o;
-  }
-  
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteTableCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteTableCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteTableCommand.java
deleted file mode 100644
index 827a8ec..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteTableCommand.java
+++ /dev/null
@@ -1,60 +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.accumulo.shell.commands;
-
-import org.apache.accumulo.shell.Shell;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-
-public class DeleteTableCommand extends TableOperation {
-  private Option forceOpt;
-
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    if (cl.hasOption(forceOpt.getOpt())) {
-      super.force();
-    } else {
-      super.noForce();
-    }
-    return super.execute(fullCommand, cl, shellState);
-  }
-
-  @Override
-  public String description() {
-    return "deletes a table";
-  }
-
-  @Override
-  protected void doTableOp(final Shell shellState, final String tableName) throws Exception {
-    shellState.getConnector().tableOperations().delete(tableName);
-    shellState.getReader().println("Table: [" + tableName + "] has been deleted.");
-
-    if (shellState.getTableName().equals(tableName)) {
-      shellState.setTableName("");
-    }
-  }
-
-  @Override
-  public Options getOptions() {
-    forceOpt = new Option("f", "force", false, "force deletion without prompting");
-    final Options opts = super.getOptions();
-
-    opts.addOption(forceOpt);
-    return opts;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteUserCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteUserCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteUserCommand.java
deleted file mode 100644
index 22d072a..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteUserCommand.java
+++ /dev/null
@@ -1,19 +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.accumulo.shell.commands;
-
-public class DeleteUserCommand extends DropUserCommand {}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/DropTableCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/DropTableCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/DropTableCommand.java
deleted file mode 100644
index 45b40dd..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/DropTableCommand.java
+++ /dev/null
@@ -1,19 +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.accumulo.shell.commands;
-
-public class DropTableCommand extends DeleteTableCommand {}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/DropUserCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/DropUserCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/DropUserCommand.java
deleted file mode 100644
index 7de216d..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/DropUserCommand.java
+++ /dev/null
@@ -1,61 +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.accumulo.shell.commands;
-
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.util.BadArgumentException;
-import org.apache.accumulo.shell.Shell;
-import org.apache.accumulo.shell.Token;
-import org.apache.accumulo.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-
-public class DropUserCommand extends Command {
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException {
-    final String user = cl.getArgs()[0];
-    if (shellState.getConnector().whoami().equals(user)) {
-      throw new BadArgumentException("You cannot delete yourself", fullCommand, fullCommand.indexOf(user));
-    }
-    shellState.getConnector().securityOperations().dropLocalUser(user);
-    Shell.log.debug("Deleted user " + user);
-    return 0;
-  }
-  
-  @Override
-  public String description() {
-    return "deletes a user";
-  }
-  
-  @Override
-  public String usage() {
-    return getName() + " <username>";
-  }
-  
-  @Override
-  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> completionSet) {
-    registerCompletionForUsers(root, completionSet);
-  }
-  
-  @Override
-  public int numArgs() {
-    return 1;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/EGrepCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/EGrepCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/EGrepCommand.java
deleted file mode 100644
index 958f5eb..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/EGrepCommand.java
+++ /dev/null
@@ -1,59 +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.accumulo.shell.commands;
-
-import java.io.IOException;
-
-import org.apache.accumulo.core.client.BatchScanner;
-import org.apache.accumulo.core.client.IteratorSetting;
-import org.apache.accumulo.core.iterators.user.RegExFilter;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-
-public class EGrepCommand extends GrepCommand {
-  
-  private Option matchSubstringOption;
-  
-  @Override
-  protected void setUpIterator(final int prio, final String name, final String term, final BatchScanner scanner, CommandLine cl) throws IOException {
-    if (prio < 0) {
-      throw new IllegalArgumentException("Priority < 0 " + prio);
-    }
-    final IteratorSetting si = new IteratorSetting(prio, name, RegExFilter.class);
-    RegExFilter.setRegexs(si, term, term, term, term, true, cl.hasOption(matchSubstringOption.getOpt()));
-    scanner.addScanIterator(si);
-  }
-  
-  @Override
-  public String description() {
-    return "searches each row, column family, column qualifier and value, in parallel, on the server side (using a java Matcher, so put .* before and after your term if you're not matching the whole element)";
-  }
-  
-  @Override
-  public String usage() {
-    return getName() + " <regex>{ <regex>}";
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options opts = super.getOptions();
-    matchSubstringOption = new Option("g", "global", false, "forces the use of the find() expression matcher, causing substring matches to return true");
-    opts.addOption(matchSubstringOption);
-    return opts;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/ExecfileCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/ExecfileCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/ExecfileCommand.java
deleted file mode 100644
index b384d5c..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/ExecfileCommand.java
+++ /dev/null
@@ -1,67 +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.accumulo.shell.commands;
-
-import java.io.File;
-import java.nio.charset.StandardCharsets;
-import java.util.Scanner;
-
-import org.apache.accumulo.shell.Shell;
-import org.apache.accumulo.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-
-public class ExecfileCommand extends Command {
-  private Option verboseOption;
-  
-  @Override
-  public String description() {
-    return "specifies a file containing accumulo commands to execute";
-  }
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    Scanner scanner = new Scanner(new File(cl.getArgs()[0]), StandardCharsets.UTF_8.name());
-    try {
-      while (scanner.hasNextLine()) {
-        shellState.execCommand(scanner.nextLine(), true, cl.hasOption(verboseOption.getOpt()));
-      }
-    } finally {
-      scanner.close();
-    }
-    return 0;
-  }
-  
-  @Override
-  public String usage() {
-    return getName() + " <fileName>";
-  }
-  
-  @Override
-  public int numArgs() {
-    return 1;
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options opts = new Options();
-    verboseOption = new Option("v", "verbose", false, "display command prompt as commands are executed");
-    opts.addOption(verboseOption);
-    return opts;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/ExitCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/ExitCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/ExitCommand.java
deleted file mode 100644
index 1d44409..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/ExitCommand.java
+++ /dev/null
@@ -1,39 +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.accumulo.shell.commands;
-
-import org.apache.accumulo.shell.Shell;
-import org.apache.accumulo.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-
-public class ExitCommand extends Command {
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) {
-    shellState.setExit(true);
-    return 0;
-  }
-  
-  @Override
-  public String description() {
-    return "exits the shell";
-  }
-  
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/ExportTableCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/ExportTableCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/ExportTableCommand.java
deleted file mode 100644
index d8d358c..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/ExportTableCommand.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.accumulo.shell.commands;
-
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.TableExistsException;
-import org.apache.accumulo.core.client.TableNotFoundException;
-import org.apache.accumulo.shell.Shell;
-import org.apache.accumulo.shell.Token;
-import org.apache.accumulo.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-
-public class ExportTableCommand extends Command {
-  
-  private Option tableOpt;
-
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException, TableNotFoundException,
-      TableExistsException {
-    
-    final String tableName = OptUtil.getTableOpt(cl, shellState);
-
-    shellState.getConnector().tableOperations().exportTable(tableName, cl.getArgs()[0]);
-    return 0;
-  }
-  
-  @Override
-  public String usage() {
-    return getName() + " <export dir>";
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-    
-    tableOpt = new Option(Shell.tableOption, "table", true, "table to export");
-    
-    tableOpt.setArgName("table");
-    
-    o.addOption(tableOpt);
-
-    return o;
-  }
-  
-  @Override
-  public String description() {
-    return "exports a table";
-  }
-  
-  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> completionSet) {
-    registerCompletionForTables(root, completionSet);
-  }
-  
-  @Override
-  public int numArgs() {
-    return 1;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/ExtensionCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/ExtensionCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/ExtensionCommand.java
deleted file mode 100644
index fbc1833..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/ExtensionCommand.java
+++ /dev/null
@@ -1,102 +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.accumulo.shell.commands;
-
-import java.util.HashSet;
-import java.util.ServiceLoader;
-import java.util.Set;
-import java.util.TreeSet;
-
-import org.apache.accumulo.shell.Shell;
-import org.apache.accumulo.shell.ShellExtension;
-import org.apache.accumulo.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-
-public class ExtensionCommand extends Command {
-  
-  protected Option enable, disable, list;
-  
-  private static ServiceLoader<ShellExtension> extensions = null;
-  
-  private Set<String> loadedHeaders = new HashSet<String>();
-  private Set<String> loadedCommands = new HashSet<String>();
-  private Set<String> loadedExtensions = new TreeSet<String>();
-  
-  public int execute(String fullCommand, CommandLine cl, Shell shellState) throws Exception {
-    if (cl.hasOption(enable.getOpt())) {
-      extensions = ServiceLoader.load(ShellExtension.class);
-      for (ShellExtension se : extensions) {
-        
-        loadedExtensions.add(se.getExtensionName());
-        String header = "-- " + se.getExtensionName() + " Extension Commands ---------";
-        loadedHeaders.add(header);
-        shellState.commandGrouping.put(header, se.getCommands());
-        
-        for (Command cmd : se.getCommands()) {
-          String name = se.getExtensionName() + "::" + cmd.getName();
-          loadedCommands.add(name);
-          shellState.commandFactory.put(name, cmd);
-        }
-      }
-    } else if (cl.hasOption(disable.getOpt())) {
-      //Remove the headers
-      for (String header : loadedHeaders) {
-        shellState.commandGrouping.remove(header);
-      }
-      //remove the commands
-      for (String name : loadedCommands) {
-        shellState.commandFactory.remove(name);
-      }
-      //Reset state
-      loadedExtensions.clear();
-      extensions.reload();
-    } else if (cl.hasOption(list.getOpt())) {
-      shellState.printLines(loadedExtensions.iterator(), true);
-    } else {
-      printHelp(shellState);
-    }
-    return 0;
-  }
-  
-  public String description() {
-    return "Enable, disable, or list shell extensions";
-  }
-  
-  public int numArgs() {
-    return 0;
-  }
-  
-  @Override
-  public String getName() {
-    return "extensions";
-  }
-
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-    enable = new Option("e", "enable", false, "enable shell extensions");
-    disable = new Option("d", "disable", false, "disable shell extensions");
-    list = new Option("l", "list", false, "list shell extensions");
-    o.addOption(enable);
-    o.addOption(disable);
-    o.addOption(list);
-    return o;
-  }
-    
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/FateCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/FateCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/FateCommand.java
deleted file mode 100644
index eae1ec8..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/FateCommand.java
+++ /dev/null
@@ -1,180 +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.accumulo.shell.commands;
-
-import java.io.IOException;
-import java.util.Collections;
-import java.util.EnumSet;
-import java.util.Formatter;
-import java.util.HashSet;
-import java.util.Set;
-
-import org.apache.accumulo.core.Constants;
-import org.apache.accumulo.core.client.Instance;
-import org.apache.accumulo.core.conf.AccumuloConfiguration;
-import org.apache.accumulo.core.conf.Property;
-import org.apache.accumulo.core.zookeeper.ZooUtil;
-import org.apache.accumulo.fate.AdminUtil;
-import org.apache.accumulo.fate.ReadOnlyTStore.TStatus;
-import org.apache.accumulo.fate.ZooStore;
-import org.apache.accumulo.fate.zookeeper.IZooReaderWriter;
-import org.apache.accumulo.fate.zookeeper.ZooReaderWriter;
-import org.apache.accumulo.shell.Shell;
-import org.apache.accumulo.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-import org.apache.commons.cli.ParseException;
-import org.apache.zookeeper.KeeperException;
-
-/**
- * Manage FATE transactions
- * 
- */
-public class FateCommand extends Command {
-  
-  private static final String SCHEME = "digest";
-  
-  private static final String USER = "accumulo";
-  
-  private Option secretOption;
-  private Option statusOption;
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws ParseException, KeeperException, InterruptedException,
-      IOException {
-    Instance instance = shellState.getInstance();
-    String[] args = cl.getArgs();
-    if (args.length <= 0) {
-      throw new ParseException("Must provide a command to execute");
-    }
-    String cmd = args[0];
-    boolean failedCommand = false;
-    
-    AdminUtil<FateCommand> admin = new AdminUtil<FateCommand>(false);
-    
-    String path = ZooUtil.getRoot(instance) + Constants.ZFATE;
-    String masterPath = ZooUtil.getRoot(instance) + Constants.ZMASTER_LOCK;
-    IZooReaderWriter zk = getZooReaderWriter(shellState.getInstance(), cl.getOptionValue(secretOption.getOpt()));
-    ZooStore<FateCommand> zs = new ZooStore<FateCommand>(path, zk);
-    
-    if ("fail".equals(cmd)) {
-      if (args.length <= 1) {
-        throw new ParseException("Must provide transaction ID");
-      }
-      for (int i = 1; i < args.length; i++) {
-        if (!admin.prepFail(zs, zk, masterPath, args[i])) {
-          System.out.printf("Could not fail transaction: %s%n", args[i]);
-          failedCommand = true;
-        }
-      }
-    } else if ("delete".equals(cmd)) {
-      if (args.length <= 1) {
-        throw new ParseException("Must provide transaction ID");
-      }
-      for (int i = 1; i < args.length; i++) {
-        if (admin.prepDelete(zs, zk, masterPath, args[i])) {
-          admin.deleteLocks(zs, zk, ZooUtil.getRoot(instance) + Constants.ZTABLE_LOCKS, args[i]);
-        } else {
-          System.out.printf("Could not delete transaction: %s%n", args[i]);
-          failedCommand = true;
-        }
-      }
-    } else if ("list".equals(cmd) || "print".equals(cmd)) {
-      // Parse transaction ID filters for print display
-      Set<Long> filterTxid = null;
-      if (args.length >= 2) {
-        filterTxid = new HashSet<Long>(args.length);
-        for (int i = 1; i < args.length; i++) {
-          try {
-            Long val = Long.parseLong(args[i], 16);
-            filterTxid.add(val);
-          } catch (NumberFormatException nfe) {
-            // Failed to parse, will exit instead of displaying everything since the intention was to potentially filter some data
-            System.out.printf("Invalid transaction ID format: %s%n", args[i]);
-            return 1;
-          }
-        }
-      }
-      
-      // Parse TStatus filters for print display
-      EnumSet<TStatus> filterStatus = null;
-      if (cl.hasOption(statusOption.getOpt())) {
-        filterStatus = EnumSet.noneOf(TStatus.class);
-        String[] tstat = cl.getOptionValues(statusOption.getOpt());
-        for (int i = 0; i < tstat.length; i++) {
-          try {
-            filterStatus.add(TStatus.valueOf(tstat[i]));
-          } catch (IllegalArgumentException iae) {
-            System.out.printf("Invalid transaction status name: %s%n", tstat[i]);
-            return 1;
-          }
-        }
-      }
-      
-      StringBuilder buf = new StringBuilder(8096);
-      Formatter fmt = new Formatter(buf);
-      admin.print(zs, zk, ZooUtil.getRoot(instance) + Constants.ZTABLE_LOCKS, fmt, filterTxid, filterStatus);
-      shellState.printLines(Collections.singletonList(buf.toString()).iterator(), true);
-    } else {
-      throw new ParseException("Invalid command option");
-    }
-    
-    return failedCommand ? 1 : 0;
-  }
-  
-  protected synchronized IZooReaderWriter getZooReaderWriter(Instance instance, String secret) {
-    
-    if (secret == null) {
-      @SuppressWarnings("deprecation")
-      AccumuloConfiguration conf = AccumuloConfiguration.getSiteConfiguration();
-      secret = conf.get(Property.INSTANCE_SECRET);
-    }
-    
-    return new ZooReaderWriter(instance.getZooKeepers(), instance.getZooKeepersSessionTimeOut(), SCHEME, (USER + ":" + secret).getBytes());
-  }
-  
-  @Override
-  public String description() {
-    return "manage FATE transactions";
-  }
-  
-  @Override
-  public String usage() {
-    return getName() + " fail <txid>... | delete <txid>... | print [<txid>...]";
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-    secretOption = new Option("s", "secret", true, "specify the instance secret to use");
-    secretOption.setOptionalArg(false);
-    o.addOption(secretOption);
-    statusOption = new Option("t", "status-type", true,
-        "filter 'print' on the transaction status type(s) {NEW, IN_PROGRESS, FAILED_IN_PROGRESS, FAILED, SUCCESSFUL}");
-    statusOption.setArgs(Option.UNLIMITED_VALUES);
-    statusOption.setOptionalArg(false);
-    o.addOption(statusOption);
-    return o;
-  }
-  
-  @Override
-  public int numArgs() {
-    // Arg length varies between 1 to n
-    return -1;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/FlushCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/FlushCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/FlushCommand.java
deleted file mode 100644
index 34e22a5..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/FlushCommand.java
+++ /dev/null
@@ -1,63 +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.accumulo.shell.commands;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.TableNotFoundException;
-import org.apache.accumulo.shell.Shell;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-import org.apache.hadoop.io.Text;
-
-public class FlushCommand extends TableOperation {
-  private Text startRow;
-  private Text endRow;
-  
-  private boolean wait;
-  private Option waitOpt;
-  
-  @Override
-  public String description() {
-    return "flushes a tables data that is currently in memory to disk";
-  }
-  
-  protected void doTableOp(final Shell shellState, final String tableName) throws AccumuloException, AccumuloSecurityException, TableNotFoundException {
-    shellState.getConnector().tableOperations().flush(tableName, startRow, endRow, wait);
-    Shell.log.info("Flush of table " + tableName + (wait ? " completed." : " initiated..."));
-  }
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    wait = cl.hasOption(waitOpt.getLongOpt());
-    startRow = OptUtil.getStartRow(cl);
-    endRow = OptUtil.getEndRow(cl);
-    return super.execute(fullCommand, cl, shellState);
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options opts = super.getOptions();
-    waitOpt = new Option("w", "wait", false, "wait for flush to finish");
-    opts.addOption(waitOpt);
-    opts.addOption(OptUtil.startRowOpt());
-    opts.addOption(OptUtil.endRowOpt());
-    
-    return opts;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/FormatterCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/FormatterCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/FormatterCommand.java
deleted file mode 100644
index e416699..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/FormatterCommand.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.accumulo.shell.commands;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.conf.Property;
-import org.apache.accumulo.core.util.format.Formatter;
-import org.apache.accumulo.shell.Shell;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-
-public class FormatterCommand extends ShellPluginConfigurationCommand {
-  
-  private Option interpeterOption;
-
-  public FormatterCommand() {
-    super("formatter", Property.TABLE_FORMATTER_CLASS, "f");
-  }
-
-  @Override
-  public String description() {
-    return "specifies a formatter to use for displaying table entries";
-  }
-
-  public static Class<? extends Formatter> getCurrentFormatter(final String tableName, final Shell shellState) {
-    return ShellPluginConfigurationCommand.getPluginClass(tableName, shellState, Formatter.class, Property.TABLE_FORMATTER_CLASS);
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options options = super.getOptions();
-    
-    interpeterOption = new Option("i", "interpeter", false, "configure class as interpreter also");
-    
-    options.addOption(interpeterOption);
-    
-    return options;
-  }
-  
-  protected void setPlugin(final CommandLine cl, final Shell shellState, final String tableName, final String className) throws AccumuloException, AccumuloSecurityException {
-    super.setPlugin(cl, shellState, tableName, className);
-    if (cl.hasOption(interpeterOption.getOpt())) {
-      shellState.getConnector().tableOperations().setProperty(tableName, Property.TABLE_INTERPRETER_CLASS.toString(), className);
-    }
-  }
-  
-  protected void removePlugin(final CommandLine cl, final Shell shellState, final String tableName) throws AccumuloException, AccumuloSecurityException {
-    super.removePlugin(cl, shellState, tableName);
-    if (cl.hasOption(interpeterOption.getOpt())) {
-      shellState.getConnector().tableOperations().removeProperty(tableName, Property.TABLE_INTERPRETER_CLASS.toString());
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/GetAuthsCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/GetAuthsCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/GetAuthsCommand.java
deleted file mode 100644
index 0156d44..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/GetAuthsCommand.java
+++ /dev/null
@@ -1,67 +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.accumulo.shell.commands;
-
-import java.io.IOException;
-import java.util.SortedSet;
-import java.util.TreeSet;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.security.Authorizations;
-import org.apache.accumulo.shell.Shell;
-import org.apache.accumulo.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-import org.apache.commons.lang.StringUtils;
-
-public class GetAuthsCommand extends Command {
-  private Option userOpt;
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException, IOException {
-    final String user = cl.getOptionValue(userOpt.getOpt(), shellState.getConnector().whoami());
-    // Sort authorizations
-    Authorizations auths = shellState.getConnector().securityOperations().getUserAuthorizations(user);
-    SortedSet<String> set = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
-    for (byte[] auth : auths) {
-      set.add(new String(auth));
-    }
-    shellState.getReader().println(StringUtils.join(set, ','));
-    return 0;
-  }
-  
-  @Override
-  public String description() {
-    return "displays the maximum scan authorizations for a user";
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-    userOpt = new Option(Shell.userOption, "user", true, "user to operate on");
-    userOpt.setArgName("user");
-    o.addOption(userOpt);
-    return o;
-  }
-  
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/GetGroupsCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/GetGroupsCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/GetGroupsCommand.java
deleted file mode 100644
index 6cae7e0..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/GetGroupsCommand.java
+++ /dev/null
@@ -1,60 +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.accumulo.shell.commands;
-
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-
-import org.apache.accumulo.core.util.LocalityGroupUtil;
-import org.apache.accumulo.shell.Shell;
-import org.apache.accumulo.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Options;
-import org.apache.hadoop.io.Text;
-
-public class GetGroupsCommand extends Command {
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    final String tableName = OptUtil.getTableOpt(cl, shellState);
-    
-    final Map<String,Set<Text>> groups = shellState.getConnector().tableOperations().getLocalityGroups(tableName);
-    
-    for (Entry<String,Set<Text>> entry : groups.entrySet()) {
-      shellState.getReader().println(entry.getKey() + "=" + LocalityGroupUtil.encodeColumnFamilies(entry.getValue()));
-    }
-    return 0;
-  }
-  
-  @Override
-  public String description() {
-    return "gets the locality groups for a given table";
-  }
-  
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options opts = new Options();
-    opts.addOption(OptUtil.tableOpt("table to fetch locality groups from"));
-    return opts;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/GetSplitsCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/GetSplitsCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/GetSplitsCommand.java
deleted file mode 100644
index f275c39..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/GetSplitsCommand.java
+++ /dev/null
@@ -1,155 +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.accumulo.shell.commands;
-
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.util.Iterator;
-import java.util.Map.Entry;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.Scanner;
-import org.apache.accumulo.core.client.TableNotFoundException;
-import org.apache.accumulo.core.data.Key;
-import org.apache.accumulo.core.data.KeyExtent;
-import org.apache.accumulo.core.data.Range;
-import org.apache.accumulo.core.data.Value;
-import org.apache.accumulo.core.metadata.MetadataTable;
-import org.apache.accumulo.core.metadata.RootTable;
-import org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection;
-import org.apache.accumulo.core.security.Authorizations;
-import org.apache.accumulo.core.util.TextUtil;
-import org.apache.accumulo.core.util.format.BinaryFormatter;
-import org.apache.accumulo.shell.Shell;
-import org.apache.accumulo.shell.Shell.Command;
-import org.apache.accumulo.shell.Shell.PrintFile;
-import org.apache.accumulo.shell.Shell.PrintLine;
-import org.apache.accumulo.shell.Shell.PrintShell;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-import org.apache.commons.codec.binary.Base64;
-import org.apache.hadoop.io.Text;
-
-public class GetSplitsCommand extends Command {
-  
-  private Option outputFileOpt, maxSplitsOpt, base64Opt, verboseOpt;
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws IOException, AccumuloException, AccumuloSecurityException,
-      TableNotFoundException {
-    final String tableName = OptUtil.getTableOpt(cl, shellState);
-    
-    final String outputFile = cl.getOptionValue(outputFileOpt.getOpt());
-    final String m = cl.getOptionValue(maxSplitsOpt.getOpt());
-    final int maxSplits = m == null ? 0 : Integer.parseInt(m);
-    final boolean encode = cl.hasOption(base64Opt.getOpt());
-    final boolean verbose = cl.hasOption(verboseOpt.getOpt());
-    
-    final PrintLine p = outputFile == null ? new PrintShell(shellState.getReader()) : new PrintFile(outputFile);
-    
-    try {
-      if (!verbose) {
-        for (Text row : maxSplits > 0 ? shellState.getConnector().tableOperations().listSplits(tableName, maxSplits) : shellState.getConnector()
-            .tableOperations().listSplits(tableName)) {
-          p.print(encode(encode, row));
-        }
-      } else {
-        String systemTableToCheck = MetadataTable.NAME.equals(tableName) ? RootTable.NAME : MetadataTable.NAME;
-        final Scanner scanner = shellState.getConnector().createScanner(systemTableToCheck, Authorizations.EMPTY);
-        TabletsSection.TabletColumnFamily.PREV_ROW_COLUMN.fetch(scanner);
-        final Text start = new Text(shellState.getConnector().tableOperations().tableIdMap().get(tableName));
-        final Text end = new Text(start);
-        end.append(new byte[] {'<'}, 0, 1);
-        scanner.setRange(new Range(start, end));
-        for (Iterator<Entry<Key,Value>> iterator = scanner.iterator(); iterator.hasNext();) {
-          final Entry<Key,Value> next = iterator.next();
-          if (TabletsSection.TabletColumnFamily.PREV_ROW_COLUMN.hasColumns(next.getKey())) {
-            KeyExtent extent = new KeyExtent(next.getKey().getRow(), next.getValue());
-            final String pr = encode(encode, extent.getPrevEndRow());
-            final String er = encode(encode, extent.getEndRow());
-            final String line = String.format("%-26s (%s, %s%s", obscuredTabletName(extent), pr == null ? "-inf" : pr, er == null ? "+inf" : er,
-                er == null ? ") Default Tablet " : "]");
-            p.print(line);
-          }
-        }
-      }
-      
-    } finally {
-      p.close();
-    }
-    
-    return 0;
-  }
-  
-  private static String encode(final boolean encode, final Text text) {
-    if (text == null) {
-      return null;
-    }
-    BinaryFormatter.getlength(text.getLength());
-    return encode ? new String(Base64.encodeBase64(TextUtil.getBytes(text)), StandardCharsets.UTF_8) : BinaryFormatter.appendText(new StringBuilder(), text).toString();
-  }
-  
-  private static String obscuredTabletName(final KeyExtent extent) {
-    MessageDigest digester;
-    try {
-      digester = MessageDigest.getInstance("MD5");
-    } catch (NoSuchAlgorithmException e) {
-      throw new RuntimeException(e);
-    }
-    if (extent.getEndRow() != null && extent.getEndRow().getLength() > 0) {
-      digester.update(extent.getEndRow().getBytes(), 0, extent.getEndRow().getLength());
-    }
-    return new String(Base64.encodeBase64(digester.digest()), StandardCharsets.UTF_8);
-  }
-  
-  @Override
-  public String description() {
-    return "retrieves the current split points for tablets in the current table";
-  }
-  
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options opts = new Options();
-    
-    outputFileOpt = new Option("o", "output", true, "local file to write the splits to");
-    outputFileOpt.setArgName("file");
-    
-    maxSplitsOpt = new Option("m", "max", true, "maximum number of splits to return (evenly spaced)");
-    maxSplitsOpt.setArgName("num");
-    
-    base64Opt = new Option("b64", "base64encoded", false, "encode the split points");
-    
-    verboseOpt = new Option("v", "verbose", false, "print out the tablet information with start/end rows");
-    
-    opts.addOption(outputFileOpt);
-    opts.addOption(maxSplitsOpt);
-    opts.addOption(base64Opt);
-    opts.addOption(verboseOpt);
-    opts.addOption(OptUtil.tableOpt("table to get splits for"));
-    
-    return opts;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/GrantCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/GrantCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/GrantCommand.java
deleted file mode 100644
index 8f4448f..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/GrantCommand.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.accumulo.shell.commands;
-
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.accumulo.core.security.NamespacePermission;
-import org.apache.accumulo.core.security.SystemPermission;
-import org.apache.accumulo.core.security.TablePermission;
-import org.apache.accumulo.core.util.BadArgumentException;
-import org.apache.accumulo.shell.Shell;
-import org.apache.accumulo.shell.Token;
-import org.apache.accumulo.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.OptionGroup;
-import org.apache.commons.cli.Options;
-
-public class GrantCommand extends TableOperation {
-  {
-    disableUnflaggedTableOptions();
-  }
-
-  private Option systemOpt, userOpt;
-  private String user;
-  private String[] permission;
-
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    user = cl.hasOption(userOpt.getOpt()) ? cl.getOptionValue(userOpt.getOpt()) : shellState.getConnector().whoami();
-
-    permission = cl.getArgs()[0].split("\\.", 2);
-    if (cl.hasOption(systemOpt.getOpt()) && permission[0].equalsIgnoreCase("System")) {
-      try {
-        shellState.getConnector().securityOperations().grantSystemPermission(user, SystemPermission.valueOf(permission[1]));
-        Shell.log.debug("Granted " + user + " the " + permission[1] + " permission");
-      } catch (IllegalArgumentException e) {
-        throw new BadArgumentException("No such system permission", fullCommand, fullCommand.indexOf(cl.getArgs()[0]));
-      }
-    } else if (permission[0].equalsIgnoreCase("Table")) {
-      super.execute(fullCommand, cl, shellState);
-    } else if (permission[0].equalsIgnoreCase("Namespace")) {
-      if (cl.hasOption(optNamespace.getOpt())) {
-        try {
-          shellState.getConnector().securityOperations()
-              .grantNamespacePermission(user, cl.getOptionValue(optNamespace.getOpt()), NamespacePermission.valueOf(permission[1]));
-        } catch (IllegalArgumentException e) {
-          throw new BadArgumentException("No such namespace permission", fullCommand, fullCommand.indexOf(cl.getArgs()[0]));
-        }
-      } else {
-        throw new BadArgumentException("No namespace specified to apply permission to", fullCommand, fullCommand.indexOf(cl.getArgs()[0]));
-      }
-    } else {
-      throw new BadArgumentException("Unrecognized permission", fullCommand, fullCommand.indexOf(cl.getArgs()[0]));
-    }
-    return 0;
-  }
-
-  @Override
-  protected void doTableOp(final Shell shellState, final String tableName) throws Exception {
-    try {
-      shellState.getConnector().securityOperations().grantTablePermission(user, tableName, TablePermission.valueOf(permission[1]));
-      Shell.log.debug("Granted " + user + " the " + permission[1] + " permission on table " + tableName);
-    } catch (IllegalArgumentException e) {
-      throw new IllegalArgumentException("No such table permission", e);
-    }
-  }
-
-  @Override
-  public String description() {
-    return "grants system, table, or namespace permissions for a user";
-  }
-
-  @Override
-  public String usage() {
-    return getName() + " <permission>";
-  }
-
-  @Override
-  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> completionSet) {
-    final Token cmd = new Token(getName());
-    cmd.addSubcommand(new Token(TablePermission.printableValues()));
-    cmd.addSubcommand(new Token(SystemPermission.printableValues()));
-    cmd.addSubcommand(new Token(NamespacePermission.printableValues()));
-    root.addSubcommand(cmd);
-  }
-
-  @Override
-  public Options getOptions() {
-    super.getOptions();
-    final Options o = new Options();
-
-    final OptionGroup group = new OptionGroup();
-
-    systemOpt = new Option("s", "system", false, "grant a system permission");
-
-    optNamespace = new Option(Shell.namespaceOption, "namespace", true, "name of a namespace to operate on");
-    optNamespace.setArgName("namespace");
-
-    group.addOption(systemOpt);
-    group.addOption(optTableName);
-    group.addOption(optTablePattern);
-    group.addOption(optNamespace);
-
-    o.addOptionGroup(group);
-    userOpt = new Option(Shell.userOption, "user", true, "user to operate on");
-    userOpt.setArgName("username");
-    userOpt.setRequired(true);
-    o.addOption(userOpt);
-
-    return o;
-  }
-
-  @Override
-  public int numArgs() {
-    return 1;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/GrepCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/GrepCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/GrepCommand.java
deleted file mode 100644
index 1a3c484..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/GrepCommand.java
+++ /dev/null
@@ -1,111 +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.accumulo.shell.commands;
-
-import java.io.IOException;
-import java.util.Collections;
-import java.util.concurrent.TimeUnit;
-
-import org.apache.accumulo.core.client.BatchScanner;
-import org.apache.accumulo.core.client.IteratorSetting;
-import org.apache.accumulo.core.iterators.user.GrepIterator;
-import org.apache.accumulo.core.security.Authorizations;
-import org.apache.accumulo.core.util.format.Formatter;
-import org.apache.accumulo.core.util.interpret.ScanInterpreter;
-import org.apache.accumulo.shell.Shell;
-import org.apache.accumulo.shell.Shell.PrintFile;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.MissingArgumentException;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-
-public class GrepCommand extends ScanCommand {
-  
-  private Option numThreadsOpt;
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    final PrintFile printFile = getOutputFile(cl);
-    
-    final String tableName = OptUtil.getTableOpt(cl, shellState);
-    
-    if (cl.getArgList().isEmpty()) {
-      throw new MissingArgumentException("No terms specified");
-    }
-    final Class<? extends Formatter> formatter = getFormatter(cl, tableName, shellState);
-    final ScanInterpreter interpeter = getInterpreter(cl, tableName, shellState);
-    
-    // handle first argument, if present, the authorizations list to
-    // scan with
-    int numThreads = 20;
-    if (cl.hasOption(numThreadsOpt.getOpt())) {
-      numThreads = Integer.parseInt(cl.getOptionValue(numThreadsOpt.getOpt()));
-    }
-    final Authorizations auths = getAuths(cl, shellState);
-    final BatchScanner scanner = shellState.getConnector().createBatchScanner(tableName, auths, numThreads);
-    scanner.setRanges(Collections.singletonList(getRange(cl, interpeter)));
-    
-    scanner.setTimeout(getTimeout(cl), TimeUnit.MILLISECONDS);
-    
-    for (int i = 0; i < cl.getArgs().length; i++) {
-      setUpIterator(Integer.MAX_VALUE - cl.getArgs().length + i, "grep" + i, cl.getArgs()[i], scanner, cl);
-    }
-    try {
-      // handle columns
-      fetchColumns(cl, scanner, interpeter);
-      
-      // output the records
-      printRecords(cl, shellState, scanner, formatter, printFile);
-    } finally {
-      scanner.close();
-    }
-    
-    return 0;
-  }
-  
-  protected void setUpIterator(final int prio, final String name, final String term, final BatchScanner scanner, CommandLine cl) throws IOException {
-    if (prio < 0) {
-      throw new IllegalArgumentException("Priority < 0 " + prio);
-    }
-    final IteratorSetting grep = new IteratorSetting(prio, name, GrepIterator.class);
-    GrepIterator.setTerm(grep, term);
-    scanner.addScanIterator(grep);
-  }
-  
-  @Override
-  public String description() {
-    return "searches each row, column family, column qualifier and value in a table for a substring (not a regular expression), in parallel, on the server side";
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options opts = super.getOptions();
-    numThreadsOpt = new Option("nt", "num-threads", true, "number of threads to use");
-    opts.addOption(numThreadsOpt);
-    return opts;
-  }
-  
-  @Override
-  public String usage() {
-    return getName() + " <term>{ <term>}";
-  }
-  
-  @Override
-  public int numArgs() {
-    return Shell.NO_FIXED_ARG_LENGTH_CHECK;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/HelpCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/HelpCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/HelpCommand.java
deleted file mode 100644
index 90e8c4f..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/HelpCommand.java
+++ /dev/null
@@ -1,129 +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.accumulo.shell.commands;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-
-import org.apache.accumulo.shell.Shell;
-import org.apache.accumulo.shell.ShellCommandException;
-import org.apache.accumulo.shell.Token;
-import org.apache.accumulo.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-
-public class HelpCommand extends Command {
-  private Option disablePaginationOpt;
-  private Option noWrapOpt;
-  
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws ShellCommandException, IOException {
-    int numColumns = shellState.getReader().getTerminal().getWidth();
-    if (cl.hasOption(noWrapOpt.getOpt())) {
-      numColumns = Integer.MAX_VALUE;
-    }
-    // print help summary
-    if (cl.getArgs().length == 0) {
-      int i = 0;
-      for (String cmd : shellState.commandFactory.keySet()) {
-        i = Math.max(i, cmd.length());
-      }
-      if (numColumns < 40) {
-        throw new IllegalArgumentException("numColumns must be at least 40 (was " + numColumns + ")");
-      }
-      final ArrayList<String> output = new ArrayList<String>();
-      for (Entry<String,Command[]> cmdGroup : shellState.commandGrouping.entrySet()) {
-        output.add(cmdGroup.getKey());
-        for (Command c : cmdGroup.getValue()) {
-          String n = c.getName();
-          String s = c.description();
-          if (s == null) {
-            s = "";
-          }
-          int beginIndex = 0;
-          int endIndex = s.length();
-          while (beginIndex < endIndex && s.charAt(beginIndex) == ' ')
-            beginIndex++;
-          String dash = "-";
-          while (endIndex > beginIndex && endIndex - beginIndex + i + 5 > numColumns) {
-            endIndex = s.lastIndexOf(" ", numColumns + beginIndex - i - 5);
-            if (endIndex == -1 || endIndex < beginIndex) {
-              endIndex = numColumns + beginIndex - i - 5 - 1;
-              output.add(String.format("%-" + i + "s  %s  %s-", n, dash, s.substring(beginIndex, endIndex)));
-              dash = " ";
-              beginIndex = endIndex;
-            } else {
-              output.add(String.format("%-" + i + "s  %s  %s", n, dash, s.substring(beginIndex, endIndex)));
-              dash = " ";
-              beginIndex = endIndex + 1;
-            }
-            n = "";
-            endIndex = s.length();
-            while (beginIndex < endIndex && s.charAt(beginIndex) == ' ') {
-              beginIndex++;
-            }
-          }
-          output.add(String.format("%-" + i + "s  %s  %s", n, dash, s.substring(beginIndex, endIndex)));
-        }
-        output.add("");
-      }
-      shellState.printLines(output.iterator(), !cl.hasOption(disablePaginationOpt.getOpt()));
-    }
-    
-    // print help for every command on command line
-    for (String cmd : cl.getArgs()) {
-      final Command c = shellState.commandFactory.get(cmd);
-      if (c == null) {
-        shellState.getReader().println(String.format("Unknown command \"%s\".  Enter \"help\" for a list possible commands.", cmd));
-      } else {
-        c.printHelp(shellState, numColumns);
-      }
-    }
-    return 0;
-  }
-  
-  public String description() {
-    return "provides information about the available commands";
-  }
-  
-  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> special) {
-    registerCompletionForCommands(root, special);
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-    disablePaginationOpt = new Option("np", "no-pagination", false, "disable pagination of output");
-    o.addOption(disablePaginationOpt);
-    noWrapOpt = new Option("nw", "no-wrap", false, "disable wrapping of output");
-    o.addOption(noWrapOpt);
-    return o;
-  }
-  
-  @Override
-  public String usage() {
-    return getName() + " [ <command>{ <command>} ]";
-  }
-  
-  @Override
-  public int numArgs() {
-    return Shell.NO_FIXED_ARG_LENGTH_CHECK;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/HiddenCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/HiddenCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/HiddenCommand.java
deleted file mode 100644
index 824517d..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/HiddenCommand.java
+++ /dev/null
@@ -1,62 +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.accumulo.shell.commands;
-
-import java.nio.charset.StandardCharsets;
-import java.security.SecureRandom;
-import java.util.Random;
-
-import org.apache.accumulo.shell.Shell;
-import org.apache.accumulo.shell.ShellCommandException;
-import org.apache.accumulo.shell.Shell.Command;
-import org.apache.accumulo.shell.ShellCommandException.ErrorCode;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.codec.binary.Base64;
-
-public class HiddenCommand extends Command {
-  private static Random rand = new SecureRandom();
-  
-  @Override
-  public String description() {
-    return "The first rule of Accumulo is: \"You don't talk about Accumulo.\"";
-  }
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    if (rand.nextInt(10) == 0) {
-      shellState.getReader().beep();
-      shellState.getReader().println();
-      shellState.getReader().println(
-          new String(Base64.decodeBase64(("ICAgICAgIC4tLS4KICAgICAgLyAvXCBcCiAgICAgKCAvLS1cICkKICAgICAuPl8gIF88LgogICAgLyB8ICd8ICcgXAog"
-              + "ICAvICB8Xy58Xy4gIFwKICAvIC98ICAgICAgfFwgXAogfCB8IHwgfFwvfCB8IHwgfAogfF98IHwgfCAgfCB8IHxffAogICAgIC8gIF9fICBcCiAgICAvICAv"
-              + "ICBcICBcCiAgIC8gIC8gICAgXCAgXF8KIHwvICAvICAgICAgXCB8IHwKIHxfXy8gICAgICAgIFx8X3wK").getBytes(StandardCharsets.UTF_8)), StandardCharsets.UTF_8));
-    } else {
-      throw new ShellCommandException(ErrorCode.UNRECOGNIZED_COMMAND, getName());
-    }
-    return 0;
-  }
-  
-  @Override
-  public int numArgs() {
-    return Shell.NO_FIXED_ARG_LENGTH_CHECK;
-  }
-  
-  @Override
-  public String getName() {
-    return "accvmvlo";
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/HistoryCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/HistoryCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/HistoryCommand.java
deleted file mode 100644
index 1c1314a..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/HistoryCommand.java
+++ /dev/null
@@ -1,82 +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.accumulo.shell.commands;
-
-import java.io.IOException;
-import java.util.Iterator;
-import java.util.ListIterator;
-
-import jline.console.history.History.Entry;
-
-import org.apache.accumulo.shell.Shell;
-import org.apache.accumulo.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-import org.apache.commons.collections.iterators.AbstractIteratorDecorator;
-
-public class HistoryCommand extends Command {
-  private Option clearHist;
-  private Option disablePaginationOpt;
-  
-  @SuppressWarnings("unchecked")
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws IOException {
-    if (cl.hasOption(clearHist.getOpt())) {
-      shellState.getReader().getHistory().clear();
-    } else {
-      ListIterator<Entry> it = shellState.getReader().getHistory().entries();
-      shellState.printLines(new HistoryLineIterator(it), !cl.hasOption(disablePaginationOpt.getOpt()));
-    }
-    
-    return 0;
-  }
-  
-  /**
-   * Decorator that converts an Iterator<History.Entry> to an Iterator<String>.
-   */
-  private static class HistoryLineIterator extends AbstractIteratorDecorator {
-    public HistoryLineIterator(Iterator<Entry> iterator) {
-      super(iterator);
-    }
-    
-    @Override
-    public String next() {
-      return super.next().toString();
-    }
-  }
-  
-  @Override
-  public String description() {
-    return ("generates a list of commands previously executed");
-  }
-  
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-    clearHist = new Option("c", "clear", false, "clear history file");
-    o.addOption(clearHist);
-    disablePaginationOpt = new Option("np", "no-pagination", false, "disable pagination of output");
-    o.addOption(disablePaginationOpt);
-    return o;
-  }
-}


[14/53] [abbrv] git commit: ACCUMULO-1897 Move shell into new package and module

Posted by el...@apache.org.
ACCUMULO-1897 Move shell into new package and module


Project: http://git-wip-us.apache.org/repos/asf/accumulo/repo
Commit: http://git-wip-us.apache.org/repos/asf/accumulo/commit/bcc9e7e4
Tree: http://git-wip-us.apache.org/repos/asf/accumulo/tree/bcc9e7e4
Diff: http://git-wip-us.apache.org/repos/asf/accumulo/diff/bcc9e7e4

Branch: refs/heads/ACCUMULO-378
Commit: bcc9e7e41c9a40cc36502fece266780c7cba0de8
Parents: 3a8f620
Author: Mike Drob <md...@cloudera.com>
Authored: Fri Apr 4 23:41:46 2014 -0700
Committer: Mike Drob <md...@cloudera.com>
Committed: Mon Apr 7 17:01:41 2014 -0400

----------------------------------------------------------------------
 core/pom.xml                                    |   19 -
 .../accumulo/core/client/mock/MockShell.java    |  142 ---
 .../core/util/format/DeleterFormatter.java      |  101 --
 .../apache/accumulo/core/util/shell/Shell.java  | 1168 ------------------
 .../core/util/shell/ShellCommandException.java  |   59 -
 .../core/util/shell/ShellCompletor.java         |  162 ---
 .../core/util/shell/ShellExtension.java         |   27 -
 .../accumulo/core/util/shell/ShellOptions.java  |   33 -
 .../core/util/shell/ShellOptionsJC.java         |  280 -----
 .../accumulo/core/util/shell/ShellUtil.java     |   60 -
 .../apache/accumulo/core/util/shell/Token.java  |  137 --
 .../core/util/shell/commands/AboutCommand.java  |   56 -
 .../commands/ActiveCompactionIterator.java      |  136 --
 .../util/shell/commands/ActiveScanIterator.java |   91 --
 .../util/shell/commands/AddAuthsCommand.java    |   82 --
 .../util/shell/commands/AddSplitsCommand.java   |   88 --
 .../shell/commands/AuthenticateCommand.java     |   66 -
 .../core/util/shell/commands/ByeCommand.java    |   19 -
 .../util/shell/commands/ClasspathCommand.java   |   55 -
 .../core/util/shell/commands/ClearCommand.java  |   52 -
 .../util/shell/commands/CloneTableCommand.java  |  102 --
 .../core/util/shell/commands/ClsCommand.java    |   19 -
 .../util/shell/commands/CompactCommand.java     |  129 --
 .../core/util/shell/commands/ConfigCommand.java |  315 -----
 .../util/shell/commands/ConstraintCommand.java  |  134 --
 .../shell/commands/CreateNamespaceCommand.java  |   99 --
 .../util/shell/commands/CreateTableCommand.java |  203 ---
 .../util/shell/commands/CreateUserCommand.java  |   76 --
 .../core/util/shell/commands/DUCommand.java     |  124 --
 .../core/util/shell/commands/DebugCommand.java  |   71 --
 .../core/util/shell/commands/DeleteCommand.java |  112 --
 .../util/shell/commands/DeleteIterCommand.java  |  114 --
 .../util/shell/commands/DeleteManyCommand.java  |   82 --
 .../shell/commands/DeleteNamespaceCommand.java  |  100 --
 .../util/shell/commands/DeleteRowsCommand.java  |   65 -
 .../shell/commands/DeleteScanIterCommand.java   |  102 --
 .../shell/commands/DeleteShellIterCommand.java  |  100 --
 .../util/shell/commands/DeleteTableCommand.java |   60 -
 .../util/shell/commands/DeleteUserCommand.java  |   19 -
 .../util/shell/commands/DropTableCommand.java   |   19 -
 .../util/shell/commands/DropUserCommand.java    |   61 -
 .../core/util/shell/commands/EGrepCommand.java  |   59 -
 .../util/shell/commands/ExecfileCommand.java    |   67 -
 .../core/util/shell/commands/ExitCommand.java   |   39 -
 .../util/shell/commands/ExportTableCommand.java |   78 --
 .../util/shell/commands/ExtensionCommand.java   |  102 --
 .../core/util/shell/commands/FateCommand.java   |  180 ---
 .../core/util/shell/commands/FlushCommand.java  |   63 -
 .../util/shell/commands/FormatterCommand.java   |   69 --
 .../util/shell/commands/GetAuthsCommand.java    |   67 -
 .../util/shell/commands/GetGroupsCommand.java   |   60 -
 .../util/shell/commands/GetSplitsCommand.java   |  155 ---
 .../core/util/shell/commands/GrantCommand.java  |  133 --
 .../core/util/shell/commands/GrepCommand.java   |  111 --
 .../core/util/shell/commands/HelpCommand.java   |  129 --
 .../core/util/shell/commands/HiddenCommand.java |   62 -
 .../util/shell/commands/HistoryCommand.java     |   82 --
 .../shell/commands/ImportDirectoryCommand.java  |   58 -
 .../util/shell/commands/ImportTableCommand.java |   51 -
 .../core/util/shell/commands/InfoCommand.java   |   19 -
 .../core/util/shell/commands/InsertCommand.java |  148 ---
 .../util/shell/commands/InterpreterCommand.java |   40 -
 .../shell/commands/ListCompactionsCommand.java  |   78 --
 .../util/shell/commands/ListIterCommand.java    |  140 ---
 .../util/shell/commands/ListScansCommand.java   |   78 --
 .../shell/commands/ListShellIterCommand.java    |  105 --
 .../core/util/shell/commands/MaxRowCommand.java |   55 -
 .../core/util/shell/commands/MergeCommand.java  |  111 --
 .../commands/NamespacePermissionsCommand.java   |   44 -
 .../util/shell/commands/NamespacesCommand.java  |   83 --
 .../util/shell/commands/NoTableCommand.java     |   40 -
 .../util/shell/commands/OfflineCommand.java     |   61 -
 .../core/util/shell/commands/OnlineCommand.java |   61 -
 .../core/util/shell/commands/OptUtil.java       |  146 ---
 .../core/util/shell/commands/PasswdCommand.java |   96 --
 .../core/util/shell/commands/PingCommand.java   |   82 --
 .../core/util/shell/commands/PingIterator.java  |   58 -
 .../util/shell/commands/QuestionCommand.java    |   24 -
 .../core/util/shell/commands/QuitCommand.java   |   19 -
 .../shell/commands/QuotedStringTokenizer.java   |  141 ---
 .../shell/commands/RenameNamespaceCommand.java  |   79 --
 .../util/shell/commands/RenameTableCommand.java |   62 -
 .../core/util/shell/commands/RevokeCommand.java |  133 --
 .../core/util/shell/commands/ScanCommand.java   |  334 -----
 .../core/util/shell/commands/ScriptCommand.java |  290 -----
 .../util/shell/commands/SetAuthsCommand.java    |   77 --
 .../util/shell/commands/SetGroupsCommand.java   |   78 --
 .../util/shell/commands/SetIterCommand.java     |  453 -------
 .../util/shell/commands/SetScanIterCommand.java |  127 --
 .../shell/commands/SetShellIterCommand.java     |  131 --
 .../ShellPluginConfigurationCommand.java        |  146 ---
 .../core/util/shell/commands/SleepCommand.java  |   46 -
 .../commands/SystemPermissionsCommand.java      |   44 -
 .../core/util/shell/commands/TableCommand.java  |   60 -
 .../util/shell/commands/TableOperation.java     |  153 ---
 .../shell/commands/TablePermissionsCommand.java |   44 -
 .../core/util/shell/commands/TablesCommand.java |  107 --
 .../core/util/shell/commands/TraceCommand.java  |  101 --
 .../core/util/shell/commands/UserCommand.java   |   71 --
 .../shell/commands/UserPermissionsCommand.java  |  106 --
 .../core/util/shell/commands/UsersCommand.java  |   45 -
 .../core/util/shell/commands/WhoAmICommand.java |   41 -
 .../core/util/format/DeleterFormatterTest.java  |  176 ---
 .../core/util/shell/PasswordConverterTest.java  |  113 --
 .../core/util/shell/ShellConfigTest.java        |   90 --
 .../core/util/shell/ShellSetInstanceTest.java   |  242 ----
 .../accumulo/core/util/shell/ShellTest.java     |  281 -----
 .../accumulo/core/util/shell/ShellUtilTest.java |   66 -
 .../shell/command/FormatterCommandTest.java     |  184 ---
 core/src/test/resources/shelltest.txt           |   16 -
 examples/simple/pom.xml                         |    4 +
 .../examples/simple/shell/DebugCommand.java     |    4 +-
 .../simple/shell/MyAppShellExtension.java       |    4 +-
 pom.xml                                         |    6 +
 server/monitor/pom.xml                          |    4 +
 .../accumulo/monitor/servlets/ShellServlet.java |    2 +-
 shell/pom.xml                                   |  123 ++
 .../java/org/apache/accumulo/shell/Shell.java   | 1168 ++++++++++++++++++
 .../accumulo/shell/ShellCommandException.java   |   59 +
 .../apache/accumulo/shell/ShellCompletor.java   |  162 +++
 .../apache/accumulo/shell/ShellExtension.java   |   27 +
 .../org/apache/accumulo/shell/ShellOptions.java |   33 +
 .../apache/accumulo/shell/ShellOptionsJC.java   |  280 +++++
 .../org/apache/accumulo/shell/ShellUtil.java    |   60 +
 .../java/org/apache/accumulo/shell/Token.java   |  137 ++
 .../accumulo/shell/commands/AboutCommand.java   |   56 +
 .../commands/ActiveCompactionIterator.java      |  136 ++
 .../shell/commands/ActiveScanIterator.java      |   91 ++
 .../shell/commands/AddAuthsCommand.java         |   82 ++
 .../shell/commands/AddSplitsCommand.java        |   88 ++
 .../shell/commands/AuthenticateCommand.java     |   66 +
 .../accumulo/shell/commands/ByeCommand.java     |   19 +
 .../shell/commands/ClasspathCommand.java        |   55 +
 .../accumulo/shell/commands/ClearCommand.java   |   52 +
 .../shell/commands/CloneTableCommand.java       |  102 ++
 .../accumulo/shell/commands/ClsCommand.java     |   19 +
 .../accumulo/shell/commands/CompactCommand.java |  129 ++
 .../accumulo/shell/commands/ConfigCommand.java  |  315 +++++
 .../shell/commands/ConstraintCommand.java       |  134 ++
 .../shell/commands/CreateNamespaceCommand.java  |   99 ++
 .../shell/commands/CreateTableCommand.java      |  203 +++
 .../shell/commands/CreateUserCommand.java       |   76 ++
 .../accumulo/shell/commands/DUCommand.java      |  124 ++
 .../accumulo/shell/commands/DebugCommand.java   |   71 ++
 .../accumulo/shell/commands/DeleteCommand.java  |  112 ++
 .../shell/commands/DeleteIterCommand.java       |  114 ++
 .../shell/commands/DeleteManyCommand.java       |   82 ++
 .../shell/commands/DeleteNamespaceCommand.java  |  100 ++
 .../shell/commands/DeleteRowsCommand.java       |   65 +
 .../shell/commands/DeleteScanIterCommand.java   |  102 ++
 .../shell/commands/DeleteShellIterCommand.java  |  100 ++
 .../shell/commands/DeleteTableCommand.java      |   60 +
 .../shell/commands/DeleteUserCommand.java       |   19 +
 .../shell/commands/DropTableCommand.java        |   19 +
 .../shell/commands/DropUserCommand.java         |   61 +
 .../accumulo/shell/commands/EGrepCommand.java   |   59 +
 .../shell/commands/ExecfileCommand.java         |   67 +
 .../accumulo/shell/commands/ExitCommand.java    |   39 +
 .../shell/commands/ExportTableCommand.java      |   78 ++
 .../shell/commands/ExtensionCommand.java        |  102 ++
 .../accumulo/shell/commands/FateCommand.java    |  180 +++
 .../accumulo/shell/commands/FlushCommand.java   |   63 +
 .../shell/commands/FormatterCommand.java        |   69 ++
 .../shell/commands/GetAuthsCommand.java         |   67 +
 .../shell/commands/GetGroupsCommand.java        |   60 +
 .../shell/commands/GetSplitsCommand.java        |  155 +++
 .../accumulo/shell/commands/GrantCommand.java   |  133 ++
 .../accumulo/shell/commands/GrepCommand.java    |  111 ++
 .../accumulo/shell/commands/HelpCommand.java    |  129 ++
 .../accumulo/shell/commands/HiddenCommand.java  |   62 +
 .../accumulo/shell/commands/HistoryCommand.java |   82 ++
 .../shell/commands/ImportDirectoryCommand.java  |   58 +
 .../shell/commands/ImportTableCommand.java      |   51 +
 .../accumulo/shell/commands/InfoCommand.java    |   19 +
 .../accumulo/shell/commands/InsertCommand.java  |  148 +++
 .../shell/commands/InterpreterCommand.java      |   40 +
 .../shell/commands/ListCompactionsCommand.java  |   78 ++
 .../shell/commands/ListIterCommand.java         |  140 +++
 .../shell/commands/ListScansCommand.java        |   78 ++
 .../shell/commands/ListShellIterCommand.java    |  105 ++
 .../accumulo/shell/commands/MaxRowCommand.java  |   55 +
 .../accumulo/shell/commands/MergeCommand.java   |  111 ++
 .../commands/NamespacePermissionsCommand.java   |   44 +
 .../shell/commands/NamespacesCommand.java       |   83 ++
 .../accumulo/shell/commands/NoTableCommand.java |   40 +
 .../accumulo/shell/commands/OfflineCommand.java |   61 +
 .../accumulo/shell/commands/OnlineCommand.java  |   61 +
 .../apache/accumulo/shell/commands/OptUtil.java |  146 +++
 .../accumulo/shell/commands/PasswdCommand.java  |   96 ++
 .../accumulo/shell/commands/PingCommand.java    |   82 ++
 .../accumulo/shell/commands/PingIterator.java   |   58 +
 .../shell/commands/QuestionCommand.java         |   24 +
 .../accumulo/shell/commands/QuitCommand.java    |   19 +
 .../shell/commands/QuotedStringTokenizer.java   |  141 +++
 .../shell/commands/RenameNamespaceCommand.java  |   79 ++
 .../shell/commands/RenameTableCommand.java      |   62 +
 .../accumulo/shell/commands/RevokeCommand.java  |  133 ++
 .../accumulo/shell/commands/ScanCommand.java    |  334 +++++
 .../accumulo/shell/commands/ScriptCommand.java  |  290 +++++
 .../shell/commands/SetAuthsCommand.java         |   77 ++
 .../shell/commands/SetGroupsCommand.java        |   78 ++
 .../accumulo/shell/commands/SetIterCommand.java |  453 +++++++
 .../shell/commands/SetScanIterCommand.java      |  127 ++
 .../shell/commands/SetShellIterCommand.java     |  131 ++
 .../ShellPluginConfigurationCommand.java        |  146 +++
 .../accumulo/shell/commands/SleepCommand.java   |   46 +
 .../commands/SystemPermissionsCommand.java      |   44 +
 .../accumulo/shell/commands/TableCommand.java   |   60 +
 .../accumulo/shell/commands/TableOperation.java |  153 +++
 .../shell/commands/TablePermissionsCommand.java |   44 +
 .../accumulo/shell/commands/TablesCommand.java  |  107 ++
 .../accumulo/shell/commands/TraceCommand.java   |  101 ++
 .../accumulo/shell/commands/UserCommand.java    |   71 ++
 .../shell/commands/UserPermissionsCommand.java  |  106 ++
 .../accumulo/shell/commands/UsersCommand.java   |   45 +
 .../accumulo/shell/commands/WhoAmICommand.java  |   41 +
 .../accumulo/shell/format/DeleterFormatter.java |  102 ++
 .../apache/accumulo/shell/mock/MockShell.java   |  143 +++
 shell/src/main/resources/.gitignore             |    0
 .../accumulo/shell/PasswordConverterTest.java   |  113 ++
 .../apache/accumulo/shell/ShellConfigTest.java  |   91 ++
 .../accumulo/shell/ShellSetInstanceTest.java    |  244 ++++
 .../org/apache/accumulo/shell/ShellTest.java    |  282 +++++
 .../apache/accumulo/shell/ShellUtilTest.java    |   67 +
 .../shell/command/FormatterCommandTest.java     |  184 +++
 .../shell/format/DeleterFormatterTest.java      |  177 +++
 shell/src/test/resources/log4j.properties       |   28 +
 shell/src/test/resources/shelltest.txt          |   16 +
 .../java/org/apache/accumulo/start/Main.java    |    2 +-
 .../org/apache/accumulo/test/ShellServerIT.java |    2 +-
 230 files changed, 12190 insertions(+), 12036 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/pom.xml
----------------------------------------------------------------------
diff --git a/core/pom.xml b/core/pom.xml
index a89846c..2572fc1 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -35,10 +35,6 @@
       <artifactId>guava</artifactId>
     </dependency>
     <dependency>
-      <groupId>commons-cli</groupId>
-      <artifactId>commons-cli</artifactId>
-    </dependency>
-    <dependency>
       <groupId>commons-codec</groupId>
       <artifactId>commons-codec</artifactId>
     </dependency>
@@ -122,21 +118,6 @@
       <scope>test</scope>
     </dependency>
     <dependency>
-      <groupId>org.powermock</groupId>
-      <artifactId>powermock-api-easymock</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.powermock</groupId>
-      <artifactId>powermock-core</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.powermock</groupId>
-      <artifactId>powermock-module-junit4</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
       <groupId>org.slf4j</groupId>
       <artifactId>slf4j-log4j12</artifactId>
       <scope>test</scope>

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/client/mock/MockShell.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/client/mock/MockShell.java b/core/src/main/java/org/apache/accumulo/core/client/mock/MockShell.java
deleted file mode 100644
index a8061f7..0000000
--- a/core/src/main/java/org/apache/accumulo/core/client/mock/MockShell.java
+++ /dev/null
@@ -1,142 +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.accumulo.core.client.mock;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.nio.charset.StandardCharsets;
-
-import jline.console.ConsoleReader;
-
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.ShellOptionsJC;
-
-/**
- * An Accumulo Shell implementation that allows a developer to attach an InputStream and Writer to the Shell for testing purposes.
- */
-public class MockShell extends Shell {
-  private static final String NEWLINE = "\n";
-  
-  protected InputStream in;
-  protected OutputStream out;
-  
-  public MockShell(InputStream in, OutputStream out) throws IOException {
-    super();
-    this.in = in;
-    this.out = out;
-  }
-  
-  public boolean config(String... args) {
-    configError = super.config(args);
-    
-    // Update the ConsoleReader with the input and output "redirected"
-    try {
-      this.reader = new ConsoleReader(in, out);
-    } catch (Exception e) {
-      printException(e);
-      configError = true;
-    }
-    
-    // Don't need this for testing purposes
-    this.reader.setHistoryEnabled(false);
-    this.reader.setPaginationEnabled(false);
-    
-    // Make the parsing from the client easier;
-    this.verbose = false;
-    return configError;
-  }
-  
-  @Override
-  protected void setInstance(ShellOptionsJC options) {
-    // We always want a MockInstance for this test
-    instance = new MockInstance();
-  }
-  
-  public int start() throws IOException {
-    if (configError)
-      return 1;
-    
-    String input;
-    if (isVerbose())
-      printInfo();
-    
-    if (execFile != null) {
-      java.util.Scanner scanner = new java.util.Scanner(execFile, StandardCharsets.UTF_8.name());
-      try {
-        while (scanner.hasNextLine() && !hasExited()) {
-          execCommand(scanner.nextLine(), true, isVerbose());
-        }
-      } finally {
-        scanner.close();
-      }
-    } else if (execCommand != null) {
-      for (String command : execCommand.split("\n")) {
-        execCommand(command, true, isVerbose());
-      }
-      return exitCode;
-    }
-    
-    while (true) {
-      if (hasExited())
-        return exitCode;
-      
-      reader.setPrompt(getDefaultPrompt());
-      input = reader.readLine();
-      if (input == null) {
-        reader.println();
-        return exitCode;
-      } // user canceled
-      
-      execCommand(input, false, false);
-    }
-  }
-  
-  /**
-   * @param in
-   *          the in to set
-   */
-  public void setConsoleInputStream(InputStream in) {
-    this.in = in;
-  }
-  
-  /**
-   * @param out
-   *          the output stream to set
-   */
-  public void setConsoleWriter(OutputStream out) {
-    this.out = out;
-  }
-  
-  /**
-   * Convenience method to create the byte-array to hand to the console
-   * 
-   * @param commands
-   *          An array of commands to run
-   * @return A byte[] input stream which can be handed to the console.
-   */
-  public static ByteArrayInputStream makeCommands(String... commands) {
-    StringBuilder sb = new StringBuilder(commands.length * 8);
-    
-    for (String command : commands) {
-      sb.append(command).append(NEWLINE);
-    }
-    
-    return new ByteArrayInputStream(sb.toString().getBytes(StandardCharsets.UTF_8));
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/format/DeleterFormatter.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/format/DeleterFormatter.java b/core/src/main/java/org/apache/accumulo/core/util/format/DeleterFormatter.java
deleted file mode 100644
index 7ac0510..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/format/DeleterFormatter.java
+++ /dev/null
@@ -1,101 +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.accumulo.core.util.format;
-
-import java.io.IOException;
-import java.util.Map.Entry;
-
-import org.apache.accumulo.core.client.BatchWriter;
-import org.apache.accumulo.core.client.MutationsRejectedException;
-import org.apache.accumulo.core.data.ConstraintViolationSummary;
-import org.apache.accumulo.core.data.Key;
-import org.apache.accumulo.core.data.Mutation;
-import org.apache.accumulo.core.data.Value;
-import org.apache.accumulo.core.security.ColumnVisibility;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.log4j.Logger;
-
-public class DeleterFormatter extends DefaultFormatter {
-  
-  private static final Logger log = Logger.getLogger(DeleterFormatter.class);
-  private BatchWriter writer;
-  private Shell shellState;
-  private boolean printTimestamps;
-  private boolean force;
-  private boolean more;
-  
-  public DeleterFormatter(BatchWriter writer, Iterable<Entry<Key,Value>> scanner, boolean printTimestamps, Shell shellState, boolean force) {
-    super.initialize(scanner, printTimestamps);
-    this.writer = writer;
-    this.shellState = shellState;
-    this.printTimestamps = printTimestamps;
-    this.force = force;
-    this.more = true;
-  }
-  
-  @Override
-  public boolean hasNext() {
-    if (!getScannerIterator().hasNext() || !more) {
-      try {
-        writer.close();
-      } catch (MutationsRejectedException e) {
-        log.error(e.toString());
-        if (Shell.isDebuggingEnabled())
-          for (ConstraintViolationSummary cvs : e.getConstraintViolationSummaries())
-            log.trace(cvs.toString());
-      }
-      return false;
-    }
-    return true;
-  }
-  
-  /**
-   * @return null, because the iteration will provide prompts and handle deletes internally.
-   */
-  @Override
-  public String next() {
-    Entry<Key,Value> next = getScannerIterator().next();
-    Key key = next.getKey();
-    Mutation m = new Mutation(key.getRow());
-    String entryStr = formatEntry(next, printTimestamps);
-    boolean delete = force;
-    try {
-      if (!force) {
-        shellState.getReader().flush();
-        String line = shellState.getReader().readLine("Delete { " + entryStr + " } ? ");
-        more = line != null;
-        delete = line != null && (line.equalsIgnoreCase("y") || line.equalsIgnoreCase("yes"));
-      }
-      if (delete) {
-        m.putDelete(key.getColumnFamily(), key.getColumnQualifier(), new ColumnVisibility(key.getColumnVisibility()), key.getTimestamp());
-        try {
-          writer.addMutation(m);
-        } catch (MutationsRejectedException e) {
-          log.error(e.toString());
-          if (Shell.isDebuggingEnabled())
-            for (ConstraintViolationSummary cvs : e.getConstraintViolationSummaries())
-              log.trace(cvs.toString());
-        }
-      }
-      shellState.getReader().print(String.format("[%s] %s%n", delete ? "DELETED" : "SKIPPED", entryStr));
-    } catch (IOException e) {
-      log.error("Cannot write to console", e);
-      throw new RuntimeException(e);
-    }
-    return null;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/Shell.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/Shell.java b/core/src/main/java/org/apache/accumulo/core/util/shell/Shell.java
deleted file mode 100644
index f481395..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/Shell.java
+++ /dev/null
@@ -1,1168 +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.accumulo.core.util.shell;
-
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.OutputStreamWriter;
-import java.io.PrintWriter;
-import java.net.InetAddress;
-import java.nio.charset.StandardCharsets;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.TreeMap;
-import java.util.UUID;
-
-import jline.console.ConsoleReader;
-import jline.console.UserInterruptException;
-import jline.console.history.FileHistory;
-
-import org.apache.accumulo.core.Constants;
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.ClientConfiguration;
-import org.apache.accumulo.core.client.ClientConfiguration.ClientProperty;
-import org.apache.accumulo.core.client.Connector;
-import org.apache.accumulo.core.client.Instance;
-import org.apache.accumulo.core.client.IteratorSetting;
-import org.apache.accumulo.core.client.TableNotFoundException;
-import org.apache.accumulo.core.client.ZooKeeperInstance;
-import org.apache.accumulo.core.client.impl.ServerConfigurationUtil;
-import org.apache.accumulo.core.client.impl.Tables;
-import org.apache.accumulo.core.client.mock.MockInstance;
-import org.apache.accumulo.core.client.security.tokens.AuthenticationToken;
-import org.apache.accumulo.core.client.security.tokens.PasswordToken;
-import org.apache.accumulo.core.conf.AccumuloConfiguration;
-import org.apache.accumulo.core.conf.DefaultConfiguration;
-import org.apache.accumulo.core.conf.Property;
-import org.apache.accumulo.core.conf.SiteConfiguration;
-import org.apache.accumulo.core.data.Key;
-import org.apache.accumulo.core.data.Value;
-import org.apache.accumulo.core.data.thrift.TConstraintViolationSummary;
-import org.apache.accumulo.core.tabletserver.thrift.ConstraintViolationException;
-import org.apache.accumulo.core.trace.DistributedTrace;
-import org.apache.accumulo.core.util.BadArgumentException;
-import org.apache.accumulo.core.util.format.BinaryFormatter;
-import org.apache.accumulo.core.util.format.DefaultFormatter;
-import org.apache.accumulo.core.util.format.Formatter;
-import org.apache.accumulo.core.util.format.FormatterFactory;
-import org.apache.accumulo.core.util.shell.commands.AboutCommand;
-import org.apache.accumulo.core.util.shell.commands.AddAuthsCommand;
-import org.apache.accumulo.core.util.shell.commands.AddSplitsCommand;
-import org.apache.accumulo.core.util.shell.commands.AuthenticateCommand;
-import org.apache.accumulo.core.util.shell.commands.ByeCommand;
-import org.apache.accumulo.core.util.shell.commands.ClasspathCommand;
-import org.apache.accumulo.core.util.shell.commands.ClearCommand;
-import org.apache.accumulo.core.util.shell.commands.CloneTableCommand;
-import org.apache.accumulo.core.util.shell.commands.ClsCommand;
-import org.apache.accumulo.core.util.shell.commands.CompactCommand;
-import org.apache.accumulo.core.util.shell.commands.ConfigCommand;
-import org.apache.accumulo.core.util.shell.commands.ConstraintCommand;
-import org.apache.accumulo.core.util.shell.commands.CreateNamespaceCommand;
-import org.apache.accumulo.core.util.shell.commands.CreateTableCommand;
-import org.apache.accumulo.core.util.shell.commands.CreateUserCommand;
-import org.apache.accumulo.core.util.shell.commands.DUCommand;
-import org.apache.accumulo.core.util.shell.commands.DebugCommand;
-import org.apache.accumulo.core.util.shell.commands.DeleteCommand;
-import org.apache.accumulo.core.util.shell.commands.DeleteIterCommand;
-import org.apache.accumulo.core.util.shell.commands.DeleteManyCommand;
-import org.apache.accumulo.core.util.shell.commands.DeleteNamespaceCommand;
-import org.apache.accumulo.core.util.shell.commands.DeleteRowsCommand;
-import org.apache.accumulo.core.util.shell.commands.DeleteScanIterCommand;
-import org.apache.accumulo.core.util.shell.commands.DeleteShellIterCommand;
-import org.apache.accumulo.core.util.shell.commands.DeleteTableCommand;
-import org.apache.accumulo.core.util.shell.commands.DeleteUserCommand;
-import org.apache.accumulo.core.util.shell.commands.DropTableCommand;
-import org.apache.accumulo.core.util.shell.commands.DropUserCommand;
-import org.apache.accumulo.core.util.shell.commands.EGrepCommand;
-import org.apache.accumulo.core.util.shell.commands.ExecfileCommand;
-import org.apache.accumulo.core.util.shell.commands.ExitCommand;
-import org.apache.accumulo.core.util.shell.commands.ExportTableCommand;
-import org.apache.accumulo.core.util.shell.commands.ExtensionCommand;
-import org.apache.accumulo.core.util.shell.commands.FateCommand;
-import org.apache.accumulo.core.util.shell.commands.FlushCommand;
-import org.apache.accumulo.core.util.shell.commands.FormatterCommand;
-import org.apache.accumulo.core.util.shell.commands.GetAuthsCommand;
-import org.apache.accumulo.core.util.shell.commands.GetGroupsCommand;
-import org.apache.accumulo.core.util.shell.commands.GetSplitsCommand;
-import org.apache.accumulo.core.util.shell.commands.GrantCommand;
-import org.apache.accumulo.core.util.shell.commands.GrepCommand;
-import org.apache.accumulo.core.util.shell.commands.HelpCommand;
-import org.apache.accumulo.core.util.shell.commands.HiddenCommand;
-import org.apache.accumulo.core.util.shell.commands.HistoryCommand;
-import org.apache.accumulo.core.util.shell.commands.ImportDirectoryCommand;
-import org.apache.accumulo.core.util.shell.commands.ImportTableCommand;
-import org.apache.accumulo.core.util.shell.commands.InfoCommand;
-import org.apache.accumulo.core.util.shell.commands.InsertCommand;
-import org.apache.accumulo.core.util.shell.commands.InterpreterCommand;
-import org.apache.accumulo.core.util.shell.commands.ListCompactionsCommand;
-import org.apache.accumulo.core.util.shell.commands.ListIterCommand;
-import org.apache.accumulo.core.util.shell.commands.ListScansCommand;
-import org.apache.accumulo.core.util.shell.commands.ListShellIterCommand;
-import org.apache.accumulo.core.util.shell.commands.MaxRowCommand;
-import org.apache.accumulo.core.util.shell.commands.MergeCommand;
-import org.apache.accumulo.core.util.shell.commands.NamespacePermissionsCommand;
-import org.apache.accumulo.core.util.shell.commands.NamespacesCommand;
-import org.apache.accumulo.core.util.shell.commands.NoTableCommand;
-import org.apache.accumulo.core.util.shell.commands.OfflineCommand;
-import org.apache.accumulo.core.util.shell.commands.OnlineCommand;
-import org.apache.accumulo.core.util.shell.commands.PasswdCommand;
-import org.apache.accumulo.core.util.shell.commands.PingCommand;
-import org.apache.accumulo.core.util.shell.commands.QuestionCommand;
-import org.apache.accumulo.core.util.shell.commands.QuitCommand;
-import org.apache.accumulo.core.util.shell.commands.QuotedStringTokenizer;
-import org.apache.accumulo.core.util.shell.commands.RenameNamespaceCommand;
-import org.apache.accumulo.core.util.shell.commands.RenameTableCommand;
-import org.apache.accumulo.core.util.shell.commands.RevokeCommand;
-import org.apache.accumulo.core.util.shell.commands.ScanCommand;
-import org.apache.accumulo.core.util.shell.commands.ScriptCommand;
-import org.apache.accumulo.core.util.shell.commands.SetAuthsCommand;
-import org.apache.accumulo.core.util.shell.commands.SetGroupsCommand;
-import org.apache.accumulo.core.util.shell.commands.SetIterCommand;
-import org.apache.accumulo.core.util.shell.commands.SetScanIterCommand;
-import org.apache.accumulo.core.util.shell.commands.SetShellIterCommand;
-import org.apache.accumulo.core.util.shell.commands.SleepCommand;
-import org.apache.accumulo.core.util.shell.commands.SystemPermissionsCommand;
-import org.apache.accumulo.core.util.shell.commands.TableCommand;
-import org.apache.accumulo.core.util.shell.commands.TablePermissionsCommand;
-import org.apache.accumulo.core.util.shell.commands.TablesCommand;
-import org.apache.accumulo.core.util.shell.commands.TraceCommand;
-import org.apache.accumulo.core.util.shell.commands.UserCommand;
-import org.apache.accumulo.core.util.shell.commands.UserPermissionsCommand;
-import org.apache.accumulo.core.util.shell.commands.UsersCommand;
-import org.apache.accumulo.core.util.shell.commands.WhoAmICommand;
-import org.apache.accumulo.core.volume.VolumeConfiguration;
-import org.apache.accumulo.core.zookeeper.ZooUtil;
-import org.apache.accumulo.fate.zookeeper.ZooReader;
-import org.apache.commons.cli.BasicParser;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.HelpFormatter;
-import org.apache.commons.cli.MissingOptionException;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-import org.apache.commons.cli.ParseException;
-import org.apache.hadoop.fs.Path;
-import org.apache.log4j.Level;
-import org.apache.log4j.Logger;
-
-import com.beust.jcommander.JCommander;
-import com.beust.jcommander.ParameterException;
-
-/**
- * A convenient console interface to perform basic accumulo functions Includes auto-complete, help, and quoted strings with escape sequences
- */
-public class Shell extends ShellOptions {
-  public static final Logger log = Logger.getLogger(Shell.class);
-  private static final Logger audit = Logger.getLogger(Shell.class.getName() + ".audit");
-
-  public static final String CHARSET = "ISO-8859-1";
-  public static final int NO_FIXED_ARG_LENGTH_CHECK = -1;
-  public static final String COMMENT_PREFIX = "#";
-  public static final String HISTORY_DIR_NAME = ".accumulo";
-  public static final String HISTORY_FILE_NAME = "shell_history.txt";
-  private static final String SHELL_DESCRIPTION = "Shell - Apache Accumulo Interactive Shell";
-
-  protected int exitCode = 0;
-  private String tableName;
-  protected Instance instance;
-  private Connector connector;
-  protected ConsoleReader reader;
-  private String principal;
-  private AuthenticationToken token;
-  private final Class<? extends Formatter> defaultFormatterClass = DefaultFormatter.class;
-  private final Class<? extends Formatter> binaryFormatterClass = BinaryFormatter.class;
-  public Map<String,List<IteratorSetting>> scanIteratorOptions = new HashMap<String,List<IteratorSetting>>();
-  public Map<String,List<IteratorSetting>> iteratorProfiles = new HashMap<String,List<IteratorSetting>>();
-
-  private Token rootToken;
-  public final Map<String,Command> commandFactory = new TreeMap<String,Command>();
-  public final Map<String,Command[]> commandGrouping = new TreeMap<String,Command[]>();
-  protected boolean configError = false;
-
-  // exit if true
-  private boolean exit = false;
-
-  // file to execute commands from
-  protected File execFile = null;
-  // single command to execute from the command line
-  protected String execCommand = null;
-  protected boolean verbose = true;
-
-  private boolean tabCompletion;
-  private boolean disableAuthTimeout;
-  private long authTimeout;
-  private long lastUserActivity = System.currentTimeMillis();
-  private boolean logErrorsToConsole = false;
-  private PrintWriter writer = null;
-  private boolean masking = false;
-
-  public Shell() throws IOException {
-    this(new ConsoleReader(), new PrintWriter(
-        new OutputStreamWriter(System.out,
-        System.getProperty("jline.WindowsTerminal.output.encoding", System.getProperty("file.encoding")))));
-  }
-
-  public Shell(ConsoleReader reader, PrintWriter writer) {
-    super();
-    this.reader = reader;
-    this.writer = writer;
-  }
-
-  // Not for client use
-  public boolean config(String... args) {
-    ShellOptionsJC options = new ShellOptionsJC();
-    JCommander jc = new JCommander();
-
-    jc.setProgramName("accumulo shell");
-    jc.addObject(options);
-    try {
-      jc.parse(args);
-    } catch (ParameterException e) {
-      configError = true;
-    }
-
-    if (options.isHelpEnabled()) {
-      configError = true;
-    }
-
-    if (!configError && options.getUnrecognizedOptions() != null) {
-      configError = true;
-      logError("Unrecognized Options: " + options.getUnrecognizedOptions().toString());
-    }
-
-    if (configError) {
-      jc.usage();
-      return true;
-    }
-
-    setDebugging(options.isDebugEnabled());
-    authTimeout = options.getAuthTimeout() * 60 * 1000; // convert minutes to milliseconds
-    disableAuthTimeout = options.isAuthTimeoutDisabled();
-
-    // get the options that were parsed
-    String user = options.getUsername();
-    String password = options.getPassword();
-
-    tabCompletion = !options.isTabCompletionDisabled();
-
-    // Use a fake (Mock), ZK, or HdfsZK Accumulo instance
-    setInstance(options);
-
-    // AuthenticationToken options
-    token = options.getAuthenticationToken();
-    Map<String,String> loginOptions = options.getTokenProperties();
-
-    // process default parameters if unspecified
-    try {
-      boolean hasToken = (token != null);
-      boolean hasTokenOptions = !loginOptions.isEmpty();
-
-      if (hasToken && password != null) {
-        throw new ParameterException("Can not supply '--pass' option with '--tokenClass' option");
-      }
-
-      Runtime.getRuntime().addShutdownHook(new Thread() {
-        @Override
-        public void run() {
-          reader.getTerminal().setEchoEnabled(true);
-        }
-      });
-
-      // Need either both a token and options, or neither, but not just one.
-      if (hasToken != hasTokenOptions) {
-        throw new ParameterException("Must supply either both or neither of '--tokenClass' and '--tokenProperty'");
-      } else if (hasToken) { // implied hasTokenOptions
-        // Fully qualified name so we don't shadow java.util.Properties
-        org.apache.accumulo.core.client.security.tokens.AuthenticationToken.Properties props;
-        // and line wrap it because the package name is so long
-        props = new org.apache.accumulo.core.client.security.tokens.AuthenticationToken.Properties();
-
-        props.putAllStrings(loginOptions);
-        token.init(props);
-      } else {
-        // Read password if the user explicitly asked for it, or didn't specify anything at all
-        if ("stdin".equals(password) || password == null) {
-          password = reader.readLine("Password: ", '*');
-        }
-
-        if (password == null) {
-          // User cancel, e.g. Ctrl-D pressed
-          throw new ParameterException("No password or token option supplied");
-        } else {
-          this.token = new PasswordToken(password);
-        }
-      }
-
-      if (!options.isFake()) {
-        ZooReader zr = new ZooReader(instance.getZooKeepers(), instance.getZooKeepersSessionTimeOut());
-        DistributedTrace.enable(instance, zr, "shell", InetAddress.getLocalHost().getHostName());
-      }
-
-      this.setTableName("");
-      this.principal = user;
-      connector = instance.getConnector(this.principal, token);
-
-    } catch (Exception e) {
-      printException(e);
-      configError = true;
-    }
-
-    // decide whether to execute commands from a file and quit
-    if (options.getExecFile() != null) {
-      execFile = options.getExecFile();
-      verbose = false;
-    } else if (options.getExecFileVerbose() != null) {
-      execFile = options.getExecFileVerbose();
-      verbose = true;
-    }
-    execCommand = options.getExecCommand();
-    if (execCommand != null) {
-      verbose = false;
-    }
-
-    rootToken = new Token();
-
-    Command[] dataCommands = {new DeleteCommand(), new DeleteManyCommand(), new DeleteRowsCommand(), new EGrepCommand(), new FormatterCommand(),
-        new InterpreterCommand(), new GrepCommand(), new ImportDirectoryCommand(), new InsertCommand(), new MaxRowCommand(), new ScanCommand()};
-    Command[] debuggingCommands = {new ClasspathCommand(), new DebugCommand(), new ListScansCommand(), new ListCompactionsCommand(), new TraceCommand(),
-        new PingCommand()};
-    Command[] execCommands = {new ExecfileCommand(), new HistoryCommand(), new ExtensionCommand(), new ScriptCommand()};
-    Command[] exitCommands = {new ByeCommand(), new ExitCommand(), new QuitCommand()};
-    Command[] helpCommands = {new AboutCommand(), new HelpCommand(), new InfoCommand(), new QuestionCommand()};
-    Command[] iteratorCommands = {new DeleteIterCommand(), new DeleteScanIterCommand(), new ListIterCommand(), new SetIterCommand(), new SetScanIterCommand(),
-        new SetShellIterCommand(), new ListShellIterCommand(), new DeleteShellIterCommand()};
-    Command[] otherCommands = {new HiddenCommand()};
-    Command[] permissionsCommands = {new GrantCommand(), new RevokeCommand(), new SystemPermissionsCommand(), new TablePermissionsCommand(),
-        new UserPermissionsCommand(), new NamespacePermissionsCommand()};
-    Command[] stateCommands = {new AuthenticateCommand(), new ClsCommand(), new ClearCommand(), new FateCommand(), new NoTableCommand(), new SleepCommand(),
-        new TableCommand(), new UserCommand(), new WhoAmICommand()};
-    Command[] tableCommands = {new CloneTableCommand(), new ConfigCommand(), new CreateTableCommand(), new DeleteTableCommand(), new DropTableCommand(),
-        new DUCommand(), new ExportTableCommand(), new ImportTableCommand(), new OfflineCommand(), new OnlineCommand(), new RenameTableCommand(),
-        new TablesCommand(), new NamespacesCommand(), new CreateNamespaceCommand(), new DeleteNamespaceCommand(), new RenameNamespaceCommand()};
-    Command[] tableControlCommands = {new AddSplitsCommand(), new CompactCommand(), new ConstraintCommand(), new FlushCommand(), new GetGroupsCommand(),
-        new GetSplitsCommand(), new MergeCommand(), new SetGroupsCommand()};
-    Command[] userCommands = {new AddAuthsCommand(), new CreateUserCommand(), new DeleteUserCommand(), new DropUserCommand(), new GetAuthsCommand(),
-        new PasswdCommand(), new SetAuthsCommand(), new UsersCommand()};
-    commandGrouping.put("-- Writing, Reading, and Removing Data --", dataCommands);
-    commandGrouping.put("-- Debugging Commands -------------------", debuggingCommands);
-    commandGrouping.put("-- Shell Execution Commands -------------", execCommands);
-    commandGrouping.put("-- Exiting Commands ---------------------", exitCommands);
-    commandGrouping.put("-- Help Commands ------------------------", helpCommands);
-    commandGrouping.put("-- Iterator Configuration ---------------", iteratorCommands);
-    commandGrouping.put("-- Permissions Administration Commands --", permissionsCommands);
-    commandGrouping.put("-- Shell State Commands -----------------", stateCommands);
-    commandGrouping.put("-- Table Administration Commands --------", tableCommands);
-    commandGrouping.put("-- Table Control Commands ---------------", tableControlCommands);
-    commandGrouping.put("-- User Administration Commands ---------", userCommands);
-
-    for (Command[] cmds : commandGrouping.values()) {
-      for (Command cmd : cmds)
-        commandFactory.put(cmd.getName(), cmd);
-    }
-    for (Command cmd : otherCommands) {
-      commandFactory.put(cmd.getName(), cmd);
-    }
-    return configError;
-  }
-
-  /**
-   * Sets the instance used by the shell based on the given options.
-   * 
-   * @param options
-   *          shell options
-   */
-  protected void setInstance(ShellOptionsJC options) {
-    // should only be one set of instance options set
-    instance = null;
-    if (options.isFake()) {
-      instance = new MockInstance("fake");
-    } else {
-      String instanceName, hosts;
-      if (options.isHdfsZooInstance()) {
-        instanceName = hosts = null;
-      } else if (options.getZooKeeperInstance().size() > 0) {
-        List<String> zkOpts = options.getZooKeeperInstance();
-        instanceName = zkOpts.get(0);
-        hosts = zkOpts.get(1);
-      } else {
-        instanceName = options.getZooKeeperInstanceName();
-        hosts = options.getZooKeeperHosts();
-      }
-      try {
-        instance = getZooInstance(instanceName, hosts, options.getClientConfiguration());
-      } catch (Exception e) {
-        throw new IllegalArgumentException("Unable to load client config from " + options.getClientConfigFile(), e);
-      }
-    }
-  }
-
-  /*
-   * Takes instanceName and keepers as separate arguments, rather than just packaged into the clientConfig, so that we can fail over to accumulo-site.xml or
-   * HDFS config if they're unspecified.
-   */
-  private static Instance getZooInstance(String instanceName, String keepers, ClientConfiguration clientConfig) {
-    UUID instanceId = null;
-    if (instanceName == null) {
-      instanceName = clientConfig.get(ClientProperty.INSTANCE_NAME);
-    }
-    if (instanceName == null || keepers == null) {
-      AccumuloConfiguration conf = SiteConfiguration.getInstance(ServerConfigurationUtil.convertClientConfig(DefaultConfiguration.getInstance(), clientConfig));
-      if (instanceName == null) {
-        Path instanceDir = new Path(VolumeConfiguration.getVolumeUris(conf)[0], "instance_id");
-        instanceId = UUID.fromString(ZooUtil.getInstanceIDFromHdfs(instanceDir, conf));
-      }
-      if (keepers == null) {
-        keepers = conf.get(Property.INSTANCE_ZK_HOST);
-      }
-    }
-    if (instanceId != null) {
-      return new ZooKeeperInstance(clientConfig.withInstance(instanceId).withZkHosts(keepers));
-    } else {
-      return new ZooKeeperInstance(clientConfig.withInstance(instanceName).withZkHosts(keepers));
-    }
-  }
-
-  public Connector getConnector() {
-    return connector;
-  }
-
-  public Instance getInstance() {
-    return instance;
-  }
-
-  public static void main(String args[]) throws IOException {
-    Shell shell = new Shell();
-    try {
-      shell.config(args);
-
-      System.exit(shell.start());
-    } finally {
-      shell.shutdown();
-    }
-  }
-
-  public int start() throws IOException {
-    if (configError)
-      return 1;
-
-    String input;
-    if (isVerbose())
-      printInfo();
-
-    String home = System.getProperty("HOME");
-    if (home == null)
-      home = System.getenv("HOME");
-    String configDir = home + "/" + HISTORY_DIR_NAME;
-    String historyPath = configDir + "/" + HISTORY_FILE_NAME;
-    File accumuloDir = new File(configDir);
-    if (!accumuloDir.exists() && !accumuloDir.mkdirs())
-      log.warn("Unable to make directory for history at " + accumuloDir);
-    try {
-      final FileHistory history = new FileHistory(new File(historyPath));
-      reader.setHistory(history);
-      // Add shutdown hook to flush file history, per jline javadocs
-      Runtime.getRuntime().addShutdownHook(new Thread() {
-        @Override
-        public void run() {
-          try {
-            history.flush();
-          } catch (IOException e) {
-            log.warn("Could not flush history to file.");
-          }
-        }
-      });
-    } catch (IOException e) {
-      log.warn("Unable to load history file at " + historyPath);
-    }
-
-    // Turn Ctrl+C into Exception instead of JVM exit
-    reader.setHandleUserInterrupt(true);
-
-    ShellCompletor userCompletor = null;
-
-    if (execFile != null) {
-      java.util.Scanner scanner = new java.util.Scanner(execFile, StandardCharsets.UTF_8.name());
-      try {
-        while (scanner.hasNextLine() && !hasExited()) {
-          execCommand(scanner.nextLine(), true, isVerbose());
-        }
-      } finally {
-        scanner.close();
-      }
-    } else if (execCommand != null) {
-      for (String command : execCommand.split("\n")) {
-        execCommand(command, true, isVerbose());
-      }
-      return exitCode;
-    }
-
-    while (true) {
-      try {
-        if (hasExited())
-          return exitCode;
-
-        // If tab completion is true we need to reset
-        if (tabCompletion) {
-          if (userCompletor != null)
-            reader.removeCompleter(userCompletor);
-
-          userCompletor = setupCompletion();
-          reader.addCompleter(userCompletor);
-        }
-
-        reader.setPrompt(getDefaultPrompt());
-        input = reader.readLine();
-        if (input == null) {
-          reader.println();
-          return exitCode;
-        } // User Canceled (Ctrl+D)
-
-        execCommand(input, disableAuthTimeout, false);
-      } catch (UserInterruptException uie) {
-        // User Cancelled (Ctrl+C)
-        reader.println();
-
-        String partialLine = uie.getPartialLine();
-        if (partialLine == null || "".equals(uie.getPartialLine().trim())) {
-          // No content, actually exit
-          return exitCode;
-        }
-      } finally {
-        reader.flush();
-      }
-    }
-  }
-
-  public void shutdown() {
-    if (reader != null) {
-      reader.shutdown();
-    }
-  }
-
-  public void printInfo() throws IOException {
-    reader.print("\n" + SHELL_DESCRIPTION + "\n" + "- \n" + "- version: " + Constants.VERSION + "\n" + "- instance name: "
-        + connector.getInstance().getInstanceName() + "\n" + "- instance id: " + connector.getInstance().getInstanceID() + "\n" + "- \n"
-        + "- type 'help' for a list of available commands\n" + "- \n");
-    reader.flush();
-  }
-
-  public void printVerboseInfo() throws IOException {
-    StringBuilder sb = new StringBuilder("-\n");
-    sb.append("- Current user: ").append(connector.whoami()).append("\n");
-    if (execFile != null)
-      sb.append("- Executing commands from: ").append(execFile).append("\n");
-    if (disableAuthTimeout)
-      sb.append("- Authorization timeout: disabled\n");
-    else
-      sb.append("- Authorization timeout: ").append(String.format("%.2fs%n", authTimeout / 1000.0));
-    sb.append("- Debug: ").append(isDebuggingEnabled() ? "on" : "off").append("\n");
-    if (!scanIteratorOptions.isEmpty()) {
-      for (Entry<String,List<IteratorSetting>> entry : scanIteratorOptions.entrySet()) {
-        sb.append("- Session scan iterators for table ").append(entry.getKey()).append(":\n");
-        for (IteratorSetting setting : entry.getValue()) {
-          sb.append("-    Iterator ").append(setting.getName()).append(" options:\n");
-          sb.append("-        ").append("iteratorPriority").append(" = ").append(setting.getPriority()).append("\n");
-          sb.append("-        ").append("iteratorClassName").append(" = ").append(setting.getIteratorClass()).append("\n");
-          for (Entry<String,String> optEntry : setting.getOptions().entrySet()) {
-            sb.append("-        ").append(optEntry.getKey()).append(" = ").append(optEntry.getValue()).append("\n");
-          }
-        }
-      }
-    }
-    sb.append("-\n");
-    reader.print(sb.toString());
-  }
-
-  public String getDefaultPrompt() {
-    return connector.whoami() + "@" + connector.getInstance().getInstanceName() + (getTableName().isEmpty() ? "" : " ") + getTableName() + "> ";
-  }
-
-  public void execCommand(String input, boolean ignoreAuthTimeout, boolean echoPrompt) throws IOException {
-    audit.log(Level.INFO, getDefaultPrompt() + input);
-    if (echoPrompt) {
-      reader.print(getDefaultPrompt());
-      reader.println(input);
-    }
-
-    if (input.startsWith(COMMENT_PREFIX)) {
-      return;
-    }
-
-    String fields[];
-    try {
-      fields = new QuotedStringTokenizer(input).getTokens();
-    } catch (BadArgumentException e) {
-      printException(e);
-      ++exitCode;
-      return;
-    }
-    if (fields.length == 0)
-      return;
-
-    String command = fields[0];
-    fields = fields.length > 1 ? Arrays.copyOfRange(fields, 1, fields.length) : new String[] {};
-
-    Command sc = null;
-    if (command.length() > 0) {
-      try {
-        // Obtain the command from the command table
-        sc = commandFactory.get(command);
-        if (sc == null) {
-          reader.println(String.format("Unknown command \"%s\".  Enter \"help\" for a list possible commands.", command));
-          reader.flush();
-          return;
-        }
-
-        if (!(sc instanceof ExitCommand) && !ignoreAuthTimeout && System.currentTimeMillis() - lastUserActivity > authTimeout) {
-          reader.println("Shell has been idle for too long. Please re-authenticate.");
-          boolean authFailed = true;
-          do {
-            String pwd = readMaskedLine("Enter current password for '" + connector.whoami() + "': ", '*');
-            if (pwd == null) {
-              reader.println();
-              return;
-            } // user canceled
-
-            try {
-              authFailed = !connector.securityOperations().authenticateUser(connector.whoami(), new PasswordToken(pwd));
-            } catch (Exception e) {
-              ++exitCode;
-              printException(e);
-            }
-
-            if (authFailed)
-              reader.print("Invalid password. ");
-          } while (authFailed);
-          lastUserActivity = System.currentTimeMillis();
-        }
-
-        // Get the options from the command on how to parse the string
-        Options parseOpts = sc.getOptionsWithHelp();
-
-        // Parse the string using the given options
-        CommandLine cl = new BasicParser().parse(parseOpts, fields);
-
-        int actualArgLen = cl.getArgs().length;
-        int expectedArgLen = sc.numArgs();
-        if (cl.hasOption(helpOption)) {
-          // Display help if asked to; otherwise execute the command
-          sc.printHelp(this);
-        } else if (expectedArgLen != NO_FIXED_ARG_LENGTH_CHECK && actualArgLen != expectedArgLen) {
-          ++exitCode;
-          // Check for valid number of fixed arguments (if not
-          // negative; negative means it is not checked, for
-          // vararg-like commands)
-          printException(new IllegalArgumentException(String.format("Expected %d argument%s. There %s %d.", expectedArgLen, expectedArgLen == 1 ? "" : "s",
-              actualArgLen == 1 ? "was" : "were", actualArgLen)));
-          sc.printHelp(this);
-        } else {
-          int tmpCode = sc.execute(input, cl, this);
-          exitCode += tmpCode;
-          reader.flush();
-        }
-
-      } catch (ConstraintViolationException e) {
-        ++exitCode;
-        printConstraintViolationException(e);
-      } catch (TableNotFoundException e) {
-        ++exitCode;
-        if (getTableName().equals(e.getTableName()))
-          setTableName("");
-        printException(e);
-      } catch (ParseException e) {
-        // not really an error if the exception is a missing required
-        // option when the user is asking for help
-        if (!(e instanceof MissingOptionException && (Arrays.asList(fields).contains("-" + helpOption) || Arrays.asList(fields).contains("--" + helpLongOption)))) {
-          ++exitCode;
-          printException(e);
-        }
-        if (sc != null)
-          sc.printHelp(this);
-      } catch (UserInterruptException e) {
-        ++exitCode;
-      } catch (Exception e) {
-        ++exitCode;
-        printException(e);
-      }
-    } else {
-      ++exitCode;
-      printException(new BadArgumentException("Unrecognized empty command", command, -1));
-    }
-    reader.flush();
-  }
-
-  /**
-   * The command tree is built in reverse so that the references are more easily linked up. There is some code in token to allow forward building of the command
-   * tree.
-   */
-  private ShellCompletor setupCompletion() {
-    rootToken = new Token();
-
-    Set<String> tableNames = null;
-    try {
-      tableNames = connector.tableOperations().list();
-    } catch (Exception e) {
-      log.debug("Unable to obtain list of tables", e);
-      tableNames = Collections.emptySet();
-    }
-
-    Set<String> userlist = null;
-    try {
-      userlist = connector.securityOperations().listLocalUsers();
-    } catch (Exception e) {
-      log.debug("Unable to obtain list of users", e);
-      userlist = Collections.emptySet();
-    }
-
-    Set<String> namespaces = null;
-    try {
-      namespaces = connector.namespaceOperations().list();
-    } catch (Exception e) {
-      log.debug("Unable to obtain list of namespaces", e);
-      namespaces = Collections.emptySet();
-    }
-
-    Map<Command.CompletionSet,Set<String>> options = new HashMap<Command.CompletionSet,Set<String>>();
-
-    Set<String> commands = new HashSet<String>();
-    for (String a : commandFactory.keySet())
-      commands.add(a);
-
-    Set<String> modifiedUserlist = new HashSet<String>();
-    Set<String> modifiedTablenames = new HashSet<String>();
-    Set<String> modifiedNamespaces = new HashSet<String>();
-
-    for (String a : tableNames)
-      modifiedTablenames.add(a.replaceAll("([\\s'\"])", "\\\\$1"));
-    for (String a : userlist)
-      modifiedUserlist.add(a.replaceAll("([\\s'\"])", "\\\\$1"));
-    for (String a : namespaces) {
-      String b = a.replaceAll("([\\s'\"])", "\\\\$1");
-      modifiedNamespaces.add(b.isEmpty() ? "\"\"" : b);
-    }
-
-    options.put(Command.CompletionSet.USERNAMES, modifiedUserlist);
-    options.put(Command.CompletionSet.TABLENAMES, modifiedTablenames);
-    options.put(Command.CompletionSet.NAMESPACES, modifiedNamespaces);
-    options.put(Command.CompletionSet.COMMANDS, commands);
-
-    for (Command[] cmdGroup : commandGrouping.values()) {
-      for (Command c : cmdGroup) {
-        c.getOptionsWithHelp(); // prep the options for the command
-        // so that the completion can
-        // include them
-        c.registerCompletion(rootToken, options);
-      }
-    }
-    return new ShellCompletor(rootToken, options);
-  }
-
-  /**
-   * The Command class represents a command to be run in the shell. It contains the methods to execute along with some methods to help tab completion, and
-   * return the command name, help, and usage.
-   */
-  public static abstract class Command {
-    // Helper methods for completion
-    public enum CompletionSet {
-      TABLENAMES, USERNAMES, COMMANDS, NAMESPACES
-    }
-
-    static Set<String> getCommandNames(Map<CompletionSet,Set<String>> objects) {
-      return objects.get(CompletionSet.COMMANDS);
-    }
-
-    static Set<String> getTableNames(Map<CompletionSet,Set<String>> objects) {
-      return objects.get(CompletionSet.TABLENAMES);
-    }
-
-    static Set<String> getUserNames(Map<CompletionSet,Set<String>> objects) {
-      return objects.get(CompletionSet.USERNAMES);
-    }
-
-    static Set<String> getNamespaces(Map<CompletionSet,Set<String>> objects) {
-      return objects.get(CompletionSet.NAMESPACES);
-    }
-
-    public void registerCompletionGeneral(Token root, Set<String> args, boolean caseSens) {
-      Token t = new Token(args);
-      t.setCaseSensitive(caseSens);
-
-      Token command = new Token(getName());
-      command.addSubcommand(t);
-
-      root.addSubcommand(command);
-    }
-
-    public void registerCompletionForTables(Token root, Map<CompletionSet,Set<String>> completionSet) {
-      registerCompletionGeneral(root, completionSet.get(CompletionSet.TABLENAMES), true);
-    }
-
-    public void registerCompletionForUsers(Token root, Map<CompletionSet,Set<String>> completionSet) {
-      registerCompletionGeneral(root, completionSet.get(CompletionSet.USERNAMES), true);
-    }
-
-    public void registerCompletionForCommands(Token root, Map<CompletionSet,Set<String>> completionSet) {
-      registerCompletionGeneral(root, completionSet.get(CompletionSet.COMMANDS), false);
-    }
-
-    public void registerCompletionForNamespaces(Token root, Map<CompletionSet,Set<String>> completionSet) {
-      registerCompletionGeneral(root, completionSet.get(CompletionSet.NAMESPACES), true);
-    }
-
-    // abstract methods to override
-    public abstract int execute(String fullCommand, CommandLine cl, Shell shellState) throws Exception;
-
-    public abstract String description();
-
-    /**
-     * If the number of arguments is not always zero (not including those arguments handled through Options), make sure to override the {@link #usage()} method.
-     * Otherwise, {@link #usage()} does need to be overridden.
-     */
-    public abstract int numArgs();
-
-    // OPTIONAL methods to override:
-
-    // the general version of getname uses reflection to get the class name
-    // and then cuts off the suffix -Command to get the name of the command
-    public String getName() {
-      String s = this.getClass().getName();
-      int st = Math.max(s.lastIndexOf('$'), s.lastIndexOf('.'));
-      int i = s.indexOf("Command");
-      return i > 0 ? s.substring(st + 1, i).toLowerCase(Locale.ENGLISH) : null;
-    }
-
-    // The general version of this method adds the name
-    // of the command to the completion tree
-    public void registerCompletion(Token root, Map<CompletionSet,Set<String>> completion_set) {
-      root.addSubcommand(new Token(getName()));
-    }
-
-    // The general version of this method uses the HelpFormatter
-    // that comes with the apache Options package to print out the help
-    public final void printHelp(Shell shellState) {
-      shellState.printHelp(usage(), "description: " + this.description(), getOptionsWithHelp());
-    }
-
-    public final void printHelp(Shell shellState, int width) {
-      shellState.printHelp(usage(), "description: " + this.description(), getOptionsWithHelp(), width);
-    }
-
-    // Get options with help
-    public final Options getOptionsWithHelp() {
-      Options opts = getOptions();
-      opts.addOption(new Option(helpOption, helpLongOption, false, "display this help"));
-      return opts;
-    }
-
-    // General usage is just the command
-    public String usage() {
-      return getName();
-    }
-
-    // General Options are empty
-    public Options getOptions() {
-      return new Options();
-    }
-  }
-
-  public interface PrintLine {
-    void print(String s);
-
-    void close();
-  }
-
-  public static class PrintShell implements PrintLine {
-    ConsoleReader reader;
-
-    public PrintShell(ConsoleReader reader) {
-      this.reader = reader;
-    }
-
-    @Override
-    public void print(String s) {
-      try {
-        reader.println(s);
-      } catch (Exception ex) {
-        throw new RuntimeException(ex);
-      }
-    }
-
-    @Override
-    public void close() {}
-  };
-
-  public static class PrintFile implements PrintLine {
-    PrintWriter writer;
-
-    public PrintFile(String filename) throws FileNotFoundException {
-      writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(filename), StandardCharsets.UTF_8)));
-    }
-
-    @Override
-    public void print(String s) {
-      writer.println(s);
-    }
-
-    @Override
-    public void close() {
-      writer.close();
-    }
-  };
-
-  public final void printLines(Iterator<String> lines, boolean paginate) throws IOException {
-    printLines(lines, paginate, null);
-  }
-
-  public final void printLines(Iterator<String> lines, boolean paginate, PrintLine out) throws IOException {
-    int linesPrinted = 0;
-    String prompt = "-- hit any key to continue or 'q' to quit --";
-    int lastPromptLength = prompt.length();
-    int termWidth = reader.getTerminal().getWidth();
-    int maxLines = reader.getTerminal().getHeight();
-
-    String peek = null;
-    while (lines.hasNext()) {
-      String nextLine = lines.next();
-      if (nextLine == null)
-        continue;
-      for (String line : nextLine.split("\\n")) {
-        if (out == null) {
-          if (peek != null) {
-            reader.println(peek);
-            if (paginate) {
-              linesPrinted += peek.length() == 0 ? 0 : Math.ceil(peek.length() * 1.0 / termWidth);
-
-              // check if displaying the next line would result in
-              // scrolling off the screen
-              if (linesPrinted + Math.ceil(lastPromptLength * 1.0 / termWidth) + Math.ceil(prompt.length() * 1.0 / termWidth)
-                  + Math.ceil(line.length() * 1.0 / termWidth) > maxLines) {
-                linesPrinted = 0;
-                int numdashes = (termWidth - prompt.length()) / 2;
-                String nextPrompt = repeat("-", numdashes) + prompt + repeat("-", numdashes);
-                lastPromptLength = nextPrompt.length();
-                reader.print(nextPrompt);
-                reader.flush();
-
-                if (Character.toUpperCase((char) reader.readCharacter()) == 'Q') {
-                  reader.println();
-                  return;
-                }
-                reader.println();
-                termWidth = reader.getTerminal().getWidth();
-                maxLines = reader.getTerminal().getHeight();
-              }
-            }
-          }
-          peek = line;
-        } else {
-          out.print(line);
-        }
-      }
-    }
-    if (out == null && peek != null) {
-      reader.println(peek);
-    }
-  }
-
-  public final void printRecords(Iterable<Entry<Key,Value>> scanner, boolean printTimestamps, boolean paginate, Class<? extends Formatter> formatterClass,
-      PrintLine outFile) throws IOException {
-    printLines(FormatterFactory.getFormatter(formatterClass, scanner, printTimestamps), paginate, outFile);
-  }
-
-  public final void printRecords(Iterable<Entry<Key,Value>> scanner, boolean printTimestamps, boolean paginate, Class<? extends Formatter> formatterClass)
-      throws IOException {
-    printLines(FormatterFactory.getFormatter(formatterClass, scanner, printTimestamps), paginate);
-  }
-
-  public final void printBinaryRecords(Iterable<Entry<Key,Value>> scanner, boolean printTimestamps, boolean paginate, PrintLine outFile) throws IOException {
-    printLines(FormatterFactory.getFormatter(binaryFormatterClass, scanner, printTimestamps), paginate, outFile);
-  }
-
-  public final void printBinaryRecords(Iterable<Entry<Key,Value>> scanner, boolean printTimestamps, boolean paginate) throws IOException {
-    printLines(FormatterFactory.getFormatter(binaryFormatterClass, scanner, printTimestamps), paginate);
-  }
-
-  public static String repeat(String s, int c) {
-    StringBuilder sb = new StringBuilder();
-    for (int i = 0; i < c; i++)
-      sb.append(s);
-    return sb.toString();
-  }
-
-  public void checkTableState() {
-    if (getTableName().isEmpty())
-      throw new IllegalStateException(
-          "Not in a table context. Please use 'table <tableName>' to switch to a table, or use '-t' to specify a table if option is available.");
-  }
-
-  private final void printConstraintViolationException(ConstraintViolationException cve) {
-    printException(cve, "");
-    int COL1 = 50, COL2 = 14;
-    int col3 = Math.max(1, Math.min(Integer.MAX_VALUE, reader.getTerminal().getWidth() - COL1 - COL2 - 6));
-    logError(String.format("%" + COL1 + "s-+-%" + COL2 + "s-+-%" + col3 + "s%n", repeat("-", COL1), repeat("-", COL2), repeat("-", col3)));
-    logError(String.format("%-" + COL1 + "s | %" + COL2 + "s | %-" + col3 + "s%n", "Constraint class", "Violation code", "Violation Description"));
-    logError(String.format("%" + COL1 + "s-+-%" + COL2 + "s-+-%" + col3 + "s%n", repeat("-", COL1), repeat("-", COL2), repeat("-", col3)));
-    for (TConstraintViolationSummary cvs : cve.violationSummaries)
-      logError(String.format("%-" + COL1 + "s | %" + COL2 + "d | %-" + col3 + "s%n", cvs.constrainClass, cvs.violationCode, cvs.violationDescription));
-    logError(String.format("%" + COL1 + "s-+-%" + COL2 + "s-+-%" + col3 + "s%n", repeat("-", COL1), repeat("-", COL2), repeat("-", col3)));
-  }
-
-  public final void printException(Exception e) {
-    printException(e, e.getMessage());
-  }
-
-  private final void printException(Exception e, String msg) {
-    logError(e.getClass().getName() + (msg != null ? ": " + msg : ""));
-    log.debug(e.getClass().getName() + (msg != null ? ": " + msg : ""), e);
-  }
-
-  public static final void setDebugging(boolean debuggingEnabled) {
-    Logger.getLogger(Constants.CORE_PACKAGE_NAME).setLevel(debuggingEnabled ? Level.TRACE : Level.INFO);
-  }
-
-  public static final boolean isDebuggingEnabled() {
-    return Logger.getLogger(Constants.CORE_PACKAGE_NAME).isTraceEnabled();
-  }
-
-  private final void printHelp(String usage, String description, Options opts) {
-    printHelp(usage, description, opts, Integer.MAX_VALUE);
-  }
-
-  private final void printHelp(String usage, String description, Options opts, int width) {
-    // TODO Use the OutputStream from the JLine ConsoleReader if we can ever get access to it
-    new HelpFormatter().printHelp(writer, width, usage, description, opts, 2, 5, null, true);
-    writer.flush();
-  }
-
-  public int getExitCode() {
-    return exitCode;
-  }
-
-  public void resetExitCode() {
-    exitCode = 0;
-  }
-
-  public void setExit(boolean exit) {
-    this.exit = exit;
-  }
-
-  public boolean getExit() {
-    return this.exit;
-  }
-
-  public boolean isVerbose() {
-    return verbose;
-  }
-
-  public void setTableName(String tableName) {
-    this.tableName = (tableName == null || tableName.isEmpty()) ? "" : Tables.qualified(tableName);
-  }
-
-  public String getTableName() {
-    return tableName;
-  }
-
-  public ConsoleReader getReader() {
-    return reader;
-  }
-
-  public void updateUser(String principal, AuthenticationToken token) throws AccumuloException, AccumuloSecurityException {
-    connector = instance.getConnector(principal, token);
-    this.principal = principal;
-    this.token = token;
-  }
-
-  public String getPrincipal() {
-    return principal;
-  }
-
-  public AuthenticationToken getToken() {
-    return token;
-  }
-
-  /**
-   * Return the formatter for the current table.
-   * 
-   * @return the formatter class for the current table
-   */
-  public Class<? extends Formatter> getFormatter() {
-    return getFormatter(this.tableName);
-  }
-
-  /**
-   * Return the formatter for the given table.
-   * 
-   * @param tableName
-   *          the table name
-   * @return the formatter class for the given table
-   */
-  public Class<? extends Formatter> getFormatter(String tableName) {
-    Class<? extends Formatter> formatter = FormatterCommand.getCurrentFormatter(tableName, this);
-
-    if (null == formatter) {
-      logError("Could not load the specified formatter. Using the DefaultFormatter");
-      return this.defaultFormatterClass;
-    } else {
-      return formatter;
-    }
-  }
-
-  public void setLogErrorsToConsole() {
-    this.logErrorsToConsole = true;
-  }
-
-  private void logError(String s) {
-    log.error(s);
-    if (logErrorsToConsole) {
-      try {
-        reader.println("ERROR: " + s);
-        reader.flush();
-      } catch (IOException e) {}
-    }
-  }
-
-  public String readMaskedLine(String prompt, Character mask) throws IOException {
-    this.masking = true;
-    String s = reader.readLine(prompt, mask);
-    this.masking = false;
-    return s;
-  }
-
-  public boolean isMasking() {
-    return masking;
-  }
-
-  public boolean hasExited() {
-    return exit;
-  }
-
-  public boolean isTabCompletion() {
-    return tabCompletion;
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/ShellCommandException.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/ShellCommandException.java b/core/src/main/java/org/apache/accumulo/core/util/shell/ShellCommandException.java
deleted file mode 100644
index 6bef379..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/ShellCommandException.java
+++ /dev/null
@@ -1,59 +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.accumulo.core.util.shell;
-
-public class ShellCommandException extends Exception {
-  private static final long serialVersionUID = 1L;
-  
-  public enum ErrorCode {
-    UNKNOWN_ERROR("Unknown error"),
-    UNSUPPORTED_LANGUAGE("Programming language used is not supported"),
-    UNRECOGNIZED_COMMAND("Command is not supported"),
-    INITIALIZATION_FAILURE("Command could not be initialized"),
-    XML_PARSING_ERROR("Failed to parse the XML file");
-    
-    private String description;
-    
-    private ErrorCode(String description) {
-      this.description = description;
-    }
-    
-    public String getDescription() {
-      return this.description;
-    }
-    
-    public String toString() {
-      return getDescription();
-    }
-  }
-  
-  private ErrorCode code;
-  private String command;
-  
-  public ShellCommandException(ErrorCode code) {
-    this(code, null);
-  }
-  
-  public ShellCommandException(ErrorCode code, String command) {
-    this.code = code;
-    this.command = command;
-  }
-  
-  public String getMessage() {
-    return code + (command != null ? " (" + command + ")" : "");
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/ShellCompletor.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/ShellCompletor.java b/core/src/main/java/org/apache/accumulo/core/util/shell/ShellCompletor.java
deleted file mode 100644
index c64e0c7..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/ShellCompletor.java
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.accumulo.core.util.shell;
-
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import jline.console.completer.Completer;
-
-import org.apache.accumulo.core.util.shell.Shell.Command.CompletionSet;
-import org.apache.accumulo.core.util.shell.commands.QuotedStringTokenizer;
-
-public class ShellCompletor implements Completer {
-
-  // private static final Logger log = Logger.getLogger(ShellCompletor.class);
-
-  Map<CompletionSet,Set<String>> options;
-  Token root = null;
-
-  public ShellCompletor() {}
-
-  public ShellCompletor(Token root) {
-    this.root = root;
-  }
-
-  public ShellCompletor(Token rootToken, Map<CompletionSet,Set<String>> options) {
-    this.root = rootToken;
-    this.options = options;
-  }
-
-  @Override
-  @SuppressWarnings({"unchecked", "rawtypes"})
-  public int complete(String buffer, int cursor, List candidates) {
-    try {
-      return _complete(buffer, cursor, candidates);
-    } catch (Exception e) {
-      candidates.add("");
-      candidates.add(e.getMessage());
-      return cursor;
-    }
-  }
-
-  private int _complete(String fullBuffer, int cursor, List<String> candidates) {
-    boolean inTableFlag = false, inUserFlag = false, inNamespaceFlag = false;
-    // Only want to grab the buffer up to the cursor because
-    // the user could be trying to tab complete in the middle
-    // of the line
-    String buffer = fullBuffer.substring(0, cursor);
-
-    Token current_command_token = root;
-    String current_string_token = null;
-    boolean end_space = buffer.endsWith(" ");
-
-    // tabbing with no text
-    if (buffer.length() == 0) {
-      candidates.addAll(root.getSubcommandNames());
-      return 0;
-    }
-
-    String prefix = "";
-
-    QuotedStringTokenizer qst = new QuotedStringTokenizer(buffer);
-
-    Iterator<String> iter = qst.iterator();
-    while (iter.hasNext()) {
-      current_string_token = iter.next();
-      current_string_token = current_string_token.replaceAll("([\\s'\"])", "\\\\$1");
-
-      if (!iter.hasNext()) {
-        // if we end in a space and that space isn't part of the last token
-        // (which would be the case at the start of a quote) OR the buffer
-        // ends with a " indicating that we need to start on the next command
-        // and not complete the current command.
-        if (end_space && !current_string_token.endsWith(" ") || buffer.endsWith("\"")) {
-          // match subcommands
-
-          // we're in a subcommand so try to match the universal
-          // option flags if we're there
-          if (current_string_token.trim().equals("-" + Shell.tableOption)) {
-            candidates.addAll(options.get(Shell.Command.CompletionSet.TABLENAMES));
-            prefix += "-" + Shell.tableOption + " ";
-          } else if (current_string_token.trim().equals("-" + Shell.userOption)) {
-            candidates.addAll(options.get(Shell.Command.CompletionSet.USERNAMES));
-            prefix += "-" + Shell.userOption + " ";
-          } else if (current_string_token.trim().equals("-" + Shell.namespaceOption)) {
-            candidates.addAll(options.get(Shell.Command.CompletionSet.NAMESPACES));
-            prefix += "-" + Shell.namespaceOption + " ";
-          } else if (current_command_token != null) {
-            Token next = current_command_token.getSubcommand(current_string_token);
-            if (next != null) {
-              current_command_token = next;
-
-              if (current_command_token.getCaseSensitive())
-                prefix += current_string_token + " ";
-              else
-                prefix += current_string_token.toUpperCase() + " ";
-
-              candidates.addAll(current_command_token.getSubcommandNames());
-            }
-          }
-          Collections.sort(candidates);
-          return (prefix.length());
-        }
-        // need to match current command
-        // if we're in -t <table>, -u <user>, or -tn <namespace> complete those
-        if (inTableFlag) {
-          for (String a : options.get(Shell.Command.CompletionSet.TABLENAMES))
-            if (a.startsWith(current_string_token))
-              candidates.add(a);
-        } else if (inUserFlag) {
-          for (String a : options.get(Shell.Command.CompletionSet.USERNAMES))
-            if (a.startsWith(current_string_token))
-              candidates.add(a);
-        } else if (inNamespaceFlag) {
-          for (String a : options.get(Shell.Command.CompletionSet.NAMESPACES))
-            if (a.startsWith(current_string_token))
-              candidates.add(a);
-        } else if (current_command_token != null)
-          candidates.addAll(current_command_token.getSubcommandNames(current_string_token));
-
-        Collections.sort(candidates);
-        return (prefix.length());
-      }
-
-      if (current_string_token.trim().equals("-" + Shell.tableOption))
-        inTableFlag = true;
-      else if (current_string_token.trim().equals("-" + Shell.userOption))
-        inUserFlag = true;
-      else if (current_string_token.trim().equals("-" + Shell.namespaceOption))
-        inNamespaceFlag = true;
-      else
-        inUserFlag = inTableFlag = inNamespaceFlag = false;
-
-      if (current_command_token != null && current_command_token.getCaseSensitive())
-        prefix += current_string_token + " ";
-      else
-        prefix += current_string_token.toUpperCase() + " ";
-
-      if (current_command_token != null && current_command_token.getSubcommandNames().contains(current_string_token))
-        current_command_token = current_command_token.getSubcommand(current_string_token);
-
-    }
-    return 0;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/ShellExtension.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/ShellExtension.java b/core/src/main/java/org/apache/accumulo/core/util/shell/ShellExtension.java
deleted file mode 100644
index 5deccef..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/ShellExtension.java
+++ /dev/null
@@ -1,27 +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.accumulo.core.util.shell;
-
-import org.apache.accumulo.core.util.shell.Shell.Command;
-
-public abstract class ShellExtension {
-    
-    public abstract String getExtensionName();
-
-    public abstract Command[] getCommands();
-    
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/ShellOptions.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/ShellOptions.java b/core/src/main/java/org/apache/accumulo/core/util/shell/ShellOptions.java
deleted file mode 100644
index 4e573ed..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/ShellOptions.java
+++ /dev/null
@@ -1,33 +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.accumulo.core.util.shell;
-
-import org.apache.commons.cli.Option;
-
-/**
- * Abstract class to encompass the Options available on the Accumulo Shell
- */
-public abstract class ShellOptions {
-  // Global options flags
-  public static final String userOption = "u";
-  public static final String tableOption = "t";
-  public static final String namespaceOption = "ns";
-  public static final String helpOption = "?";
-  public static final String helpLongOption = "help";
-
-  final Option helpOpt = new Option(helpOption, helpLongOption, false, "display this help");
-}


[26/53] [abbrv] Revert "ACCUMULO-1897 Move shell into new package and module"

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/Shell.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/Shell.java b/shell/src/main/java/org/apache/accumulo/shell/Shell.java
deleted file mode 100644
index 48d8bd0..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/Shell.java
+++ /dev/null
@@ -1,1168 +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.accumulo.shell;
-
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.OutputStreamWriter;
-import java.io.PrintWriter;
-import java.net.InetAddress;
-import java.nio.charset.StandardCharsets;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.TreeMap;
-import java.util.UUID;
-
-import jline.console.ConsoleReader;
-import jline.console.UserInterruptException;
-import jline.console.history.FileHistory;
-
-import org.apache.accumulo.core.Constants;
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.ClientConfiguration;
-import org.apache.accumulo.core.client.ClientConfiguration.ClientProperty;
-import org.apache.accumulo.core.client.Connector;
-import org.apache.accumulo.core.client.Instance;
-import org.apache.accumulo.core.client.IteratorSetting;
-import org.apache.accumulo.core.client.TableNotFoundException;
-import org.apache.accumulo.core.client.ZooKeeperInstance;
-import org.apache.accumulo.core.client.impl.ServerConfigurationUtil;
-import org.apache.accumulo.core.client.impl.Tables;
-import org.apache.accumulo.core.client.mock.MockInstance;
-import org.apache.accumulo.core.client.security.tokens.AuthenticationToken;
-import org.apache.accumulo.core.client.security.tokens.PasswordToken;
-import org.apache.accumulo.core.conf.AccumuloConfiguration;
-import org.apache.accumulo.core.conf.DefaultConfiguration;
-import org.apache.accumulo.core.conf.Property;
-import org.apache.accumulo.core.conf.SiteConfiguration;
-import org.apache.accumulo.core.data.Key;
-import org.apache.accumulo.core.data.Value;
-import org.apache.accumulo.core.data.thrift.TConstraintViolationSummary;
-import org.apache.accumulo.core.tabletserver.thrift.ConstraintViolationException;
-import org.apache.accumulo.core.trace.DistributedTrace;
-import org.apache.accumulo.core.util.BadArgumentException;
-import org.apache.accumulo.core.util.format.BinaryFormatter;
-import org.apache.accumulo.core.util.format.DefaultFormatter;
-import org.apache.accumulo.core.util.format.Formatter;
-import org.apache.accumulo.core.util.format.FormatterFactory;
-import org.apache.accumulo.core.volume.VolumeConfiguration;
-import org.apache.accumulo.core.zookeeper.ZooUtil;
-import org.apache.accumulo.fate.zookeeper.ZooReader;
-import org.apache.accumulo.shell.commands.AboutCommand;
-import org.apache.accumulo.shell.commands.AddAuthsCommand;
-import org.apache.accumulo.shell.commands.AddSplitsCommand;
-import org.apache.accumulo.shell.commands.AuthenticateCommand;
-import org.apache.accumulo.shell.commands.ByeCommand;
-import org.apache.accumulo.shell.commands.ClasspathCommand;
-import org.apache.accumulo.shell.commands.ClearCommand;
-import org.apache.accumulo.shell.commands.CloneTableCommand;
-import org.apache.accumulo.shell.commands.ClsCommand;
-import org.apache.accumulo.shell.commands.CompactCommand;
-import org.apache.accumulo.shell.commands.ConfigCommand;
-import org.apache.accumulo.shell.commands.ConstraintCommand;
-import org.apache.accumulo.shell.commands.CreateNamespaceCommand;
-import org.apache.accumulo.shell.commands.CreateTableCommand;
-import org.apache.accumulo.shell.commands.CreateUserCommand;
-import org.apache.accumulo.shell.commands.DUCommand;
-import org.apache.accumulo.shell.commands.DebugCommand;
-import org.apache.accumulo.shell.commands.DeleteCommand;
-import org.apache.accumulo.shell.commands.DeleteIterCommand;
-import org.apache.accumulo.shell.commands.DeleteManyCommand;
-import org.apache.accumulo.shell.commands.DeleteNamespaceCommand;
-import org.apache.accumulo.shell.commands.DeleteRowsCommand;
-import org.apache.accumulo.shell.commands.DeleteScanIterCommand;
-import org.apache.accumulo.shell.commands.DeleteShellIterCommand;
-import org.apache.accumulo.shell.commands.DeleteTableCommand;
-import org.apache.accumulo.shell.commands.DeleteUserCommand;
-import org.apache.accumulo.shell.commands.DropTableCommand;
-import org.apache.accumulo.shell.commands.DropUserCommand;
-import org.apache.accumulo.shell.commands.EGrepCommand;
-import org.apache.accumulo.shell.commands.ExecfileCommand;
-import org.apache.accumulo.shell.commands.ExitCommand;
-import org.apache.accumulo.shell.commands.ExportTableCommand;
-import org.apache.accumulo.shell.commands.ExtensionCommand;
-import org.apache.accumulo.shell.commands.FateCommand;
-import org.apache.accumulo.shell.commands.FlushCommand;
-import org.apache.accumulo.shell.commands.FormatterCommand;
-import org.apache.accumulo.shell.commands.GetAuthsCommand;
-import org.apache.accumulo.shell.commands.GetGroupsCommand;
-import org.apache.accumulo.shell.commands.GetSplitsCommand;
-import org.apache.accumulo.shell.commands.GrantCommand;
-import org.apache.accumulo.shell.commands.GrepCommand;
-import org.apache.accumulo.shell.commands.HelpCommand;
-import org.apache.accumulo.shell.commands.HiddenCommand;
-import org.apache.accumulo.shell.commands.HistoryCommand;
-import org.apache.accumulo.shell.commands.ImportDirectoryCommand;
-import org.apache.accumulo.shell.commands.ImportTableCommand;
-import org.apache.accumulo.shell.commands.InfoCommand;
-import org.apache.accumulo.shell.commands.InsertCommand;
-import org.apache.accumulo.shell.commands.InterpreterCommand;
-import org.apache.accumulo.shell.commands.ListCompactionsCommand;
-import org.apache.accumulo.shell.commands.ListIterCommand;
-import org.apache.accumulo.shell.commands.ListScansCommand;
-import org.apache.accumulo.shell.commands.ListShellIterCommand;
-import org.apache.accumulo.shell.commands.MaxRowCommand;
-import org.apache.accumulo.shell.commands.MergeCommand;
-import org.apache.accumulo.shell.commands.NamespacePermissionsCommand;
-import org.apache.accumulo.shell.commands.NamespacesCommand;
-import org.apache.accumulo.shell.commands.NoTableCommand;
-import org.apache.accumulo.shell.commands.OfflineCommand;
-import org.apache.accumulo.shell.commands.OnlineCommand;
-import org.apache.accumulo.shell.commands.PasswdCommand;
-import org.apache.accumulo.shell.commands.PingCommand;
-import org.apache.accumulo.shell.commands.QuestionCommand;
-import org.apache.accumulo.shell.commands.QuitCommand;
-import org.apache.accumulo.shell.commands.QuotedStringTokenizer;
-import org.apache.accumulo.shell.commands.RenameNamespaceCommand;
-import org.apache.accumulo.shell.commands.RenameTableCommand;
-import org.apache.accumulo.shell.commands.RevokeCommand;
-import org.apache.accumulo.shell.commands.ScanCommand;
-import org.apache.accumulo.shell.commands.ScriptCommand;
-import org.apache.accumulo.shell.commands.SetAuthsCommand;
-import org.apache.accumulo.shell.commands.SetGroupsCommand;
-import org.apache.accumulo.shell.commands.SetIterCommand;
-import org.apache.accumulo.shell.commands.SetScanIterCommand;
-import org.apache.accumulo.shell.commands.SetShellIterCommand;
-import org.apache.accumulo.shell.commands.SleepCommand;
-import org.apache.accumulo.shell.commands.SystemPermissionsCommand;
-import org.apache.accumulo.shell.commands.TableCommand;
-import org.apache.accumulo.shell.commands.TablePermissionsCommand;
-import org.apache.accumulo.shell.commands.TablesCommand;
-import org.apache.accumulo.shell.commands.TraceCommand;
-import org.apache.accumulo.shell.commands.UserCommand;
-import org.apache.accumulo.shell.commands.UserPermissionsCommand;
-import org.apache.accumulo.shell.commands.UsersCommand;
-import org.apache.accumulo.shell.commands.WhoAmICommand;
-import org.apache.commons.cli.BasicParser;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.HelpFormatter;
-import org.apache.commons.cli.MissingOptionException;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-import org.apache.commons.cli.ParseException;
-import org.apache.hadoop.fs.Path;
-import org.apache.log4j.Level;
-import org.apache.log4j.Logger;
-
-import com.beust.jcommander.JCommander;
-import com.beust.jcommander.ParameterException;
-
-/**
- * A convenient console interface to perform basic accumulo functions Includes auto-complete, help, and quoted strings with escape sequences
- */
-public class Shell extends ShellOptions {
-  public static final Logger log = Logger.getLogger(Shell.class);
-  private static final Logger audit = Logger.getLogger(Shell.class.getName() + ".audit");
-
-  public static final String CHARSET = "ISO-8859-1";
-  public static final int NO_FIXED_ARG_LENGTH_CHECK = -1;
-  public static final String COMMENT_PREFIX = "#";
-  public static final String HISTORY_DIR_NAME = ".accumulo";
-  public static final String HISTORY_FILE_NAME = "shell_history.txt";
-  private static final String SHELL_DESCRIPTION = "Shell - Apache Accumulo Interactive Shell";
-
-  protected int exitCode = 0;
-  private String tableName;
-  protected Instance instance;
-  private Connector connector;
-  protected ConsoleReader reader;
-  private String principal;
-  private AuthenticationToken token;
-  private final Class<? extends Formatter> defaultFormatterClass = DefaultFormatter.class;
-  private final Class<? extends Formatter> binaryFormatterClass = BinaryFormatter.class;
-  public Map<String,List<IteratorSetting>> scanIteratorOptions = new HashMap<String,List<IteratorSetting>>();
-  public Map<String,List<IteratorSetting>> iteratorProfiles = new HashMap<String,List<IteratorSetting>>();
-
-  private Token rootToken;
-  public final Map<String,Command> commandFactory = new TreeMap<String,Command>();
-  public final Map<String,Command[]> commandGrouping = new TreeMap<String,Command[]>();
-  protected boolean configError = false;
-
-  // exit if true
-  private boolean exit = false;
-
-  // file to execute commands from
-  protected File execFile = null;
-  // single command to execute from the command line
-  protected String execCommand = null;
-  protected boolean verbose = true;
-
-  private boolean tabCompletion;
-  private boolean disableAuthTimeout;
-  private long authTimeout;
-  private long lastUserActivity = System.currentTimeMillis();
-  private boolean logErrorsToConsole = false;
-  private PrintWriter writer = null;
-  private boolean masking = false;
-
-  public Shell() throws IOException {
-    this(new ConsoleReader(), new PrintWriter(
-        new OutputStreamWriter(System.out,
-        System.getProperty("jline.WindowsTerminal.output.encoding", System.getProperty("file.encoding")))));
-  }
-
-  public Shell(ConsoleReader reader, PrintWriter writer) {
-    super();
-    this.reader = reader;
-    this.writer = writer;
-  }
-
-  // Not for client use
-  public boolean config(String... args) {
-    ShellOptionsJC options = new ShellOptionsJC();
-    JCommander jc = new JCommander();
-
-    jc.setProgramName("accumulo shell");
-    jc.addObject(options);
-    try {
-      jc.parse(args);
-    } catch (ParameterException e) {
-      configError = true;
-    }
-
-    if (options.isHelpEnabled()) {
-      configError = true;
-    }
-
-    if (!configError && options.getUnrecognizedOptions() != null) {
-      configError = true;
-      logError("Unrecognized Options: " + options.getUnrecognizedOptions().toString());
-    }
-
-    if (configError) {
-      jc.usage();
-      return true;
-    }
-
-    setDebugging(options.isDebugEnabled());
-    authTimeout = options.getAuthTimeout() * 60 * 1000; // convert minutes to milliseconds
-    disableAuthTimeout = options.isAuthTimeoutDisabled();
-
-    // get the options that were parsed
-    String user = options.getUsername();
-    String password = options.getPassword();
-
-    tabCompletion = !options.isTabCompletionDisabled();
-
-    // Use a fake (Mock), ZK, or HdfsZK Accumulo instance
-    setInstance(options);
-
-    // AuthenticationToken options
-    token = options.getAuthenticationToken();
-    Map<String,String> loginOptions = options.getTokenProperties();
-
-    // process default parameters if unspecified
-    try {
-      boolean hasToken = (token != null);
-      boolean hasTokenOptions = !loginOptions.isEmpty();
-
-      if (hasToken && password != null) {
-        throw new ParameterException("Can not supply '--pass' option with '--tokenClass' option");
-      }
-
-      Runtime.getRuntime().addShutdownHook(new Thread() {
-        @Override
-        public void run() {
-          reader.getTerminal().setEchoEnabled(true);
-        }
-      });
-
-      // Need either both a token and options, or neither, but not just one.
-      if (hasToken != hasTokenOptions) {
-        throw new ParameterException("Must supply either both or neither of '--tokenClass' and '--tokenProperty'");
-      } else if (hasToken) { // implied hasTokenOptions
-        // Fully qualified name so we don't shadow java.util.Properties
-        org.apache.accumulo.core.client.security.tokens.AuthenticationToken.Properties props;
-        // and line wrap it because the package name is so long
-        props = new org.apache.accumulo.core.client.security.tokens.AuthenticationToken.Properties();
-
-        props.putAllStrings(loginOptions);
-        token.init(props);
-      } else {
-        // Read password if the user explicitly asked for it, or didn't specify anything at all
-        if ("stdin".equals(password) || password == null) {
-          password = reader.readLine("Password: ", '*');
-        }
-
-        if (password == null) {
-          // User cancel, e.g. Ctrl-D pressed
-          throw new ParameterException("No password or token option supplied");
-        } else {
-          this.token = new PasswordToken(password);
-        }
-      }
-
-      if (!options.isFake()) {
-        ZooReader zr = new ZooReader(instance.getZooKeepers(), instance.getZooKeepersSessionTimeOut());
-        DistributedTrace.enable(instance, zr, "shell", InetAddress.getLocalHost().getHostName());
-      }
-
-      this.setTableName("");
-      this.principal = user;
-      connector = instance.getConnector(this.principal, token);
-
-    } catch (Exception e) {
-      printException(e);
-      configError = true;
-    }
-
-    // decide whether to execute commands from a file and quit
-    if (options.getExecFile() != null) {
-      execFile = options.getExecFile();
-      verbose = false;
-    } else if (options.getExecFileVerbose() != null) {
-      execFile = options.getExecFileVerbose();
-      verbose = true;
-    }
-    execCommand = options.getExecCommand();
-    if (execCommand != null) {
-      verbose = false;
-    }
-
-    rootToken = new Token();
-
-    Command[] dataCommands = {new DeleteCommand(), new DeleteManyCommand(), new DeleteRowsCommand(), new EGrepCommand(), new FormatterCommand(),
-        new InterpreterCommand(), new GrepCommand(), new ImportDirectoryCommand(), new InsertCommand(), new MaxRowCommand(), new ScanCommand()};
-    Command[] debuggingCommands = {new ClasspathCommand(), new DebugCommand(), new ListScansCommand(), new ListCompactionsCommand(), new TraceCommand(),
-        new PingCommand()};
-    Command[] execCommands = {new ExecfileCommand(), new HistoryCommand(), new ExtensionCommand(), new ScriptCommand()};
-    Command[] exitCommands = {new ByeCommand(), new ExitCommand(), new QuitCommand()};
-    Command[] helpCommands = {new AboutCommand(), new HelpCommand(), new InfoCommand(), new QuestionCommand()};
-    Command[] iteratorCommands = {new DeleteIterCommand(), new DeleteScanIterCommand(), new ListIterCommand(), new SetIterCommand(), new SetScanIterCommand(),
-        new SetShellIterCommand(), new ListShellIterCommand(), new DeleteShellIterCommand()};
-    Command[] otherCommands = {new HiddenCommand()};
-    Command[] permissionsCommands = {new GrantCommand(), new RevokeCommand(), new SystemPermissionsCommand(), new TablePermissionsCommand(),
-        new UserPermissionsCommand(), new NamespacePermissionsCommand()};
-    Command[] stateCommands = {new AuthenticateCommand(), new ClsCommand(), new ClearCommand(), new FateCommand(), new NoTableCommand(), new SleepCommand(),
-        new TableCommand(), new UserCommand(), new WhoAmICommand()};
-    Command[] tableCommands = {new CloneTableCommand(), new ConfigCommand(), new CreateTableCommand(), new DeleteTableCommand(), new DropTableCommand(),
-        new DUCommand(), new ExportTableCommand(), new ImportTableCommand(), new OfflineCommand(), new OnlineCommand(), new RenameTableCommand(),
-        new TablesCommand(), new NamespacesCommand(), new CreateNamespaceCommand(), new DeleteNamespaceCommand(), new RenameNamespaceCommand()};
-    Command[] tableControlCommands = {new AddSplitsCommand(), new CompactCommand(), new ConstraintCommand(), new FlushCommand(), new GetGroupsCommand(),
-        new GetSplitsCommand(), new MergeCommand(), new SetGroupsCommand()};
-    Command[] userCommands = {new AddAuthsCommand(), new CreateUserCommand(), new DeleteUserCommand(), new DropUserCommand(), new GetAuthsCommand(),
-        new PasswdCommand(), new SetAuthsCommand(), new UsersCommand()};
-    commandGrouping.put("-- Writing, Reading, and Removing Data --", dataCommands);
-    commandGrouping.put("-- Debugging Commands -------------------", debuggingCommands);
-    commandGrouping.put("-- Shell Execution Commands -------------", execCommands);
-    commandGrouping.put("-- Exiting Commands ---------------------", exitCommands);
-    commandGrouping.put("-- Help Commands ------------------------", helpCommands);
-    commandGrouping.put("-- Iterator Configuration ---------------", iteratorCommands);
-    commandGrouping.put("-- Permissions Administration Commands --", permissionsCommands);
-    commandGrouping.put("-- Shell State Commands -----------------", stateCommands);
-    commandGrouping.put("-- Table Administration Commands --------", tableCommands);
-    commandGrouping.put("-- Table Control Commands ---------------", tableControlCommands);
-    commandGrouping.put("-- User Administration Commands ---------", userCommands);
-
-    for (Command[] cmds : commandGrouping.values()) {
-      for (Command cmd : cmds)
-        commandFactory.put(cmd.getName(), cmd);
-    }
-    for (Command cmd : otherCommands) {
-      commandFactory.put(cmd.getName(), cmd);
-    }
-    return configError;
-  }
-
-  /**
-   * Sets the instance used by the shell based on the given options.
-   * 
-   * @param options
-   *          shell options
-   */
-  protected void setInstance(ShellOptionsJC options) {
-    // should only be one set of instance options set
-    instance = null;
-    if (options.isFake()) {
-      instance = new MockInstance("fake");
-    } else {
-      String instanceName, hosts;
-      if (options.isHdfsZooInstance()) {
-        instanceName = hosts = null;
-      } else if (options.getZooKeeperInstance().size() > 0) {
-        List<String> zkOpts = options.getZooKeeperInstance();
-        instanceName = zkOpts.get(0);
-        hosts = zkOpts.get(1);
-      } else {
-        instanceName = options.getZooKeeperInstanceName();
-        hosts = options.getZooKeeperHosts();
-      }
-      try {
-        instance = getZooInstance(instanceName, hosts, options.getClientConfiguration());
-      } catch (Exception e) {
-        throw new IllegalArgumentException("Unable to load client config from " + options.getClientConfigFile(), e);
-      }
-    }
-  }
-
-  /*
-   * Takes instanceName and keepers as separate arguments, rather than just packaged into the clientConfig, so that we can fail over to accumulo-site.xml or
-   * HDFS config if they're unspecified.
-   */
-  private static Instance getZooInstance(String instanceName, String keepers, ClientConfiguration clientConfig) {
-    UUID instanceId = null;
-    if (instanceName == null) {
-      instanceName = clientConfig.get(ClientProperty.INSTANCE_NAME);
-    }
-    if (instanceName == null || keepers == null) {
-      AccumuloConfiguration conf = SiteConfiguration.getInstance(ServerConfigurationUtil.convertClientConfig(DefaultConfiguration.getInstance(), clientConfig));
-      if (instanceName == null) {
-        Path instanceDir = new Path(VolumeConfiguration.getVolumeUris(conf)[0], "instance_id");
-        instanceId = UUID.fromString(ZooUtil.getInstanceIDFromHdfs(instanceDir, conf));
-      }
-      if (keepers == null) {
-        keepers = conf.get(Property.INSTANCE_ZK_HOST);
-      }
-    }
-    if (instanceId != null) {
-      return new ZooKeeperInstance(clientConfig.withInstance(instanceId).withZkHosts(keepers));
-    } else {
-      return new ZooKeeperInstance(clientConfig.withInstance(instanceName).withZkHosts(keepers));
-    }
-  }
-
-  public Connector getConnector() {
-    return connector;
-  }
-
-  public Instance getInstance() {
-    return instance;
-  }
-
-  public static void main(String args[]) throws IOException {
-    Shell shell = new Shell();
-    try {
-      shell.config(args);
-
-      System.exit(shell.start());
-    } finally {
-      shell.shutdown();
-    }
-  }
-
-  public int start() throws IOException {
-    if (configError)
-      return 1;
-
-    String input;
-    if (isVerbose())
-      printInfo();
-
-    String home = System.getProperty("HOME");
-    if (home == null)
-      home = System.getenv("HOME");
-    String configDir = home + "/" + HISTORY_DIR_NAME;
-    String historyPath = configDir + "/" + HISTORY_FILE_NAME;
-    File accumuloDir = new File(configDir);
-    if (!accumuloDir.exists() && !accumuloDir.mkdirs())
-      log.warn("Unable to make directory for history at " + accumuloDir);
-    try {
-      final FileHistory history = new FileHistory(new File(historyPath));
-      reader.setHistory(history);
-      // Add shutdown hook to flush file history, per jline javadocs
-      Runtime.getRuntime().addShutdownHook(new Thread() {
-        @Override
-        public void run() {
-          try {
-            history.flush();
-          } catch (IOException e) {
-            log.warn("Could not flush history to file.");
-          }
-        }
-      });
-    } catch (IOException e) {
-      log.warn("Unable to load history file at " + historyPath);
-    }
-
-    // Turn Ctrl+C into Exception instead of JVM exit
-    reader.setHandleUserInterrupt(true);
-
-    ShellCompletor userCompletor = null;
-
-    if (execFile != null) {
-      java.util.Scanner scanner = new java.util.Scanner(execFile, StandardCharsets.UTF_8.name());
-      try {
-        while (scanner.hasNextLine() && !hasExited()) {
-          execCommand(scanner.nextLine(), true, isVerbose());
-        }
-      } finally {
-        scanner.close();
-      }
-    } else if (execCommand != null) {
-      for (String command : execCommand.split("\n")) {
-        execCommand(command, true, isVerbose());
-      }
-      return exitCode;
-    }
-
-    while (true) {
-      try {
-        if (hasExited())
-          return exitCode;
-
-        // If tab completion is true we need to reset
-        if (tabCompletion) {
-          if (userCompletor != null)
-            reader.removeCompleter(userCompletor);
-
-          userCompletor = setupCompletion();
-          reader.addCompleter(userCompletor);
-        }
-
-        reader.setPrompt(getDefaultPrompt());
-        input = reader.readLine();
-        if (input == null) {
-          reader.println();
-          return exitCode;
-        } // User Canceled (Ctrl+D)
-
-        execCommand(input, disableAuthTimeout, false);
-      } catch (UserInterruptException uie) {
-        // User Cancelled (Ctrl+C)
-        reader.println();
-
-        String partialLine = uie.getPartialLine();
-        if (partialLine == null || "".equals(uie.getPartialLine().trim())) {
-          // No content, actually exit
-          return exitCode;
-        }
-      } finally {
-        reader.flush();
-      }
-    }
-  }
-
-  public void shutdown() {
-    if (reader != null) {
-      reader.shutdown();
-    }
-  }
-
-  public void printInfo() throws IOException {
-    reader.print("\n" + SHELL_DESCRIPTION + "\n" + "- \n" + "- version: " + Constants.VERSION + "\n" + "- instance name: "
-        + connector.getInstance().getInstanceName() + "\n" + "- instance id: " + connector.getInstance().getInstanceID() + "\n" + "- \n"
-        + "- type 'help' for a list of available commands\n" + "- \n");
-    reader.flush();
-  }
-
-  public void printVerboseInfo() throws IOException {
-    StringBuilder sb = new StringBuilder("-\n");
-    sb.append("- Current user: ").append(connector.whoami()).append("\n");
-    if (execFile != null)
-      sb.append("- Executing commands from: ").append(execFile).append("\n");
-    if (disableAuthTimeout)
-      sb.append("- Authorization timeout: disabled\n");
-    else
-      sb.append("- Authorization timeout: ").append(String.format("%.2fs%n", authTimeout / 1000.0));
-    sb.append("- Debug: ").append(isDebuggingEnabled() ? "on" : "off").append("\n");
-    if (!scanIteratorOptions.isEmpty()) {
-      for (Entry<String,List<IteratorSetting>> entry : scanIteratorOptions.entrySet()) {
-        sb.append("- Session scan iterators for table ").append(entry.getKey()).append(":\n");
-        for (IteratorSetting setting : entry.getValue()) {
-          sb.append("-    Iterator ").append(setting.getName()).append(" options:\n");
-          sb.append("-        ").append("iteratorPriority").append(" = ").append(setting.getPriority()).append("\n");
-          sb.append("-        ").append("iteratorClassName").append(" = ").append(setting.getIteratorClass()).append("\n");
-          for (Entry<String,String> optEntry : setting.getOptions().entrySet()) {
-            sb.append("-        ").append(optEntry.getKey()).append(" = ").append(optEntry.getValue()).append("\n");
-          }
-        }
-      }
-    }
-    sb.append("-\n");
-    reader.print(sb.toString());
-  }
-
-  public String getDefaultPrompt() {
-    return connector.whoami() + "@" + connector.getInstance().getInstanceName() + (getTableName().isEmpty() ? "" : " ") + getTableName() + "> ";
-  }
-
-  public void execCommand(String input, boolean ignoreAuthTimeout, boolean echoPrompt) throws IOException {
-    audit.log(Level.INFO, getDefaultPrompt() + input);
-    if (echoPrompt) {
-      reader.print(getDefaultPrompt());
-      reader.println(input);
-    }
-
-    if (input.startsWith(COMMENT_PREFIX)) {
-      return;
-    }
-
-    String fields[];
-    try {
-      fields = new QuotedStringTokenizer(input).getTokens();
-    } catch (BadArgumentException e) {
-      printException(e);
-      ++exitCode;
-      return;
-    }
-    if (fields.length == 0)
-      return;
-
-    String command = fields[0];
-    fields = fields.length > 1 ? Arrays.copyOfRange(fields, 1, fields.length) : new String[] {};
-
-    Command sc = null;
-    if (command.length() > 0) {
-      try {
-        // Obtain the command from the command table
-        sc = commandFactory.get(command);
-        if (sc == null) {
-          reader.println(String.format("Unknown command \"%s\".  Enter \"help\" for a list possible commands.", command));
-          reader.flush();
-          return;
-        }
-
-        if (!(sc instanceof ExitCommand) && !ignoreAuthTimeout && System.currentTimeMillis() - lastUserActivity > authTimeout) {
-          reader.println("Shell has been idle for too long. Please re-authenticate.");
-          boolean authFailed = true;
-          do {
-            String pwd = readMaskedLine("Enter current password for '" + connector.whoami() + "': ", '*');
-            if (pwd == null) {
-              reader.println();
-              return;
-            } // user canceled
-
-            try {
-              authFailed = !connector.securityOperations().authenticateUser(connector.whoami(), new PasswordToken(pwd));
-            } catch (Exception e) {
-              ++exitCode;
-              printException(e);
-            }
-
-            if (authFailed)
-              reader.print("Invalid password. ");
-          } while (authFailed);
-          lastUserActivity = System.currentTimeMillis();
-        }
-
-        // Get the options from the command on how to parse the string
-        Options parseOpts = sc.getOptionsWithHelp();
-
-        // Parse the string using the given options
-        CommandLine cl = new BasicParser().parse(parseOpts, fields);
-
-        int actualArgLen = cl.getArgs().length;
-        int expectedArgLen = sc.numArgs();
-        if (cl.hasOption(helpOption)) {
-          // Display help if asked to; otherwise execute the command
-          sc.printHelp(this);
-        } else if (expectedArgLen != NO_FIXED_ARG_LENGTH_CHECK && actualArgLen != expectedArgLen) {
-          ++exitCode;
-          // Check for valid number of fixed arguments (if not
-          // negative; negative means it is not checked, for
-          // vararg-like commands)
-          printException(new IllegalArgumentException(String.format("Expected %d argument%s. There %s %d.", expectedArgLen, expectedArgLen == 1 ? "" : "s",
-              actualArgLen == 1 ? "was" : "were", actualArgLen)));
-          sc.printHelp(this);
-        } else {
-          int tmpCode = sc.execute(input, cl, this);
-          exitCode += tmpCode;
-          reader.flush();
-        }
-
-      } catch (ConstraintViolationException e) {
-        ++exitCode;
-        printConstraintViolationException(e);
-      } catch (TableNotFoundException e) {
-        ++exitCode;
-        if (getTableName().equals(e.getTableName()))
-          setTableName("");
-        printException(e);
-      } catch (ParseException e) {
-        // not really an error if the exception is a missing required
-        // option when the user is asking for help
-        if (!(e instanceof MissingOptionException && (Arrays.asList(fields).contains("-" + helpOption) || Arrays.asList(fields).contains("--" + helpLongOption)))) {
-          ++exitCode;
-          printException(e);
-        }
-        if (sc != null)
-          sc.printHelp(this);
-      } catch (UserInterruptException e) {
-        ++exitCode;
-      } catch (Exception e) {
-        ++exitCode;
-        printException(e);
-      }
-    } else {
-      ++exitCode;
-      printException(new BadArgumentException("Unrecognized empty command", command, -1));
-    }
-    reader.flush();
-  }
-
-  /**
-   * The command tree is built in reverse so that the references are more easily linked up. There is some code in token to allow forward building of the command
-   * tree.
-   */
-  private ShellCompletor setupCompletion() {
-    rootToken = new Token();
-
-    Set<String> tableNames = null;
-    try {
-      tableNames = connector.tableOperations().list();
-    } catch (Exception e) {
-      log.debug("Unable to obtain list of tables", e);
-      tableNames = Collections.emptySet();
-    }
-
-    Set<String> userlist = null;
-    try {
-      userlist = connector.securityOperations().listLocalUsers();
-    } catch (Exception e) {
-      log.debug("Unable to obtain list of users", e);
-      userlist = Collections.emptySet();
-    }
-
-    Set<String> namespaces = null;
-    try {
-      namespaces = connector.namespaceOperations().list();
-    } catch (Exception e) {
-      log.debug("Unable to obtain list of namespaces", e);
-      namespaces = Collections.emptySet();
-    }
-
-    Map<Command.CompletionSet,Set<String>> options = new HashMap<Command.CompletionSet,Set<String>>();
-
-    Set<String> commands = new HashSet<String>();
-    for (String a : commandFactory.keySet())
-      commands.add(a);
-
-    Set<String> modifiedUserlist = new HashSet<String>();
-    Set<String> modifiedTablenames = new HashSet<String>();
-    Set<String> modifiedNamespaces = new HashSet<String>();
-
-    for (String a : tableNames)
-      modifiedTablenames.add(a.replaceAll("([\\s'\"])", "\\\\$1"));
-    for (String a : userlist)
-      modifiedUserlist.add(a.replaceAll("([\\s'\"])", "\\\\$1"));
-    for (String a : namespaces) {
-      String b = a.replaceAll("([\\s'\"])", "\\\\$1");
-      modifiedNamespaces.add(b.isEmpty() ? "\"\"" : b);
-    }
-
-    options.put(Command.CompletionSet.USERNAMES, modifiedUserlist);
-    options.put(Command.CompletionSet.TABLENAMES, modifiedTablenames);
-    options.put(Command.CompletionSet.NAMESPACES, modifiedNamespaces);
-    options.put(Command.CompletionSet.COMMANDS, commands);
-
-    for (Command[] cmdGroup : commandGrouping.values()) {
-      for (Command c : cmdGroup) {
-        c.getOptionsWithHelp(); // prep the options for the command
-        // so that the completion can
-        // include them
-        c.registerCompletion(rootToken, options);
-      }
-    }
-    return new ShellCompletor(rootToken, options);
-  }
-
-  /**
-   * The Command class represents a command to be run in the shell. It contains the methods to execute along with some methods to help tab completion, and
-   * return the command name, help, and usage.
-   */
-  public static abstract class Command {
-    // Helper methods for completion
-    public enum CompletionSet {
-      TABLENAMES, USERNAMES, COMMANDS, NAMESPACES
-    }
-
-    static Set<String> getCommandNames(Map<CompletionSet,Set<String>> objects) {
-      return objects.get(CompletionSet.COMMANDS);
-    }
-
-    static Set<String> getTableNames(Map<CompletionSet,Set<String>> objects) {
-      return objects.get(CompletionSet.TABLENAMES);
-    }
-
-    static Set<String> getUserNames(Map<CompletionSet,Set<String>> objects) {
-      return objects.get(CompletionSet.USERNAMES);
-    }
-
-    static Set<String> getNamespaces(Map<CompletionSet,Set<String>> objects) {
-      return objects.get(CompletionSet.NAMESPACES);
-    }
-
-    public void registerCompletionGeneral(Token root, Set<String> args, boolean caseSens) {
-      Token t = new Token(args);
-      t.setCaseSensitive(caseSens);
-
-      Token command = new Token(getName());
-      command.addSubcommand(t);
-
-      root.addSubcommand(command);
-    }
-
-    public void registerCompletionForTables(Token root, Map<CompletionSet,Set<String>> completionSet) {
-      registerCompletionGeneral(root, completionSet.get(CompletionSet.TABLENAMES), true);
-    }
-
-    public void registerCompletionForUsers(Token root, Map<CompletionSet,Set<String>> completionSet) {
-      registerCompletionGeneral(root, completionSet.get(CompletionSet.USERNAMES), true);
-    }
-
-    public void registerCompletionForCommands(Token root, Map<CompletionSet,Set<String>> completionSet) {
-      registerCompletionGeneral(root, completionSet.get(CompletionSet.COMMANDS), false);
-    }
-
-    public void registerCompletionForNamespaces(Token root, Map<CompletionSet,Set<String>> completionSet) {
-      registerCompletionGeneral(root, completionSet.get(CompletionSet.NAMESPACES), true);
-    }
-
-    // abstract methods to override
-    public abstract int execute(String fullCommand, CommandLine cl, Shell shellState) throws Exception;
-
-    public abstract String description();
-
-    /**
-     * If the number of arguments is not always zero (not including those arguments handled through Options), make sure to override the {@link #usage()} method.
-     * Otherwise, {@link #usage()} does need to be overridden.
-     */
-    public abstract int numArgs();
-
-    // OPTIONAL methods to override:
-
-    // the general version of getname uses reflection to get the class name
-    // and then cuts off the suffix -Command to get the name of the command
-    public String getName() {
-      String s = this.getClass().getName();
-      int st = Math.max(s.lastIndexOf('$'), s.lastIndexOf('.'));
-      int i = s.indexOf("Command");
-      return i > 0 ? s.substring(st + 1, i).toLowerCase(Locale.ENGLISH) : null;
-    }
-
-    // The general version of this method adds the name
-    // of the command to the completion tree
-    public void registerCompletion(Token root, Map<CompletionSet,Set<String>> completion_set) {
-      root.addSubcommand(new Token(getName()));
-    }
-
-    // The general version of this method uses the HelpFormatter
-    // that comes with the apache Options package to print out the help
-    public final void printHelp(Shell shellState) {
-      shellState.printHelp(usage(), "description: " + this.description(), getOptionsWithHelp());
-    }
-
-    public final void printHelp(Shell shellState, int width) {
-      shellState.printHelp(usage(), "description: " + this.description(), getOptionsWithHelp(), width);
-    }
-
-    // Get options with help
-    public final Options getOptionsWithHelp() {
-      Options opts = getOptions();
-      opts.addOption(new Option(helpOption, helpLongOption, false, "display this help"));
-      return opts;
-    }
-
-    // General usage is just the command
-    public String usage() {
-      return getName();
-    }
-
-    // General Options are empty
-    public Options getOptions() {
-      return new Options();
-    }
-  }
-
-  public interface PrintLine {
-    void print(String s);
-
-    void close();
-  }
-
-  public static class PrintShell implements PrintLine {
-    ConsoleReader reader;
-
-    public PrintShell(ConsoleReader reader) {
-      this.reader = reader;
-    }
-
-    @Override
-    public void print(String s) {
-      try {
-        reader.println(s);
-      } catch (Exception ex) {
-        throw new RuntimeException(ex);
-      }
-    }
-
-    @Override
-    public void close() {}
-  };
-
-  public static class PrintFile implements PrintLine {
-    PrintWriter writer;
-
-    public PrintFile(String filename) throws FileNotFoundException {
-      writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(filename), StandardCharsets.UTF_8)));
-    }
-
-    @Override
-    public void print(String s) {
-      writer.println(s);
-    }
-
-    @Override
-    public void close() {
-      writer.close();
-    }
-  };
-
-  public final void printLines(Iterator<String> lines, boolean paginate) throws IOException {
-    printLines(lines, paginate, null);
-  }
-
-  public final void printLines(Iterator<String> lines, boolean paginate, PrintLine out) throws IOException {
-    int linesPrinted = 0;
-    String prompt = "-- hit any key to continue or 'q' to quit --";
-    int lastPromptLength = prompt.length();
-    int termWidth = reader.getTerminal().getWidth();
-    int maxLines = reader.getTerminal().getHeight();
-
-    String peek = null;
-    while (lines.hasNext()) {
-      String nextLine = lines.next();
-      if (nextLine == null)
-        continue;
-      for (String line : nextLine.split("\\n")) {
-        if (out == null) {
-          if (peek != null) {
-            reader.println(peek);
-            if (paginate) {
-              linesPrinted += peek.length() == 0 ? 0 : Math.ceil(peek.length() * 1.0 / termWidth);
-
-              // check if displaying the next line would result in
-              // scrolling off the screen
-              if (linesPrinted + Math.ceil(lastPromptLength * 1.0 / termWidth) + Math.ceil(prompt.length() * 1.0 / termWidth)
-                  + Math.ceil(line.length() * 1.0 / termWidth) > maxLines) {
-                linesPrinted = 0;
-                int numdashes = (termWidth - prompt.length()) / 2;
-                String nextPrompt = repeat("-", numdashes) + prompt + repeat("-", numdashes);
-                lastPromptLength = nextPrompt.length();
-                reader.print(nextPrompt);
-                reader.flush();
-
-                if (Character.toUpperCase((char) reader.readCharacter()) == 'Q') {
-                  reader.println();
-                  return;
-                }
-                reader.println();
-                termWidth = reader.getTerminal().getWidth();
-                maxLines = reader.getTerminal().getHeight();
-              }
-            }
-          }
-          peek = line;
-        } else {
-          out.print(line);
-        }
-      }
-    }
-    if (out == null && peek != null) {
-      reader.println(peek);
-    }
-  }
-
-  public final void printRecords(Iterable<Entry<Key,Value>> scanner, boolean printTimestamps, boolean paginate, Class<? extends Formatter> formatterClass,
-      PrintLine outFile) throws IOException {
-    printLines(FormatterFactory.getFormatter(formatterClass, scanner, printTimestamps), paginate, outFile);
-  }
-
-  public final void printRecords(Iterable<Entry<Key,Value>> scanner, boolean printTimestamps, boolean paginate, Class<? extends Formatter> formatterClass)
-      throws IOException {
-    printLines(FormatterFactory.getFormatter(formatterClass, scanner, printTimestamps), paginate);
-  }
-
-  public final void printBinaryRecords(Iterable<Entry<Key,Value>> scanner, boolean printTimestamps, boolean paginate, PrintLine outFile) throws IOException {
-    printLines(FormatterFactory.getFormatter(binaryFormatterClass, scanner, printTimestamps), paginate, outFile);
-  }
-
-  public final void printBinaryRecords(Iterable<Entry<Key,Value>> scanner, boolean printTimestamps, boolean paginate) throws IOException {
-    printLines(FormatterFactory.getFormatter(binaryFormatterClass, scanner, printTimestamps), paginate);
-  }
-
-  public static String repeat(String s, int c) {
-    StringBuilder sb = new StringBuilder();
-    for (int i = 0; i < c; i++)
-      sb.append(s);
-    return sb.toString();
-  }
-
-  public void checkTableState() {
-    if (getTableName().isEmpty())
-      throw new IllegalStateException(
-          "Not in a table context. Please use 'table <tableName>' to switch to a table, or use '-t' to specify a table if option is available.");
-  }
-
-  private final void printConstraintViolationException(ConstraintViolationException cve) {
-    printException(cve, "");
-    int COL1 = 50, COL2 = 14;
-    int col3 = Math.max(1, Math.min(Integer.MAX_VALUE, reader.getTerminal().getWidth() - COL1 - COL2 - 6));
-    logError(String.format("%" + COL1 + "s-+-%" + COL2 + "s-+-%" + col3 + "s%n", repeat("-", COL1), repeat("-", COL2), repeat("-", col3)));
-    logError(String.format("%-" + COL1 + "s | %" + COL2 + "s | %-" + col3 + "s%n", "Constraint class", "Violation code", "Violation Description"));
-    logError(String.format("%" + COL1 + "s-+-%" + COL2 + "s-+-%" + col3 + "s%n", repeat("-", COL1), repeat("-", COL2), repeat("-", col3)));
-    for (TConstraintViolationSummary cvs : cve.violationSummaries)
-      logError(String.format("%-" + COL1 + "s | %" + COL2 + "d | %-" + col3 + "s%n", cvs.constrainClass, cvs.violationCode, cvs.violationDescription));
-    logError(String.format("%" + COL1 + "s-+-%" + COL2 + "s-+-%" + col3 + "s%n", repeat("-", COL1), repeat("-", COL2), repeat("-", col3)));
-  }
-
-  public final void printException(Exception e) {
-    printException(e, e.getMessage());
-  }
-
-  private final void printException(Exception e, String msg) {
-    logError(e.getClass().getName() + (msg != null ? ": " + msg : ""));
-    log.debug(e.getClass().getName() + (msg != null ? ": " + msg : ""), e);
-  }
-
-  public static final void setDebugging(boolean debuggingEnabled) {
-    Logger.getLogger(Constants.CORE_PACKAGE_NAME).setLevel(debuggingEnabled ? Level.TRACE : Level.INFO);
-  }
-
-  public static final boolean isDebuggingEnabled() {
-    return Logger.getLogger(Constants.CORE_PACKAGE_NAME).isTraceEnabled();
-  }
-
-  private final void printHelp(String usage, String description, Options opts) {
-    printHelp(usage, description, opts, Integer.MAX_VALUE);
-  }
-
-  private final void printHelp(String usage, String description, Options opts, int width) {
-    // TODO Use the OutputStream from the JLine ConsoleReader if we can ever get access to it
-    new HelpFormatter().printHelp(writer, width, usage, description, opts, 2, 5, null, true);
-    writer.flush();
-  }
-
-  public int getExitCode() {
-    return exitCode;
-  }
-
-  public void resetExitCode() {
-    exitCode = 0;
-  }
-
-  public void setExit(boolean exit) {
-    this.exit = exit;
-  }
-
-  public boolean getExit() {
-    return this.exit;
-  }
-
-  public boolean isVerbose() {
-    return verbose;
-  }
-
-  public void setTableName(String tableName) {
-    this.tableName = (tableName == null || tableName.isEmpty()) ? "" : Tables.qualified(tableName);
-  }
-
-  public String getTableName() {
-    return tableName;
-  }
-
-  public ConsoleReader getReader() {
-    return reader;
-  }
-
-  public void updateUser(String principal, AuthenticationToken token) throws AccumuloException, AccumuloSecurityException {
-    connector = instance.getConnector(principal, token);
-    this.principal = principal;
-    this.token = token;
-  }
-
-  public String getPrincipal() {
-    return principal;
-  }
-
-  public AuthenticationToken getToken() {
-    return token;
-  }
-
-  /**
-   * Return the formatter for the current table.
-   * 
-   * @return the formatter class for the current table
-   */
-  public Class<? extends Formatter> getFormatter() {
-    return getFormatter(this.tableName);
-  }
-
-  /**
-   * Return the formatter for the given table.
-   * 
-   * @param tableName
-   *          the table name
-   * @return the formatter class for the given table
-   */
-  public Class<? extends Formatter> getFormatter(String tableName) {
-    Class<? extends Formatter> formatter = FormatterCommand.getCurrentFormatter(tableName, this);
-
-    if (null == formatter) {
-      logError("Could not load the specified formatter. Using the DefaultFormatter");
-      return this.defaultFormatterClass;
-    } else {
-      return formatter;
-    }
-  }
-
-  public void setLogErrorsToConsole() {
-    this.logErrorsToConsole = true;
-  }
-
-  private void logError(String s) {
-    log.error(s);
-    if (logErrorsToConsole) {
-      try {
-        reader.println("ERROR: " + s);
-        reader.flush();
-      } catch (IOException e) {}
-    }
-  }
-
-  public String readMaskedLine(String prompt, Character mask) throws IOException {
-    this.masking = true;
-    String s = reader.readLine(prompt, mask);
-    this.masking = false;
-    return s;
-  }
-
-  public boolean isMasking() {
-    return masking;
-  }
-
-  public boolean hasExited() {
-    return exit;
-  }
-
-  public boolean isTabCompletion() {
-    return tabCompletion;
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/ShellCommandException.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/ShellCommandException.java b/shell/src/main/java/org/apache/accumulo/shell/ShellCommandException.java
deleted file mode 100644
index b25e9da..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/ShellCommandException.java
+++ /dev/null
@@ -1,59 +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.accumulo.shell;
-
-public class ShellCommandException extends Exception {
-  private static final long serialVersionUID = 1L;
-  
-  public enum ErrorCode {
-    UNKNOWN_ERROR("Unknown error"),
-    UNSUPPORTED_LANGUAGE("Programming language used is not supported"),
-    UNRECOGNIZED_COMMAND("Command is not supported"),
-    INITIALIZATION_FAILURE("Command could not be initialized"),
-    XML_PARSING_ERROR("Failed to parse the XML file");
-    
-    private String description;
-    
-    private ErrorCode(String description) {
-      this.description = description;
-    }
-    
-    public String getDescription() {
-      return this.description;
-    }
-    
-    public String toString() {
-      return getDescription();
-    }
-  }
-  
-  private ErrorCode code;
-  private String command;
-  
-  public ShellCommandException(ErrorCode code) {
-    this(code, null);
-  }
-  
-  public ShellCommandException(ErrorCode code, String command) {
-    this.code = code;
-    this.command = command;
-  }
-  
-  public String getMessage() {
-    return code + (command != null ? " (" + command + ")" : "");
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/ShellCompletor.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/ShellCompletor.java b/shell/src/main/java/org/apache/accumulo/shell/ShellCompletor.java
deleted file mode 100644
index 3ed6a04..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/ShellCompletor.java
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.accumulo.shell;
-
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import jline.console.completer.Completer;
-
-import org.apache.accumulo.shell.Shell.Command.CompletionSet;
-import org.apache.accumulo.shell.commands.QuotedStringTokenizer;
-
-public class ShellCompletor implements Completer {
-
-  // private static final Logger log = Logger.getLogger(ShellCompletor.class);
-
-  Map<CompletionSet,Set<String>> options;
-  Token root = null;
-
-  public ShellCompletor() {}
-
-  public ShellCompletor(Token root) {
-    this.root = root;
-  }
-
-  public ShellCompletor(Token rootToken, Map<CompletionSet,Set<String>> options) {
-    this.root = rootToken;
-    this.options = options;
-  }
-
-  @Override
-  @SuppressWarnings({"unchecked", "rawtypes"})
-  public int complete(String buffer, int cursor, List candidates) {
-    try {
-      return _complete(buffer, cursor, candidates);
-    } catch (Exception e) {
-      candidates.add("");
-      candidates.add(e.getMessage());
-      return cursor;
-    }
-  }
-
-  private int _complete(String fullBuffer, int cursor, List<String> candidates) {
-    boolean inTableFlag = false, inUserFlag = false, inNamespaceFlag = false;
-    // Only want to grab the buffer up to the cursor because
-    // the user could be trying to tab complete in the middle
-    // of the line
-    String buffer = fullBuffer.substring(0, cursor);
-
-    Token current_command_token = root;
-    String current_string_token = null;
-    boolean end_space = buffer.endsWith(" ");
-
-    // tabbing with no text
-    if (buffer.length() == 0) {
-      candidates.addAll(root.getSubcommandNames());
-      return 0;
-    }
-
-    String prefix = "";
-
-    QuotedStringTokenizer qst = new QuotedStringTokenizer(buffer);
-
-    Iterator<String> iter = qst.iterator();
-    while (iter.hasNext()) {
-      current_string_token = iter.next();
-      current_string_token = current_string_token.replaceAll("([\\s'\"])", "\\\\$1");
-
-      if (!iter.hasNext()) {
-        // if we end in a space and that space isn't part of the last token
-        // (which would be the case at the start of a quote) OR the buffer
-        // ends with a " indicating that we need to start on the next command
-        // and not complete the current command.
-        if (end_space && !current_string_token.endsWith(" ") || buffer.endsWith("\"")) {
-          // match subcommands
-
-          // we're in a subcommand so try to match the universal
-          // option flags if we're there
-          if (current_string_token.trim().equals("-" + Shell.tableOption)) {
-            candidates.addAll(options.get(Shell.Command.CompletionSet.TABLENAMES));
-            prefix += "-" + Shell.tableOption + " ";
-          } else if (current_string_token.trim().equals("-" + Shell.userOption)) {
-            candidates.addAll(options.get(Shell.Command.CompletionSet.USERNAMES));
-            prefix += "-" + Shell.userOption + " ";
-          } else if (current_string_token.trim().equals("-" + Shell.namespaceOption)) {
-            candidates.addAll(options.get(Shell.Command.CompletionSet.NAMESPACES));
-            prefix += "-" + Shell.namespaceOption + " ";
-          } else if (current_command_token != null) {
-            Token next = current_command_token.getSubcommand(current_string_token);
-            if (next != null) {
-              current_command_token = next;
-
-              if (current_command_token.getCaseSensitive())
-                prefix += current_string_token + " ";
-              else
-                prefix += current_string_token.toUpperCase() + " ";
-
-              candidates.addAll(current_command_token.getSubcommandNames());
-            }
-          }
-          Collections.sort(candidates);
-          return (prefix.length());
-        }
-        // need to match current command
-        // if we're in -t <table>, -u <user>, or -tn <namespace> complete those
-        if (inTableFlag) {
-          for (String a : options.get(Shell.Command.CompletionSet.TABLENAMES))
-            if (a.startsWith(current_string_token))
-              candidates.add(a);
-        } else if (inUserFlag) {
-          for (String a : options.get(Shell.Command.CompletionSet.USERNAMES))
-            if (a.startsWith(current_string_token))
-              candidates.add(a);
-        } else if (inNamespaceFlag) {
-          for (String a : options.get(Shell.Command.CompletionSet.NAMESPACES))
-            if (a.startsWith(current_string_token))
-              candidates.add(a);
-        } else if (current_command_token != null)
-          candidates.addAll(current_command_token.getSubcommandNames(current_string_token));
-
-        Collections.sort(candidates);
-        return (prefix.length());
-      }
-
-      if (current_string_token.trim().equals("-" + Shell.tableOption))
-        inTableFlag = true;
-      else if (current_string_token.trim().equals("-" + Shell.userOption))
-        inUserFlag = true;
-      else if (current_string_token.trim().equals("-" + Shell.namespaceOption))
-        inNamespaceFlag = true;
-      else
-        inUserFlag = inTableFlag = inNamespaceFlag = false;
-
-      if (current_command_token != null && current_command_token.getCaseSensitive())
-        prefix += current_string_token + " ";
-      else
-        prefix += current_string_token.toUpperCase() + " ";
-
-      if (current_command_token != null && current_command_token.getSubcommandNames().contains(current_string_token))
-        current_command_token = current_command_token.getSubcommand(current_string_token);
-
-    }
-    return 0;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/ShellExtension.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/ShellExtension.java b/shell/src/main/java/org/apache/accumulo/shell/ShellExtension.java
deleted file mode 100644
index d29d276..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/ShellExtension.java
+++ /dev/null
@@ -1,27 +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.accumulo.shell;
-
-import org.apache.accumulo.shell.Shell.Command;
-
-public abstract class ShellExtension {
-    
-    public abstract String getExtensionName();
-
-    public abstract Command[] getCommands();
-    
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/ShellOptions.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/ShellOptions.java b/shell/src/main/java/org/apache/accumulo/shell/ShellOptions.java
deleted file mode 100644
index 302a8a9..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/ShellOptions.java
+++ /dev/null
@@ -1,33 +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.accumulo.shell;
-
-import org.apache.commons.cli.Option;
-
-/**
- * Abstract class to encompass the Options available on the Accumulo Shell
- */
-public abstract class ShellOptions {
-  // Global options flags
-  public static final String userOption = "u";
-  public static final String tableOption = "t";
-  public static final String namespaceOption = "ns";
-  public static final String helpOption = "?";
-  public static final String helpLongOption = "help";
-
-  final Option helpOpt = new Option(helpOption, helpLongOption, false, "display this help");
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/ShellOptionsJC.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/ShellOptionsJC.java b/shell/src/main/java/org/apache/accumulo/shell/ShellOptionsJC.java
deleted file mode 100644
index 35cef9f..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/ShellOptionsJC.java
+++ /dev/null
@@ -1,280 +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.accumulo.shell;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Scanner;
-import java.util.TreeMap;
-
-import org.apache.accumulo.core.client.ClientConfiguration;
-import org.apache.accumulo.core.client.ClientConfiguration.ClientProperty;
-import org.apache.accumulo.core.client.security.tokens.AuthenticationToken;
-import org.apache.commons.configuration.ConfigurationException;
-import org.apache.commons.configuration.PropertiesConfiguration;
-import org.apache.log4j.Logger;
-
-import com.beust.jcommander.DynamicParameter;
-import com.beust.jcommander.IStringConverter;
-import com.beust.jcommander.Parameter;
-import com.beust.jcommander.ParameterException;
-import com.beust.jcommander.converters.FileConverter;
-
-public class ShellOptionsJC {
-  // Use the Shell logger because this is really just an extension.
-  public static final Logger log = Logger.getLogger(Shell.class);
-
-  @Parameter(names = {"-u", "--user"}, description = "username (defaults to your OS user)")
-  private String username = System.getProperty("user.name", "root");
-
-  public static class PasswordConverter implements IStringConverter<String> {
-    public static final String STDIN = "stdin";
-
-    private enum KeyType {
-      PASS("pass:"), ENV("env:") {
-        @Override
-        String process(String value) {
-          return System.getenv(value);
-        }
-      },
-      FILE("file:") {
-        @Override
-        String process(String value) {
-          Scanner scanner = null;
-          try {
-            scanner = new Scanner(new File(value));
-            return scanner.nextLine();
-          } catch (FileNotFoundException e) {
-            throw new ParameterException(e);
-          } finally {
-            if (scanner != null) {
-              scanner.close();
-            }
-          }
-        }
-      },
-      STDIN(PasswordConverter.STDIN) {
-        @Override
-        public boolean matches(String value) {
-          return prefix.equals(value);
-        }
-
-        @Override
-        public String convert(String value) {
-          // Will check for this later
-          return prefix;
-        }
-      };
-
-      String prefix;
-
-      private KeyType(String prefix) {
-        this.prefix = prefix;
-      }
-
-      public boolean matches(String value) {
-        return value.startsWith(prefix);
-      }
-
-      public String convert(String value) {
-        return process(value.substring(prefix.length()));
-      }
-
-      String process(String value) {
-        return value;
-      }
-    };
-
-    @Override
-    public String convert(String value) {
-      for (KeyType keyType : KeyType.values()) {
-        if (keyType.matches(value)) {
-          return keyType.convert(value);
-        }
-      }
-
-      return value;
-    }
-  }
-
-  // Note: Don't use "password = true" because then it will prompt even if we have a token
-  @Parameter(names = {"-p", "--password"}, description = "password (can be specified as 'pass:<password>', 'file:<local file containing the password>', "
-      + "'env:<variable containing the pass>', or stdin)", converter = PasswordConverter.class)
-  private String password;
-
-  public static class TokenConverter implements IStringConverter<AuthenticationToken> {
-    @Override
-    public AuthenticationToken convert(String value) {
-      try {
-        return Class.forName(value).asSubclass(AuthenticationToken.class).newInstance();
-      } catch (Exception e) {
-        // Catching ClassNotFoundException, ClassCastException, InstantiationException and IllegalAccessException
-        throw new ParameterException(e);
-      }
-    }
-  }
-
-  @Parameter(names = {"-tc", "--tokenClass"}, description = "token type to create, use the -l to pass options", converter = TokenConverter.class)
-  private AuthenticationToken authenticationToken;
-
-  @DynamicParameter(names = {"-l", "--tokenProperty"}, description = "login properties in the format key=value. Reuse -l for each property")
-  private Map<String,String> tokenProperties = new TreeMap<String,String>();
-
-  @Parameter(names = "--disable-tab-completion", description = "disables tab completion (for less overhead when scripting)")
-  private boolean tabCompletionDisabled;
-
-  @Parameter(names = "--debug", description = "enables client debugging")
-  private boolean debugEnabled;
-
-  @Parameter(names = "--fake", description = "fake a connection to accumulo")
-  private boolean fake;
-
-  @Parameter(names = {"-?", "--help"}, help = true, description = "display this help")
-  private boolean helpEnabled;
-
-  @Parameter(names = {"-e", "--execute-command"}, description = "executes a command, and then exits")
-  private String execCommand;
-
-  @Parameter(names = {"-f", "--execute-file"}, description = "executes commands from a file at startup", converter = FileConverter.class)
-  private File execFile;
-
-  @Parameter(names = {"-fv", "--execute-file-verbose"}, description = "executes commands from a file at startup, with commands shown",
-      converter = FileConverter.class)
-  private File execFileVerbose;
-
-  @Parameter(names = {"-h", "--hdfsZooInstance"}, description = "use hdfs zoo instance")
-  private boolean hdfsZooInstance;
-
-  @Parameter(names = {"-z", "--zooKeeperInstance"}, description = "use a zookeeper instance with the given instance name and list of zoo hosts", arity = 2)
-  private List<String> zooKeeperInstance = new ArrayList<String>();
-
-  @Parameter(names = {"--ssl"}, description = "use ssl to connect to accumulo")
-  private boolean useSsl = false;
-
-  @Parameter(
-      names = "--config-file",
-      description = "read the given client config file.  If omitted, the path searched can be specified with $ACCUMULO_CLIENT_CONF_PATH, which defaults to ~/.accumulo/config:$ACCUMULO_CONF_DIR/client.conf:/etc/accumulo/client.conf")
-  private String clientConfigFile = null;
-
-  @Parameter(names = {"-zi", "--zooKeeperInstanceName"}, description = "use a zookeeper instance with the given instance name")
-  private String zooKeeperInstanceName;
-
-  @Parameter(names = {"-zh", "--zooKeeperHosts"}, description = "use a zookeeper instance with the given list of zoo hosts")
-  private String zooKeeperHosts;
-
-  @Parameter(names = "--auth-timeout", description = "minutes the shell can be idle without re-entering a password")
-  private int authTimeout = 60; // TODO Add validator for positive number
-
-  @Parameter(names = "--disable-auth-timeout", description = "disables requiring the user to re-type a password after being idle")
-  private boolean authTimeoutDisabled;
-
-  @Parameter(hidden = true)
-  private List<String> unrecognizedOptions;
-
-  public String getUsername() {
-    return username;
-  }
-
-  public String getPassword() {
-    return password;
-  }
-
-  public AuthenticationToken getAuthenticationToken() {
-    return authenticationToken;
-  }
-
-  public Map<String,String> getTokenProperties() {
-    return tokenProperties;
-  }
-
-  public boolean isTabCompletionDisabled() {
-    return tabCompletionDisabled;
-  }
-
-  public boolean isDebugEnabled() {
-    return debugEnabled;
-  }
-
-  public boolean isFake() {
-    return fake;
-  }
-
-  public boolean isHelpEnabled() {
-    return helpEnabled;
-  }
-
-  public String getExecCommand() {
-    return execCommand;
-  }
-
-  public File getExecFile() {
-    return execFile;
-  }
-
-  public File getExecFileVerbose() {
-    return execFileVerbose;
-  }
-
-  public boolean isHdfsZooInstance() {
-    return hdfsZooInstance;
-  }
-
-  public List<String> getZooKeeperInstance() {
-    return zooKeeperInstance;
-  }
-
-  public String getZooKeeperInstanceName() {
-    return zooKeeperInstanceName;
-  }
-
-  public String getZooKeeperHosts() {
-    return zooKeeperHosts;
-  }
-
-  public int getAuthTimeout() {
-    return authTimeout;
-  }
-
-  public boolean isAuthTimeoutDisabled() {
-    return authTimeoutDisabled;
-  }
-
-  public List<String> getUnrecognizedOptions() {
-    return unrecognizedOptions;
-  }
-
-  public boolean useSsl() {
-    return useSsl;
-  }
-
-  public String getClientConfigFile() {
-    return clientConfigFile;
-  }
-
-  public ClientConfiguration getClientConfiguration() throws ConfigurationException, FileNotFoundException {
-    ClientConfiguration clientConfig = clientConfigFile == null ? ClientConfiguration.loadDefault() : new ClientConfiguration(new PropertiesConfiguration(
-        getClientConfigFile()));
-    if (useSsl()) {
-      clientConfig.setProperty(ClientProperty.INSTANCE_RPC_SSL_ENABLED, "true");
-    }
-    return clientConfig;
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/ShellUtil.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/ShellUtil.java b/shell/src/main/java/org/apache/accumulo/shell/ShellUtil.java
deleted file mode 100644
index c0f7a9a..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/ShellUtil.java
+++ /dev/null
@@ -1,60 +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.accumulo.shell;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.nio.charset.StandardCharsets;
-import java.util.List;
-import java.util.Scanner;
-
-import org.apache.commons.codec.binary.Base64;
-import org.apache.hadoop.io.Text;
-
-import com.google.common.collect.Lists;
-
-public class ShellUtil {
-
-  /**
-   * Scans the given file line-by-line (ignoring empty lines) and returns a list containing those lines. If decode is set to true, every line is decoded using
-   * {@link Base64#decodeBase64(byte[])} from the UTF-8 bytes of that line before inserting in the list.
-   * 
-   * @param filename
-   *          Path to the file that needs to be scanned
-   * @param decode
-   *          Whether to decode lines in the file
-   * @return List of {@link Text} objects containing data in the given file
-   * @throws FileNotFoundException
-   *           if the given file doesn't exist
-   */
-  public static List<Text> scanFile(String filename, boolean decode) throws FileNotFoundException {
-    String line;
-    Scanner file = new Scanner(new File(filename), StandardCharsets.UTF_8.name());
-    List<Text> result = Lists.newArrayList();
-    try {
-      while (file.hasNextLine()) {
-        line = file.nextLine();
-        if (!line.isEmpty()) {
-          result.add(decode ? new Text(Base64.decodeBase64(line.getBytes(StandardCharsets.UTF_8))) : new Text(line));
-        }
-      }
-    } finally {
-      file.close();
-    }
-    return result;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/Token.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/Token.java b/shell/src/main/java/org/apache/accumulo/shell/Token.java
deleted file mode 100644
index 5083457..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/Token.java
+++ /dev/null
@@ -1,137 +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.accumulo.shell;
-
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Set;
-
-/*
- * A token is a word in a command in the shell.  The tree that this builds is used for
- * tab-completion of tables, users, commands and certain other parts of the shell that
- * can be realistically and quickly gathered. Tokens can have multiple commands grouped 
- * together and many possible subcommands, although they are stored in a set so duplicates
- * aren't allowed.
- */
-
-public class Token {
-  private Set<String> command = new HashSet<String>();
-  private Set<Token> subcommands = new HashSet<Token>();
-  private boolean caseSensitive = false;
-  
-  public Token() {}
-  
-  public Token(String commandName) {
-    this();
-    command.add(commandName);
-  }
-  
-  public Token(Collection<String> commandNames) {
-    this();
-    command.addAll(commandNames);
-  }
-  
-  public Token(Set<String> commandNames, Set<Token> subCommandNames) {
-    this();
-    command.addAll(commandNames);
-    subcommands.addAll(subCommandNames);
-  }
-  
-  public void setCaseSensitive(boolean cs) {
-    caseSensitive = cs;
-  }
-  
-  public boolean getCaseSensitive() {
-    return caseSensitive;
-  }
-  
-  public Set<String> getCommandNames() {
-    return command;
-  }
-  
-  public Set<Token> getSubcommandList() {
-    return subcommands;
-  }
-  
-  public Token getSubcommand(String name) {
-    Iterator<Token> iter = subcommands.iterator();
-    while (iter.hasNext()) {
-      Token t = iter.next();
-      if (t.containsCommand(name))
-        return t;
-    }
-    return null;
-  }
-  
-  public Set<String> getSubcommandNames() {
-    HashSet<String> set = new HashSet<String>();
-    for (Token t : subcommands)
-      set.addAll(t.getCommandNames());
-    return set;
-  }
-  
-  public Set<String> getSubcommandNames(String startsWith) {
-    Iterator<Token> iter = subcommands.iterator();
-    HashSet<String> set = new HashSet<String>();
-    while (iter.hasNext()) {
-      Token t = iter.next();
-      Set<String> subset = t.getCommandNames();
-      for (String s : subset) {
-        if (!t.getCaseSensitive()) {
-          if (s.toLowerCase().startsWith(startsWith.toLowerCase())) {
-            set.add(s);
-          }
-        } else {
-          if (s.startsWith(startsWith)) {
-            set.add(s);
-          }
-        }
-      }
-    }
-    return set;
-  }
-  
-  public boolean containsCommand(String match) {
-    Iterator<String> iter = command.iterator();
-    while (iter.hasNext()) {
-      String t = iter.next();
-      if (caseSensitive) {
-        if (t.equals(match))
-          return true;
-      } else {
-        if (t.equalsIgnoreCase(match))
-          return true;
-      }
-    }
-    return false;
-  }
-  
-  public void addSubcommand(Token t) {
-    subcommands.add(t);
-  }
-  
-  public void addSubcommand(Collection<String> t) {
-    for (String a : t) {
-      addSubcommand(new Token(a));
-    }
-  }
-  
-  public String toString() {
-    return this.command.toString();
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/AboutCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/AboutCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/AboutCommand.java
deleted file mode 100644
index 9ba8460..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/AboutCommand.java
+++ /dev/null
@@ -1,56 +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.accumulo.shell.commands;
-
-import java.io.IOException;
-
-import org.apache.accumulo.shell.Shell;
-import org.apache.accumulo.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-
-public class AboutCommand extends Command {
-  private Option verboseOption;
-  
-  @Override
-  public String description() {
-    return "displays information about this program";
-  }
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws IOException {
-    shellState.printInfo();
-    if (cl.hasOption(verboseOption.getOpt())) {
-      shellState.printVerboseInfo();
-    }
-    return 0;
-  }
-  
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options opts = new Options();
-    verboseOption = new Option("v", "verbose", false, "display detailed session information");
-    opts.addOption(verboseOption);
-    return opts;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/ActiveCompactionIterator.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/ActiveCompactionIterator.java b/shell/src/main/java/org/apache/accumulo/shell/commands/ActiveCompactionIterator.java
deleted file mode 100644
index 159a2a6..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/ActiveCompactionIterator.java
+++ /dev/null
@@ -1,136 +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.accumulo.shell.commands;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.accumulo.core.client.IteratorSetting;
-import org.apache.accumulo.core.client.admin.ActiveCompaction;
-import org.apache.accumulo.core.client.admin.InstanceOperations;
-import org.apache.accumulo.core.util.Duration;
-
-class ActiveCompactionIterator implements Iterator<String> {
-  
-  private InstanceOperations instanceOps;
-  private Iterator<String> tsIter;
-  private Iterator<String> compactionIter;
-  
-  private static String maxDecimal(double count) {
-    if (count < 9.995)
-      return String.format("%.2f", count);
-    if (count < 99.95)
-      return String.format("%.1f", count);
-    return String.format("%.0f", count);
-  }
-
-  private static String shortenCount(long count) {
-    if (count < 1000)
-      return count + "";
-    if (count < 1000000)
-      return maxDecimal(count / 1000.0) + "K";
-    if (count < 1000000000)
-      return maxDecimal(count / 1000000.0) + "M";
-    return maxDecimal(count / 1000000000.0) + "B";
-  }
-
-  private void readNext() {
-    final List<String> compactions = new ArrayList<String>();
-    
-    while (tsIter.hasNext()) {
-      
-      final String tserver = tsIter.next();
-      try {
-        List<ActiveCompaction> acl = instanceOps.getActiveCompactions(tserver);
-        
-        acl = new ArrayList<ActiveCompaction>(acl);
-        
-        Collections.sort(acl, new Comparator<ActiveCompaction>() {
-          @Override
-          public int compare(ActiveCompaction o1, ActiveCompaction o2) {
-            return (int) (o2.getAge() - o1.getAge());
-          }
-        });
-
-        for (ActiveCompaction ac : acl) {
-          String output = ac.getOutputFile();
-          int index = output.indexOf("tables");
-          if (index > 0) {
-            output = output.substring(index + 6);
-          }
-          
-          ac.getIterators();
-          
-          List<String> iterList = new ArrayList<String>();
-          Map<String,Map<String,String>> iterOpts = new HashMap<String,Map<String,String>>();
-          for (IteratorSetting is : ac.getIterators()) {
-            iterList.add(is.getName() + "=" + is.getPriority() + "," + is.getIteratorClass());
-            iterOpts.put(is.getName(), is.getOptions());
-          }
-
-          compactions.add(String.format("%21s | %9s | %5s | %6s | %5s | %5s | %15s | %-40s | %5s | %35s | %9s | %s", tserver,
-              Duration.format(ac.getAge(), "", "-"), ac.getType(), ac.getReason(), shortenCount(ac.getEntriesRead()), shortenCount(ac.getEntriesWritten()),
-              ac.getTable(), ac.getExtent(), ac.getInputFiles().size(), output, iterList, iterOpts));
-        }
-      } catch (Exception e) {
-        compactions.add(tserver + " ERROR " + e.getMessage());
-      }
-      
-      if (compactions.size() > 0) {
-        break;
-      }
-    }
-    
-    compactionIter = compactions.iterator();
-  }
-  
-  ActiveCompactionIterator(List<String> tservers, InstanceOperations instanceOps) {
-    this.instanceOps = instanceOps;
-    this.tsIter = tservers.iterator();
-    
-    final String header = String.format(" %-21s| %-9s | %-5s | %-6s | %-5s | %-5s | %-15s | %-40s | %-5s | %-35s | %-9s | %s", "TABLET SERVER", "AGE", "TYPE",
-        "REASON", "READ", "WROTE", "TABLE", "TABLET", "INPUT", "OUTPUT", "ITERATORS", "ITERATOR OPTIONS");
-    
-    compactionIter = Collections.singletonList(header).iterator();
-  }
-  
-  @Override
-  public boolean hasNext() {
-    return compactionIter.hasNext();
-  }
-  
-  @Override
-  public String next() {
-    final String next = compactionIter.next();
-    
-    if (!compactionIter.hasNext())
-      readNext();
-    
-    return next;
-  }
-  
-  @Override
-  public void remove() {
-    throw new UnsupportedOperationException();
-  }
-  
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/ActiveScanIterator.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/ActiveScanIterator.java b/shell/src/main/java/org/apache/accumulo/shell/commands/ActiveScanIterator.java
deleted file mode 100644
index 0412317..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/ActiveScanIterator.java
+++ /dev/null
@@ -1,91 +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.accumulo.shell.commands;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-
-import org.apache.accumulo.core.client.admin.ActiveScan;
-import org.apache.accumulo.core.client.admin.InstanceOperations;
-import org.apache.accumulo.core.client.admin.ScanType;
-import org.apache.accumulo.core.util.Duration;
-
-class ActiveScanIterator implements Iterator<String> {
-  
-  private InstanceOperations instanceOps;
-  private Iterator<String> tsIter;
-  private Iterator<String> scansIter;
-  
-  private void readNext() {
-    final List<String> scans = new ArrayList<String>();
-    
-    while (tsIter.hasNext()) {
-      
-      final String tserver = tsIter.next();
-      try {
-        final List<ActiveScan> asl = instanceOps.getActiveScans(tserver);
-        
-        for (ActiveScan as : asl) {
-          scans.add(String.format("%21s |%21s |%9s |%9s |%7s |%6s |%8s |%8s |%10s |%20s |%10s |%10s | %s", tserver, as.getClient(),
-              Duration.format(as.getAge(), "", "-"), Duration.format(as.getLastContactTime(), "", "-"), as.getState(), as.getType(), as.getUser(),
-              as.getTable(), as.getColumns(), as.getAuthorizations(), (as.getType() == ScanType.SINGLE ? as.getExtent() : "N/A"), as.getSsiList(), as.getSsio()));
-        }
-      } catch (Exception e) {
-        scans.add(tserver + " ERROR " + e.getMessage());
-      }
-      
-      if (scans.size() > 0) {
-        break;
-      }
-    }
-    
-    scansIter = scans.iterator();
-  }
-  
-  ActiveScanIterator(List<String> tservers, InstanceOperations instanceOps) {
-    this.instanceOps = instanceOps;
-    this.tsIter = tservers.iterator();
-    
-    final String header = String.format(" %-21s| %-21s| %-9s| %-9s| %-7s| %-6s| %-8s| %-8s| %-10s| %-20s| %-10s| %-10s | %s", "TABLET SERVER", "CLIENT", "AGE",
-        "LAST", "STATE", "TYPE", "USER", "TABLE", "COLUMNS", "AUTHORIZATIONS", "TABLET", "ITERATORS", "ITERATOR OPTIONS");
-    
-    scansIter = Collections.singletonList(header).iterator();
-  }
-  
-  @Override
-  public boolean hasNext() {
-    return scansIter.hasNext();
-  }
-  
-  @Override
-  public String next() {
-    final String next = scansIter.next();
-    
-    if (!scansIter.hasNext())
-      readNext();
-    
-    return next;
-  }
-  
-  @Override
-  public void remove() {
-    throw new UnsupportedOperationException();
-  }
-  
-}


[50/53] [abbrv] ACCUMULO-2573 First stab at changes to IDL for replication

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/accumulo/blob/d257001d/core/src/main/java/org/apache/accumulo/core/replication/thrift/RemoteReplicationException.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/replication/thrift/RemoteReplicationException.java b/core/src/main/java/org/apache/accumulo/core/replication/thrift/RemoteReplicationException.java
new file mode 100644
index 0000000..f93bbba
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/replication/thrift/RemoteReplicationException.java
@@ -0,0 +1,500 @@
+/*
+ * 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.
+ */
+/**
+ * Autogenerated by Thrift Compiler (0.9.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ *  @generated
+ */
+package org.apache.accumulo.core.replication.thrift;
+
+import org.apache.thrift.scheme.IScheme;
+import org.apache.thrift.scheme.SchemeFactory;
+import org.apache.thrift.scheme.StandardScheme;
+
+import org.apache.thrift.scheme.TupleScheme;
+import org.apache.thrift.protocol.TTupleProtocol;
+import org.apache.thrift.protocol.TProtocolException;
+import org.apache.thrift.EncodingUtils;
+import org.apache.thrift.TException;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.EnumMap;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.EnumSet;
+import java.util.Collections;
+import java.util.BitSet;
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@SuppressWarnings("all") public class RemoteReplicationException extends TException implements org.apache.thrift.TBase<RemoteReplicationException, RemoteReplicationException._Fields>, java.io.Serializable, Cloneable {
+  private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("RemoteReplicationException");
+
+  private static final org.apache.thrift.protocol.TField CODE_FIELD_DESC = new org.apache.thrift.protocol.TField("code", org.apache.thrift.protocol.TType.I32, (short)1);
+  private static final org.apache.thrift.protocol.TField REASON_FIELD_DESC = new org.apache.thrift.protocol.TField("reason", org.apache.thrift.protocol.TType.STRING, (short)2);
+
+  private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
+  static {
+    schemes.put(StandardScheme.class, new RemoteReplicationExceptionStandardSchemeFactory());
+    schemes.put(TupleScheme.class, new RemoteReplicationExceptionTupleSchemeFactory());
+  }
+
+  public int code; // required
+  public String reason; // required
+
+  /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+  @SuppressWarnings("all") public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+    CODE((short)1, "code"),
+    REASON((short)2, "reason");
+
+    private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+
+    static {
+      for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        byName.put(field.getFieldName(), field);
+      }
+    }
+
+    /**
+     * Find the _Fields constant that matches fieldId, or null if its not found.
+     */
+    public static _Fields findByThriftId(int fieldId) {
+      switch(fieldId) {
+        case 1: // CODE
+          return CODE;
+        case 2: // REASON
+          return REASON;
+        default:
+          return null;
+      }
+    }
+
+    /**
+     * Find the _Fields constant that matches fieldId, throwing an exception
+     * if it is not found.
+     */
+    public static _Fields findByThriftIdOrThrow(int fieldId) {
+      _Fields fields = findByThriftId(fieldId);
+      if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+      return fields;
+    }
+
+    /**
+     * Find the _Fields constant that matches name, or null if its not found.
+     */
+    public static _Fields findByName(String name) {
+      return byName.get(name);
+    }
+
+    private final short _thriftId;
+    private final String _fieldName;
+
+    _Fields(short thriftId, String fieldName) {
+      _thriftId = thriftId;
+      _fieldName = fieldName;
+    }
+
+    public short getThriftFieldId() {
+      return _thriftId;
+    }
+
+    public String getFieldName() {
+      return _fieldName;
+    }
+  }
+
+  // isset id assignments
+  private static final int __CODE_ISSET_ID = 0;
+  private byte __isset_bitfield = 0;
+  public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+  static {
+    Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+    tmpMap.put(_Fields.CODE, new org.apache.thrift.meta_data.FieldMetaData("code", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
+    tmpMap.put(_Fields.REASON, new org.apache.thrift.meta_data.FieldMetaData("reason", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
+    metaDataMap = Collections.unmodifiableMap(tmpMap);
+    org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(RemoteReplicationException.class, metaDataMap);
+  }
+
+  public RemoteReplicationException() {
+  }
+
+  public RemoteReplicationException(
+    int code,
+    String reason)
+  {
+    this();
+    this.code = code;
+    setCodeIsSet(true);
+    this.reason = reason;
+  }
+
+  /**
+   * Performs a deep copy on <i>other</i>.
+   */
+  public RemoteReplicationException(RemoteReplicationException other) {
+    __isset_bitfield = other.__isset_bitfield;
+    this.code = other.code;
+    if (other.isSetReason()) {
+      this.reason = other.reason;
+    }
+  }
+
+  public RemoteReplicationException deepCopy() {
+    return new RemoteReplicationException(this);
+  }
+
+  @Override
+  public void clear() {
+    setCodeIsSet(false);
+    this.code = 0;
+    this.reason = null;
+  }
+
+  public int getCode() {
+    return this.code;
+  }
+
+  public RemoteReplicationException setCode(int code) {
+    this.code = code;
+    setCodeIsSet(true);
+    return this;
+  }
+
+  public void unsetCode() {
+    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __CODE_ISSET_ID);
+  }
+
+  /** Returns true if field code is set (has been assigned a value) and false otherwise */
+  public boolean isSetCode() {
+    return EncodingUtils.testBit(__isset_bitfield, __CODE_ISSET_ID);
+  }
+
+  public void setCodeIsSet(boolean value) {
+    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __CODE_ISSET_ID, value);
+  }
+
+  public String getReason() {
+    return this.reason;
+  }
+
+  public RemoteReplicationException setReason(String reason) {
+    this.reason = reason;
+    return this;
+  }
+
+  public void unsetReason() {
+    this.reason = null;
+  }
+
+  /** Returns true if field reason is set (has been assigned a value) and false otherwise */
+  public boolean isSetReason() {
+    return this.reason != null;
+  }
+
+  public void setReasonIsSet(boolean value) {
+    if (!value) {
+      this.reason = null;
+    }
+  }
+
+  public void setFieldValue(_Fields field, Object value) {
+    switch (field) {
+    case CODE:
+      if (value == null) {
+        unsetCode();
+      } else {
+        setCode((Integer)value);
+      }
+      break;
+
+    case REASON:
+      if (value == null) {
+        unsetReason();
+      } else {
+        setReason((String)value);
+      }
+      break;
+
+    }
+  }
+
+  public Object getFieldValue(_Fields field) {
+    switch (field) {
+    case CODE:
+      return Integer.valueOf(getCode());
+
+    case REASON:
+      return getReason();
+
+    }
+    throw new IllegalStateException();
+  }
+
+  /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+  public boolean isSet(_Fields field) {
+    if (field == null) {
+      throw new IllegalArgumentException();
+    }
+
+    switch (field) {
+    case CODE:
+      return isSetCode();
+    case REASON:
+      return isSetReason();
+    }
+    throw new IllegalStateException();
+  }
+
+  @Override
+  public boolean equals(Object that) {
+    if (that == null)
+      return false;
+    if (that instanceof RemoteReplicationException)
+      return this.equals((RemoteReplicationException)that);
+    return false;
+  }
+
+  public boolean equals(RemoteReplicationException that) {
+    if (that == null)
+      return false;
+
+    boolean this_present_code = true;
+    boolean that_present_code = true;
+    if (this_present_code || that_present_code) {
+      if (!(this_present_code && that_present_code))
+        return false;
+      if (this.code != that.code)
+        return false;
+    }
+
+    boolean this_present_reason = true && this.isSetReason();
+    boolean that_present_reason = true && that.isSetReason();
+    if (this_present_reason || that_present_reason) {
+      if (!(this_present_reason && that_present_reason))
+        return false;
+      if (!this.reason.equals(that.reason))
+        return false;
+    }
+
+    return true;
+  }
+
+  @Override
+  public int hashCode() {
+    return 0;
+  }
+
+  public int compareTo(RemoteReplicationException other) {
+    if (!getClass().equals(other.getClass())) {
+      return getClass().getName().compareTo(other.getClass().getName());
+    }
+
+    int lastComparison = 0;
+    RemoteReplicationException typedOther = (RemoteReplicationException)other;
+
+    lastComparison = Boolean.valueOf(isSetCode()).compareTo(typedOther.isSetCode());
+    if (lastComparison != 0) {
+      return lastComparison;
+    }
+    if (isSetCode()) {
+      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.code, typedOther.code);
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+    }
+    lastComparison = Boolean.valueOf(isSetReason()).compareTo(typedOther.isSetReason());
+    if (lastComparison != 0) {
+      return lastComparison;
+    }
+    if (isSetReason()) {
+      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.reason, typedOther.reason);
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+    }
+    return 0;
+  }
+
+  public _Fields fieldForId(int fieldId) {
+    return _Fields.findByThriftId(fieldId);
+  }
+
+  public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+    schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+  }
+
+  public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+    schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
+  }
+
+  @Override
+  public String toString() {
+    StringBuilder sb = new StringBuilder("RemoteReplicationException(");
+    boolean first = true;
+
+    sb.append("code:");
+    sb.append(this.code);
+    first = false;
+    if (!first) sb.append(", ");
+    sb.append("reason:");
+    if (this.reason == null) {
+      sb.append("null");
+    } else {
+      sb.append(this.reason);
+    }
+    first = false;
+    sb.append(")");
+    return sb.toString();
+  }
+
+  public void validate() throws org.apache.thrift.TException {
+    // check for required fields
+    // check for sub-struct validity
+  }
+
+  private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+    try {
+      write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+    } catch (org.apache.thrift.TException te) {
+      throw new java.io.IOException(te);
+    }
+  }
+
+  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    try {
+      // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor.
+      __isset_bitfield = 0;
+      read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+    } catch (org.apache.thrift.TException te) {
+      throw new java.io.IOException(te);
+    }
+  }
+
+  private static class RemoteReplicationExceptionStandardSchemeFactory implements SchemeFactory {
+    public RemoteReplicationExceptionStandardScheme getScheme() {
+      return new RemoteReplicationExceptionStandardScheme();
+    }
+  }
+
+  private static class RemoteReplicationExceptionStandardScheme extends StandardScheme<RemoteReplicationException> {
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot, RemoteReplicationException struct) throws org.apache.thrift.TException {
+      org.apache.thrift.protocol.TField schemeField;
+      iprot.readStructBegin();
+      while (true)
+      {
+        schemeField = iprot.readFieldBegin();
+        if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+          break;
+        }
+        switch (schemeField.id) {
+          case 1: // CODE
+            if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
+              struct.code = iprot.readI32();
+              struct.setCodeIsSet(true);
+            } else { 
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+            }
+            break;
+          case 2: // REASON
+            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+              struct.reason = iprot.readString();
+              struct.setReasonIsSet(true);
+            } else { 
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+            }
+            break;
+          default:
+            org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+        }
+        iprot.readFieldEnd();
+      }
+      iprot.readStructEnd();
+
+      // check for required fields of primitive type, which can't be checked in the validate method
+      struct.validate();
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot, RemoteReplicationException struct) throws org.apache.thrift.TException {
+      struct.validate();
+
+      oprot.writeStructBegin(STRUCT_DESC);
+      oprot.writeFieldBegin(CODE_FIELD_DESC);
+      oprot.writeI32(struct.code);
+      oprot.writeFieldEnd();
+      if (struct.reason != null) {
+        oprot.writeFieldBegin(REASON_FIELD_DESC);
+        oprot.writeString(struct.reason);
+        oprot.writeFieldEnd();
+      }
+      oprot.writeFieldStop();
+      oprot.writeStructEnd();
+    }
+
+  }
+
+  private static class RemoteReplicationExceptionTupleSchemeFactory implements SchemeFactory {
+    public RemoteReplicationExceptionTupleScheme getScheme() {
+      return new RemoteReplicationExceptionTupleScheme();
+    }
+  }
+
+  private static class RemoteReplicationExceptionTupleScheme extends TupleScheme<RemoteReplicationException> {
+
+    @Override
+    public void write(org.apache.thrift.protocol.TProtocol prot, RemoteReplicationException struct) throws org.apache.thrift.TException {
+      TTupleProtocol oprot = (TTupleProtocol) prot;
+      BitSet optionals = new BitSet();
+      if (struct.isSetCode()) {
+        optionals.set(0);
+      }
+      if (struct.isSetReason()) {
+        optionals.set(1);
+      }
+      oprot.writeBitSet(optionals, 2);
+      if (struct.isSetCode()) {
+        oprot.writeI32(struct.code);
+      }
+      if (struct.isSetReason()) {
+        oprot.writeString(struct.reason);
+      }
+    }
+
+    @Override
+    public void read(org.apache.thrift.protocol.TProtocol prot, RemoteReplicationException struct) throws org.apache.thrift.TException {
+      TTupleProtocol iprot = (TTupleProtocol) prot;
+      BitSet incoming = iprot.readBitSet(2);
+      if (incoming.get(0)) {
+        struct.code = iprot.readI32();
+        struct.setCodeIsSet(true);
+      }
+      if (incoming.get(1)) {
+        struct.reason = iprot.readString();
+        struct.setReasonIsSet(true);
+      }
+    }
+  }
+
+}
+

http://git-wip-us.apache.org/repos/asf/accumulo/blob/d257001d/core/src/main/java/org/apache/accumulo/core/replication/thrift/Replication.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/replication/thrift/Replication.java b/core/src/main/java/org/apache/accumulo/core/replication/thrift/Replication.java
new file mode 100644
index 0000000..2390d3c
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/replication/thrift/Replication.java
@@ -0,0 +1,1917 @@
+/*
+ * 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.
+ */
+/**
+ * Autogenerated by Thrift Compiler (0.9.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ *  @generated
+ */
+package org.apache.accumulo.core.replication.thrift;
+
+import org.apache.thrift.scheme.IScheme;
+import org.apache.thrift.scheme.SchemeFactory;
+import org.apache.thrift.scheme.StandardScheme;
+
+import org.apache.thrift.scheme.TupleScheme;
+import org.apache.thrift.protocol.TTupleProtocol;
+import org.apache.thrift.protocol.TProtocolException;
+import org.apache.thrift.EncodingUtils;
+import org.apache.thrift.TException;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.EnumMap;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.EnumSet;
+import java.util.Collections;
+import java.util.BitSet;
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@SuppressWarnings("all") public class Replication {
+
+  public interface Iface {
+
+    public void replicateLog(int remoteTableId, WalEdits data) throws RemoteReplicationException, org.apache.thrift.TException;
+
+    public void replicateKeyValues(int remoteTableId, KeyValues data) throws RemoteReplicationException, org.apache.thrift.TException;
+
+  }
+
+  public interface AsyncIface {
+
+    public void replicateLog(int remoteTableId, WalEdits data, org.apache.thrift.async.AsyncMethodCallback<AsyncClient.replicateLog_call> resultHandler) throws org.apache.thrift.TException;
+
+    public void replicateKeyValues(int remoteTableId, KeyValues data, org.apache.thrift.async.AsyncMethodCallback<AsyncClient.replicateKeyValues_call> resultHandler) throws org.apache.thrift.TException;
+
+  }
+
+  public static class Client extends org.apache.thrift.TServiceClient implements Iface {
+    public static class Factory implements org.apache.thrift.TServiceClientFactory<Client> {
+      public Factory() {}
+      public Client getClient(org.apache.thrift.protocol.TProtocol prot) {
+        return new Client(prot);
+      }
+      public Client getClient(org.apache.thrift.protocol.TProtocol iprot, org.apache.thrift.protocol.TProtocol oprot) {
+        return new Client(iprot, oprot);
+      }
+    }
+
+    public Client(org.apache.thrift.protocol.TProtocol prot)
+    {
+      super(prot, prot);
+    }
+
+    public Client(org.apache.thrift.protocol.TProtocol iprot, org.apache.thrift.protocol.TProtocol oprot) {
+      super(iprot, oprot);
+    }
+
+    public void replicateLog(int remoteTableId, WalEdits data) throws RemoteReplicationException, org.apache.thrift.TException
+    {
+      send_replicateLog(remoteTableId, data);
+      recv_replicateLog();
+    }
+
+    public void send_replicateLog(int remoteTableId, WalEdits data) throws org.apache.thrift.TException
+    {
+      replicateLog_args args = new replicateLog_args();
+      args.setRemoteTableId(remoteTableId);
+      args.setData(data);
+      sendBase("replicateLog", args);
+    }
+
+    public void recv_replicateLog() throws RemoteReplicationException, org.apache.thrift.TException
+    {
+      replicateLog_result result = new replicateLog_result();
+      receiveBase(result, "replicateLog");
+      if (result.e != null) {
+        throw result.e;
+      }
+      return;
+    }
+
+    public void replicateKeyValues(int remoteTableId, KeyValues data) throws RemoteReplicationException, org.apache.thrift.TException
+    {
+      send_replicateKeyValues(remoteTableId, data);
+      recv_replicateKeyValues();
+    }
+
+    public void send_replicateKeyValues(int remoteTableId, KeyValues data) throws org.apache.thrift.TException
+    {
+      replicateKeyValues_args args = new replicateKeyValues_args();
+      args.setRemoteTableId(remoteTableId);
+      args.setData(data);
+      sendBase("replicateKeyValues", args);
+    }
+
+    public void recv_replicateKeyValues() throws RemoteReplicationException, org.apache.thrift.TException
+    {
+      replicateKeyValues_result result = new replicateKeyValues_result();
+      receiveBase(result, "replicateKeyValues");
+      if (result.e != null) {
+        throw result.e;
+      }
+      return;
+    }
+
+  }
+  public static class AsyncClient extends org.apache.thrift.async.TAsyncClient implements AsyncIface {
+    public static class Factory implements org.apache.thrift.async.TAsyncClientFactory<AsyncClient> {
+      private org.apache.thrift.async.TAsyncClientManager clientManager;
+      private org.apache.thrift.protocol.TProtocolFactory protocolFactory;
+      public Factory(org.apache.thrift.async.TAsyncClientManager clientManager, org.apache.thrift.protocol.TProtocolFactory protocolFactory) {
+        this.clientManager = clientManager;
+        this.protocolFactory = protocolFactory;
+      }
+      public AsyncClient getAsyncClient(org.apache.thrift.transport.TNonblockingTransport transport) {
+        return new AsyncClient(protocolFactory, clientManager, transport);
+      }
+    }
+
+    public AsyncClient(org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.async.TAsyncClientManager clientManager, org.apache.thrift.transport.TNonblockingTransport transport) {
+      super(protocolFactory, clientManager, transport);
+    }
+
+    public void replicateLog(int remoteTableId, WalEdits data, org.apache.thrift.async.AsyncMethodCallback<replicateLog_call> resultHandler) throws org.apache.thrift.TException {
+      checkReady();
+      replicateLog_call method_call = new replicateLog_call(remoteTableId, data, resultHandler, this, ___protocolFactory, ___transport);
+      this.___currentMethod = method_call;
+      ___manager.call(method_call);
+    }
+
+    public static class replicateLog_call extends org.apache.thrift.async.TAsyncMethodCall {
+      private int remoteTableId;
+      private WalEdits data;
+      public replicateLog_call(int remoteTableId, WalEdits data, org.apache.thrift.async.AsyncMethodCallback<replicateLog_call> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
+        super(client, protocolFactory, transport, resultHandler, false);
+        this.remoteTableId = remoteTableId;
+        this.data = data;
+      }
+
+      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
+        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("replicateLog", org.apache.thrift.protocol.TMessageType.CALL, 0));
+        replicateLog_args args = new replicateLog_args();
+        args.setRemoteTableId(remoteTableId);
+        args.setData(data);
+        args.write(prot);
+        prot.writeMessageEnd();
+      }
+
+      public void getResult() throws RemoteReplicationException, org.apache.thrift.TException {
+        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
+          throw new IllegalStateException("Method call not finished!");
+        }
+        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
+        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
+        (new Client(prot)).recv_replicateLog();
+      }
+    }
+
+    public void replicateKeyValues(int remoteTableId, KeyValues data, org.apache.thrift.async.AsyncMethodCallback<replicateKeyValues_call> resultHandler) throws org.apache.thrift.TException {
+      checkReady();
+      replicateKeyValues_call method_call = new replicateKeyValues_call(remoteTableId, data, resultHandler, this, ___protocolFactory, ___transport);
+      this.___currentMethod = method_call;
+      ___manager.call(method_call);
+    }
+
+    public static class replicateKeyValues_call extends org.apache.thrift.async.TAsyncMethodCall {
+      private int remoteTableId;
+      private KeyValues data;
+      public replicateKeyValues_call(int remoteTableId, KeyValues data, org.apache.thrift.async.AsyncMethodCallback<replicateKeyValues_call> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
+        super(client, protocolFactory, transport, resultHandler, false);
+        this.remoteTableId = remoteTableId;
+        this.data = data;
+      }
+
+      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
+        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("replicateKeyValues", org.apache.thrift.protocol.TMessageType.CALL, 0));
+        replicateKeyValues_args args = new replicateKeyValues_args();
+        args.setRemoteTableId(remoteTableId);
+        args.setData(data);
+        args.write(prot);
+        prot.writeMessageEnd();
+      }
+
+      public void getResult() throws RemoteReplicationException, org.apache.thrift.TException {
+        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
+          throw new IllegalStateException("Method call not finished!");
+        }
+        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
+        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
+        (new Client(prot)).recv_replicateKeyValues();
+      }
+    }
+
+  }
+
+  public static class Processor<I extends Iface> extends org.apache.thrift.TBaseProcessor<I> implements org.apache.thrift.TProcessor {
+    private static final Logger LOGGER = LoggerFactory.getLogger(Processor.class.getName());
+    public Processor(I iface) {
+      super(iface, getProcessMap(new HashMap<String, org.apache.thrift.ProcessFunction<I, ? extends org.apache.thrift.TBase>>()));
+    }
+
+    protected Processor(I iface, Map<String,  org.apache.thrift.ProcessFunction<I, ? extends  org.apache.thrift.TBase>> processMap) {
+      super(iface, getProcessMap(processMap));
+    }
+
+    private static <I extends Iface> Map<String,  org.apache.thrift.ProcessFunction<I, ? extends  org.apache.thrift.TBase>> getProcessMap(Map<String,  org.apache.thrift.ProcessFunction<I, ? extends  org.apache.thrift.TBase>> processMap) {
+      processMap.put("replicateLog", new replicateLog());
+      processMap.put("replicateKeyValues", new replicateKeyValues());
+      return processMap;
+    }
+
+    public static class replicateLog<I extends Iface> extends org.apache.thrift.ProcessFunction<I, replicateLog_args> {
+      public replicateLog() {
+        super("replicateLog");
+      }
+
+      public replicateLog_args getEmptyArgsInstance() {
+        return new replicateLog_args();
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      public replicateLog_result getResult(I iface, replicateLog_args args) throws org.apache.thrift.TException {
+        replicateLog_result result = new replicateLog_result();
+        try {
+          iface.replicateLog(args.remoteTableId, args.data);
+        } catch (RemoteReplicationException e) {
+          result.e = e;
+        }
+        return result;
+      }
+    }
+
+    public static class replicateKeyValues<I extends Iface> extends org.apache.thrift.ProcessFunction<I, replicateKeyValues_args> {
+      public replicateKeyValues() {
+        super("replicateKeyValues");
+      }
+
+      public replicateKeyValues_args getEmptyArgsInstance() {
+        return new replicateKeyValues_args();
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      public replicateKeyValues_result getResult(I iface, replicateKeyValues_args args) throws org.apache.thrift.TException {
+        replicateKeyValues_result result = new replicateKeyValues_result();
+        try {
+          iface.replicateKeyValues(args.remoteTableId, args.data);
+        } catch (RemoteReplicationException e) {
+          result.e = e;
+        }
+        return result;
+      }
+    }
+
+  }
+
+  public static class replicateLog_args implements org.apache.thrift.TBase<replicateLog_args, replicateLog_args._Fields>, java.io.Serializable, Cloneable   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("replicateLog_args");
+
+    private static final org.apache.thrift.protocol.TField REMOTE_TABLE_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("remoteTableId", org.apache.thrift.protocol.TType.I32, (short)1);
+    private static final org.apache.thrift.protocol.TField DATA_FIELD_DESC = new org.apache.thrift.protocol.TField("data", org.apache.thrift.protocol.TType.STRUCT, (short)2);
+
+    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
+    static {
+      schemes.put(StandardScheme.class, new replicateLog_argsStandardSchemeFactory());
+      schemes.put(TupleScheme.class, new replicateLog_argsTupleSchemeFactory());
+    }
+
+    public int remoteTableId; // required
+    public WalEdits data; // required
+
+    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+    @SuppressWarnings("all") public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+      REMOTE_TABLE_ID((short)1, "remoteTableId"),
+      DATA((short)2, "data");
+
+      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+
+      static {
+        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+          byName.put(field.getFieldName(), field);
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, or null if its not found.
+       */
+      public static _Fields findByThriftId(int fieldId) {
+        switch(fieldId) {
+          case 1: // REMOTE_TABLE_ID
+            return REMOTE_TABLE_ID;
+          case 2: // DATA
+            return DATA;
+          default:
+            return null;
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, throwing an exception
+       * if it is not found.
+       */
+      public static _Fields findByThriftIdOrThrow(int fieldId) {
+        _Fields fields = findByThriftId(fieldId);
+        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    private static final int __REMOTETABLEID_ISSET_ID = 0;
+    private byte __isset_bitfield = 0;
+    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    static {
+      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+      tmpMap.put(_Fields.REMOTE_TABLE_ID, new org.apache.thrift.meta_data.FieldMetaData("remoteTableId", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
+      tmpMap.put(_Fields.DATA, new org.apache.thrift.meta_data.FieldMetaData("data", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, WalEdits.class)));
+      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(replicateLog_args.class, metaDataMap);
+    }
+
+    public replicateLog_args() {
+    }
+
+    public replicateLog_args(
+      int remoteTableId,
+      WalEdits data)
+    {
+      this();
+      this.remoteTableId = remoteTableId;
+      setRemoteTableIdIsSet(true);
+      this.data = data;
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public replicateLog_args(replicateLog_args other) {
+      __isset_bitfield = other.__isset_bitfield;
+      this.remoteTableId = other.remoteTableId;
+      if (other.isSetData()) {
+        this.data = new WalEdits(other.data);
+      }
+    }
+
+    public replicateLog_args deepCopy() {
+      return new replicateLog_args(this);
+    }
+
+    @Override
+    public void clear() {
+      setRemoteTableIdIsSet(false);
+      this.remoteTableId = 0;
+      this.data = null;
+    }
+
+    public int getRemoteTableId() {
+      return this.remoteTableId;
+    }
+
+    public replicateLog_args setRemoteTableId(int remoteTableId) {
+      this.remoteTableId = remoteTableId;
+      setRemoteTableIdIsSet(true);
+      return this;
+    }
+
+    public void unsetRemoteTableId() {
+      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __REMOTETABLEID_ISSET_ID);
+    }
+
+    /** Returns true if field remoteTableId is set (has been assigned a value) and false otherwise */
+    public boolean isSetRemoteTableId() {
+      return EncodingUtils.testBit(__isset_bitfield, __REMOTETABLEID_ISSET_ID);
+    }
+
+    public void setRemoteTableIdIsSet(boolean value) {
+      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __REMOTETABLEID_ISSET_ID, value);
+    }
+
+    public WalEdits getData() {
+      return this.data;
+    }
+
+    public replicateLog_args setData(WalEdits data) {
+      this.data = data;
+      return this;
+    }
+
+    public void unsetData() {
+      this.data = null;
+    }
+
+    /** Returns true if field data is set (has been assigned a value) and false otherwise */
+    public boolean isSetData() {
+      return this.data != null;
+    }
+
+    public void setDataIsSet(boolean value) {
+      if (!value) {
+        this.data = null;
+      }
+    }
+
+    public void setFieldValue(_Fields field, Object value) {
+      switch (field) {
+      case REMOTE_TABLE_ID:
+        if (value == null) {
+          unsetRemoteTableId();
+        } else {
+          setRemoteTableId((Integer)value);
+        }
+        break;
+
+      case DATA:
+        if (value == null) {
+          unsetData();
+        } else {
+          setData((WalEdits)value);
+        }
+        break;
+
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      case REMOTE_TABLE_ID:
+        return Integer.valueOf(getRemoteTableId());
+
+      case DATA:
+        return getData();
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case REMOTE_TABLE_ID:
+        return isSetRemoteTableId();
+      case DATA:
+        return isSetData();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof replicateLog_args)
+        return this.equals((replicateLog_args)that);
+      return false;
+    }
+
+    public boolean equals(replicateLog_args that) {
+      if (that == null)
+        return false;
+
+      boolean this_present_remoteTableId = true;
+      boolean that_present_remoteTableId = true;
+      if (this_present_remoteTableId || that_present_remoteTableId) {
+        if (!(this_present_remoteTableId && that_present_remoteTableId))
+          return false;
+        if (this.remoteTableId != that.remoteTableId)
+          return false;
+      }
+
+      boolean this_present_data = true && this.isSetData();
+      boolean that_present_data = true && that.isSetData();
+      if (this_present_data || that_present_data) {
+        if (!(this_present_data && that_present_data))
+          return false;
+        if (!this.data.equals(that.data))
+          return false;
+      }
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      return 0;
+    }
+
+    public int compareTo(replicateLog_args other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+      replicateLog_args typedOther = (replicateLog_args)other;
+
+      lastComparison = Boolean.valueOf(isSetRemoteTableId()).compareTo(typedOther.isSetRemoteTableId());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetRemoteTableId()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.remoteTableId, typedOther.remoteTableId);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetData()).compareTo(typedOther.isSetData());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetData()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.data, typedOther.data);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      return 0;
+    }
+
+    public _Fields fieldForId(int fieldId) {
+      return _Fields.findByThriftId(fieldId);
+    }
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
+    }
+
+    @Override
+    public String toString() {
+      StringBuilder sb = new StringBuilder("replicateLog_args(");
+      boolean first = true;
+
+      sb.append("remoteTableId:");
+      sb.append(this.remoteTableId);
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("data:");
+      if (this.data == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.data);
+      }
+      first = false;
+      sb.append(")");
+      return sb.toString();
+    }
+
+    public void validate() throws org.apache.thrift.TException {
+      // check for required fields
+      // check for sub-struct validity
+      if (data != null) {
+        data.validate();
+      }
+    }
+
+    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+      try {
+        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+      try {
+        // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor.
+        __isset_bitfield = 0;
+        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private static class replicateLog_argsStandardSchemeFactory implements SchemeFactory {
+      public replicateLog_argsStandardScheme getScheme() {
+        return new replicateLog_argsStandardScheme();
+      }
+    }
+
+    private static class replicateLog_argsStandardScheme extends StandardScheme<replicateLog_args> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, replicateLog_args struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TField schemeField;
+        iprot.readStructBegin();
+        while (true)
+        {
+          schemeField = iprot.readFieldBegin();
+          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+            break;
+          }
+          switch (schemeField.id) {
+            case 1: // REMOTE_TABLE_ID
+              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
+                struct.remoteTableId = iprot.readI32();
+                struct.setRemoteTableIdIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 2: // DATA
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.data = new WalEdits();
+                struct.data.read(iprot);
+                struct.setDataIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            default:
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+          }
+          iprot.readFieldEnd();
+        }
+        iprot.readStructEnd();
+
+        // check for required fields of primitive type, which can't be checked in the validate method
+        struct.validate();
+      }
+
+      public void write(org.apache.thrift.protocol.TProtocol oprot, replicateLog_args struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        oprot.writeFieldBegin(REMOTE_TABLE_ID_FIELD_DESC);
+        oprot.writeI32(struct.remoteTableId);
+        oprot.writeFieldEnd();
+        if (struct.data != null) {
+          oprot.writeFieldBegin(DATA_FIELD_DESC);
+          struct.data.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        oprot.writeFieldStop();
+        oprot.writeStructEnd();
+      }
+
+    }
+
+    private static class replicateLog_argsTupleSchemeFactory implements SchemeFactory {
+      public replicateLog_argsTupleScheme getScheme() {
+        return new replicateLog_argsTupleScheme();
+      }
+    }
+
+    private static class replicateLog_argsTupleScheme extends TupleScheme<replicateLog_args> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, replicateLog_args struct) throws org.apache.thrift.TException {
+        TTupleProtocol oprot = (TTupleProtocol) prot;
+        BitSet optionals = new BitSet();
+        if (struct.isSetRemoteTableId()) {
+          optionals.set(0);
+        }
+        if (struct.isSetData()) {
+          optionals.set(1);
+        }
+        oprot.writeBitSet(optionals, 2);
+        if (struct.isSetRemoteTableId()) {
+          oprot.writeI32(struct.remoteTableId);
+        }
+        if (struct.isSetData()) {
+          struct.data.write(oprot);
+        }
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, replicateLog_args struct) throws org.apache.thrift.TException {
+        TTupleProtocol iprot = (TTupleProtocol) prot;
+        BitSet incoming = iprot.readBitSet(2);
+        if (incoming.get(0)) {
+          struct.remoteTableId = iprot.readI32();
+          struct.setRemoteTableIdIsSet(true);
+        }
+        if (incoming.get(1)) {
+          struct.data = new WalEdits();
+          struct.data.read(iprot);
+          struct.setDataIsSet(true);
+        }
+      }
+    }
+
+  }
+
+  public static class replicateLog_result implements org.apache.thrift.TBase<replicateLog_result, replicateLog_result._Fields>, java.io.Serializable, Cloneable   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("replicateLog_result");
+
+    private static final org.apache.thrift.protocol.TField E_FIELD_DESC = new org.apache.thrift.protocol.TField("e", org.apache.thrift.protocol.TType.STRUCT, (short)1);
+
+    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
+    static {
+      schemes.put(StandardScheme.class, new replicateLog_resultStandardSchemeFactory());
+      schemes.put(TupleScheme.class, new replicateLog_resultTupleSchemeFactory());
+    }
+
+    public RemoteReplicationException e; // required
+
+    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+    @SuppressWarnings("all") public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+      E((short)1, "e");
+
+      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+
+      static {
+        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+          byName.put(field.getFieldName(), field);
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, or null if its not found.
+       */
+      public static _Fields findByThriftId(int fieldId) {
+        switch(fieldId) {
+          case 1: // E
+            return E;
+          default:
+            return null;
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, throwing an exception
+       * if it is not found.
+       */
+      public static _Fields findByThriftIdOrThrow(int fieldId) {
+        _Fields fields = findByThriftId(fieldId);
+        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    static {
+      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+      tmpMap.put(_Fields.E, new org.apache.thrift.meta_data.FieldMetaData("e", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
+      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(replicateLog_result.class, metaDataMap);
+    }
+
+    public replicateLog_result() {
+    }
+
+    public replicateLog_result(
+      RemoteReplicationException e)
+    {
+      this();
+      this.e = e;
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public replicateLog_result(replicateLog_result other) {
+      if (other.isSetE()) {
+        this.e = new RemoteReplicationException(other.e);
+      }
+    }
+
+    public replicateLog_result deepCopy() {
+      return new replicateLog_result(this);
+    }
+
+    @Override
+    public void clear() {
+      this.e = null;
+    }
+
+    public RemoteReplicationException getE() {
+      return this.e;
+    }
+
+    public replicateLog_result setE(RemoteReplicationException e) {
+      this.e = e;
+      return this;
+    }
+
+    public void unsetE() {
+      this.e = null;
+    }
+
+    /** Returns true if field e is set (has been assigned a value) and false otherwise */
+    public boolean isSetE() {
+      return this.e != null;
+    }
+
+    public void setEIsSet(boolean value) {
+      if (!value) {
+        this.e = null;
+      }
+    }
+
+    public void setFieldValue(_Fields field, Object value) {
+      switch (field) {
+      case E:
+        if (value == null) {
+          unsetE();
+        } else {
+          setE((RemoteReplicationException)value);
+        }
+        break;
+
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      case E:
+        return getE();
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case E:
+        return isSetE();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof replicateLog_result)
+        return this.equals((replicateLog_result)that);
+      return false;
+    }
+
+    public boolean equals(replicateLog_result that) {
+      if (that == null)
+        return false;
+
+      boolean this_present_e = true && this.isSetE();
+      boolean that_present_e = true && that.isSetE();
+      if (this_present_e || that_present_e) {
+        if (!(this_present_e && that_present_e))
+          return false;
+        if (!this.e.equals(that.e))
+          return false;
+      }
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      return 0;
+    }
+
+    public int compareTo(replicateLog_result other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+      replicateLog_result typedOther = (replicateLog_result)other;
+
+      lastComparison = Boolean.valueOf(isSetE()).compareTo(typedOther.isSetE());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetE()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.e, typedOther.e);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      return 0;
+    }
+
+    public _Fields fieldForId(int fieldId) {
+      return _Fields.findByThriftId(fieldId);
+    }
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
+      }
+
+    @Override
+    public String toString() {
+      StringBuilder sb = new StringBuilder("replicateLog_result(");
+      boolean first = true;
+
+      sb.append("e:");
+      if (this.e == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.e);
+      }
+      first = false;
+      sb.append(")");
+      return sb.toString();
+    }
+
+    public void validate() throws org.apache.thrift.TException {
+      // check for required fields
+      // check for sub-struct validity
+    }
+
+    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+      try {
+        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+      try {
+        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private static class replicateLog_resultStandardSchemeFactory implements SchemeFactory {
+      public replicateLog_resultStandardScheme getScheme() {
+        return new replicateLog_resultStandardScheme();
+      }
+    }
+
+    private static class replicateLog_resultStandardScheme extends StandardScheme<replicateLog_result> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, replicateLog_result struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TField schemeField;
+        iprot.readStructBegin();
+        while (true)
+        {
+          schemeField = iprot.readFieldBegin();
+          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+            break;
+          }
+          switch (schemeField.id) {
+            case 1: // E
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.e = new RemoteReplicationException();
+                struct.e.read(iprot);
+                struct.setEIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            default:
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+          }
+          iprot.readFieldEnd();
+        }
+        iprot.readStructEnd();
+
+        // check for required fields of primitive type, which can't be checked in the validate method
+        struct.validate();
+      }
+
+      public void write(org.apache.thrift.protocol.TProtocol oprot, replicateLog_result struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        if (struct.e != null) {
+          oprot.writeFieldBegin(E_FIELD_DESC);
+          struct.e.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        oprot.writeFieldStop();
+        oprot.writeStructEnd();
+      }
+
+    }
+
+    private static class replicateLog_resultTupleSchemeFactory implements SchemeFactory {
+      public replicateLog_resultTupleScheme getScheme() {
+        return new replicateLog_resultTupleScheme();
+      }
+    }
+
+    private static class replicateLog_resultTupleScheme extends TupleScheme<replicateLog_result> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, replicateLog_result struct) throws org.apache.thrift.TException {
+        TTupleProtocol oprot = (TTupleProtocol) prot;
+        BitSet optionals = new BitSet();
+        if (struct.isSetE()) {
+          optionals.set(0);
+        }
+        oprot.writeBitSet(optionals, 1);
+        if (struct.isSetE()) {
+          struct.e.write(oprot);
+        }
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, replicateLog_result struct) throws org.apache.thrift.TException {
+        TTupleProtocol iprot = (TTupleProtocol) prot;
+        BitSet incoming = iprot.readBitSet(1);
+        if (incoming.get(0)) {
+          struct.e = new RemoteReplicationException();
+          struct.e.read(iprot);
+          struct.setEIsSet(true);
+        }
+      }
+    }
+
+  }
+
+  public static class replicateKeyValues_args implements org.apache.thrift.TBase<replicateKeyValues_args, replicateKeyValues_args._Fields>, java.io.Serializable, Cloneable   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("replicateKeyValues_args");
+
+    private static final org.apache.thrift.protocol.TField REMOTE_TABLE_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("remoteTableId", org.apache.thrift.protocol.TType.I32, (short)1);
+    private static final org.apache.thrift.protocol.TField DATA_FIELD_DESC = new org.apache.thrift.protocol.TField("data", org.apache.thrift.protocol.TType.STRUCT, (short)2);
+
+    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
+    static {
+      schemes.put(StandardScheme.class, new replicateKeyValues_argsStandardSchemeFactory());
+      schemes.put(TupleScheme.class, new replicateKeyValues_argsTupleSchemeFactory());
+    }
+
+    public int remoteTableId; // required
+    public KeyValues data; // required
+
+    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+    @SuppressWarnings("all") public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+      REMOTE_TABLE_ID((short)1, "remoteTableId"),
+      DATA((short)2, "data");
+
+      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+
+      static {
+        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+          byName.put(field.getFieldName(), field);
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, or null if its not found.
+       */
+      public static _Fields findByThriftId(int fieldId) {
+        switch(fieldId) {
+          case 1: // REMOTE_TABLE_ID
+            return REMOTE_TABLE_ID;
+          case 2: // DATA
+            return DATA;
+          default:
+            return null;
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, throwing an exception
+       * if it is not found.
+       */
+      public static _Fields findByThriftIdOrThrow(int fieldId) {
+        _Fields fields = findByThriftId(fieldId);
+        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    private static final int __REMOTETABLEID_ISSET_ID = 0;
+    private byte __isset_bitfield = 0;
+    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    static {
+      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+      tmpMap.put(_Fields.REMOTE_TABLE_ID, new org.apache.thrift.meta_data.FieldMetaData("remoteTableId", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
+      tmpMap.put(_Fields.DATA, new org.apache.thrift.meta_data.FieldMetaData("data", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, KeyValues.class)));
+      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(replicateKeyValues_args.class, metaDataMap);
+    }
+
+    public replicateKeyValues_args() {
+    }
+
+    public replicateKeyValues_args(
+      int remoteTableId,
+      KeyValues data)
+    {
+      this();
+      this.remoteTableId = remoteTableId;
+      setRemoteTableIdIsSet(true);
+      this.data = data;
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public replicateKeyValues_args(replicateKeyValues_args other) {
+      __isset_bitfield = other.__isset_bitfield;
+      this.remoteTableId = other.remoteTableId;
+      if (other.isSetData()) {
+        this.data = new KeyValues(other.data);
+      }
+    }
+
+    public replicateKeyValues_args deepCopy() {
+      return new replicateKeyValues_args(this);
+    }
+
+    @Override
+    public void clear() {
+      setRemoteTableIdIsSet(false);
+      this.remoteTableId = 0;
+      this.data = null;
+    }
+
+    public int getRemoteTableId() {
+      return this.remoteTableId;
+    }
+
+    public replicateKeyValues_args setRemoteTableId(int remoteTableId) {
+      this.remoteTableId = remoteTableId;
+      setRemoteTableIdIsSet(true);
+      return this;
+    }
+
+    public void unsetRemoteTableId() {
+      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __REMOTETABLEID_ISSET_ID);
+    }
+
+    /** Returns true if field remoteTableId is set (has been assigned a value) and false otherwise */
+    public boolean isSetRemoteTableId() {
+      return EncodingUtils.testBit(__isset_bitfield, __REMOTETABLEID_ISSET_ID);
+    }
+
+    public void setRemoteTableIdIsSet(boolean value) {
+      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __REMOTETABLEID_ISSET_ID, value);
+    }
+
+    public KeyValues getData() {
+      return this.data;
+    }
+
+    public replicateKeyValues_args setData(KeyValues data) {
+      this.data = data;
+      return this;
+    }
+
+    public void unsetData() {
+      this.data = null;
+    }
+
+    /** Returns true if field data is set (has been assigned a value) and false otherwise */
+    public boolean isSetData() {
+      return this.data != null;
+    }
+
+    public void setDataIsSet(boolean value) {
+      if (!value) {
+        this.data = null;
+      }
+    }
+
+    public void setFieldValue(_Fields field, Object value) {
+      switch (field) {
+      case REMOTE_TABLE_ID:
+        if (value == null) {
+          unsetRemoteTableId();
+        } else {
+          setRemoteTableId((Integer)value);
+        }
+        break;
+
+      case DATA:
+        if (value == null) {
+          unsetData();
+        } else {
+          setData((KeyValues)value);
+        }
+        break;
+
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      case REMOTE_TABLE_ID:
+        return Integer.valueOf(getRemoteTableId());
+
+      case DATA:
+        return getData();
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case REMOTE_TABLE_ID:
+        return isSetRemoteTableId();
+      case DATA:
+        return isSetData();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof replicateKeyValues_args)
+        return this.equals((replicateKeyValues_args)that);
+      return false;
+    }
+
+    public boolean equals(replicateKeyValues_args that) {
+      if (that == null)
+        return false;
+
+      boolean this_present_remoteTableId = true;
+      boolean that_present_remoteTableId = true;
+      if (this_present_remoteTableId || that_present_remoteTableId) {
+        if (!(this_present_remoteTableId && that_present_remoteTableId))
+          return false;
+        if (this.remoteTableId != that.remoteTableId)
+          return false;
+      }
+
+      boolean this_present_data = true && this.isSetData();
+      boolean that_present_data = true && that.isSetData();
+      if (this_present_data || that_present_data) {
+        if (!(this_present_data && that_present_data))
+          return false;
+        if (!this.data.equals(that.data))
+          return false;
+      }
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      return 0;
+    }
+
+    public int compareTo(replicateKeyValues_args other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+      replicateKeyValues_args typedOther = (replicateKeyValues_args)other;
+
+      lastComparison = Boolean.valueOf(isSetRemoteTableId()).compareTo(typedOther.isSetRemoteTableId());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetRemoteTableId()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.remoteTableId, typedOther.remoteTableId);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetData()).compareTo(typedOther.isSetData());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetData()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.data, typedOther.data);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      return 0;
+    }
+
+    public _Fields fieldForId(int fieldId) {
+      return _Fields.findByThriftId(fieldId);
+    }
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
+    }
+
+    @Override
+    public String toString() {
+      StringBuilder sb = new StringBuilder("replicateKeyValues_args(");
+      boolean first = true;
+
+      sb.append("remoteTableId:");
+      sb.append(this.remoteTableId);
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("data:");
+      if (this.data == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.data);
+      }
+      first = false;
+      sb.append(")");
+      return sb.toString();
+    }
+
+    public void validate() throws org.apache.thrift.TException {
+      // check for required fields
+      // check for sub-struct validity
+      if (data != null) {
+        data.validate();
+      }
+    }
+
+    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+      try {
+        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+      try {
+        // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor.
+        __isset_bitfield = 0;
+        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private static class replicateKeyValues_argsStandardSchemeFactory implements SchemeFactory {
+      public replicateKeyValues_argsStandardScheme getScheme() {
+        return new replicateKeyValues_argsStandardScheme();
+      }
+    }
+
+    private static class replicateKeyValues_argsStandardScheme extends StandardScheme<replicateKeyValues_args> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, replicateKeyValues_args struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TField schemeField;
+        iprot.readStructBegin();
+        while (true)
+        {
+          schemeField = iprot.readFieldBegin();
+          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+            break;
+          }
+          switch (schemeField.id) {
+            case 1: // REMOTE_TABLE_ID
+              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
+                struct.remoteTableId = iprot.readI32();
+                struct.setRemoteTableIdIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 2: // DATA
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.data = new KeyValues();
+                struct.data.read(iprot);
+                struct.setDataIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            default:
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+          }
+          iprot.readFieldEnd();
+        }
+        iprot.readStructEnd();
+
+        // check for required fields of primitive type, which can't be checked in the validate method
+        struct.validate();
+      }
+
+      public void write(org.apache.thrift.protocol.TProtocol oprot, replicateKeyValues_args struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        oprot.writeFieldBegin(REMOTE_TABLE_ID_FIELD_DESC);
+        oprot.writeI32(struct.remoteTableId);
+        oprot.writeFieldEnd();
+        if (struct.data != null) {
+          oprot.writeFieldBegin(DATA_FIELD_DESC);
+          struct.data.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        oprot.writeFieldStop();
+        oprot.writeStructEnd();
+      }
+
+    }
+
+    private static class replicateKeyValues_argsTupleSchemeFactory implements SchemeFactory {
+      public replicateKeyValues_argsTupleScheme getScheme() {
+        return new replicateKeyValues_argsTupleScheme();
+      }
+    }
+
+    private static class replicateKeyValues_argsTupleScheme extends TupleScheme<replicateKeyValues_args> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, replicateKeyValues_args struct) throws org.apache.thrift.TException {
+        TTupleProtocol oprot = (TTupleProtocol) prot;
+        BitSet optionals = new BitSet();
+        if (struct.isSetRemoteTableId()) {
+          optionals.set(0);
+        }
+        if (struct.isSetData()) {
+          optionals.set(1);
+        }
+        oprot.writeBitSet(optionals, 2);
+        if (struct.isSetRemoteTableId()) {
+          oprot.writeI32(struct.remoteTableId);
+        }
+        if (struct.isSetData()) {
+          struct.data.write(oprot);
+        }
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, replicateKeyValues_args struct) throws org.apache.thrift.TException {
+        TTupleProtocol iprot = (TTupleProtocol) prot;
+        BitSet incoming = iprot.readBitSet(2);
+        if (incoming.get(0)) {
+          struct.remoteTableId = iprot.readI32();
+          struct.setRemoteTableIdIsSet(true);
+        }
+        if (incoming.get(1)) {
+          struct.data = new KeyValues();
+          struct.data.read(iprot);
+          struct.setDataIsSet(true);
+        }
+      }
+    }
+
+  }
+
+  public static class replicateKeyValues_result implements org.apache.thrift.TBase<replicateKeyValues_result, replicateKeyValues_result._Fields>, java.io.Serializable, Cloneable   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("replicateKeyValues_result");
+
+    private static final org.apache.thrift.protocol.TField E_FIELD_DESC = new org.apache.thrift.protocol.TField("e", org.apache.thrift.protocol.TType.STRUCT, (short)1);
+
+    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
+    static {
+      schemes.put(StandardScheme.class, new replicateKeyValues_resultStandardSchemeFactory());
+      schemes.put(TupleScheme.class, new replicateKeyValues_resultTupleSchemeFactory());
+    }
+
+    public RemoteReplicationException e; // required
+
+    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+    @SuppressWarnings("all") public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+      E((short)1, "e");
+
+      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+
+      static {
+        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+          byName.put(field.getFieldName(), field);
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, or null if its not found.
+       */
+      public static _Fields findByThriftId(int fieldId) {
+        switch(fieldId) {
+          case 1: // E
+            return E;
+          default:
+            return null;
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, throwing an exception
+       * if it is not found.
+       */
+      public static _Fields findByThriftIdOrThrow(int fieldId) {
+        _Fields fields = findByThriftId(fieldId);
+        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    static {
+      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+      tmpMap.put(_Fields.E, new org.apache.thrift.meta_data.FieldMetaData("e", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
+      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(replicateKeyValues_result.class, metaDataMap);
+    }
+
+    public replicateKeyValues_result() {
+    }
+
+    public replicateKeyValues_result(
+      RemoteReplicationException e)
+    {
+      this();
+      this.e = e;
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public replicateKeyValues_result(replicateKeyValues_result other) {
+      if (other.isSetE()) {
+        this.e = new RemoteReplicationException(other.e);
+      }
+    }
+
+    public replicateKeyValues_result deepCopy() {
+      return new replicateKeyValues_result(this);
+    }
+
+    @Override
+    public void clear() {
+      this.e = null;
+    }
+
+    public RemoteReplicationException getE() {
+      return this.e;
+    }
+
+    public replicateKeyValues_result setE(RemoteReplicationException e) {
+      this.e = e;
+      return this;
+    }
+
+    public void unsetE() {
+      this.e = null;
+    }
+
+    /** Returns true if field e is set (has been assigned a value) and false otherwise */
+    public boolean isSetE() {
+      return this.e != null;
+    }
+
+    public void setEIsSet(boolean value) {
+      if (!value) {
+        this.e = null;
+      }
+    }
+
+    public void setFieldValue(_Fields field, Object value) {
+      switch (field) {
+      case E:
+        if (value == null) {
+          unsetE();
+        } else {
+          setE((RemoteReplicationException)value);
+        }
+        break;
+
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      case E:
+        return getE();
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case E:
+        return isSetE();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof replicateKeyValues_result)
+        return this.equals((replicateKeyValues_result)that);
+      return false;
+    }
+
+    public boolean equals(replicateKeyValues_result that) {
+      if (that == null)
+        return false;
+
+      boolean this_present_e = true && this.isSetE();
+      boolean that_present_e = true && that.isSetE();
+      if (this_present_e || that_present_e) {
+        if (!(this_present_e && that_present_e))
+          return false;
+        if (!this.e.equals(that.e))
+          return false;
+      }
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      return 0;
+    }
+
+    public int compareTo(replicateKeyValues_result other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+      replicateKeyValues_result typedOther = (replicateKeyValues_result)other;
+
+      lastComparison = Boolean.valueOf(isSetE()).compareTo(typedOther.isSetE());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetE()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.e, typedOther.e);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      return 0;
+    }
+
+    public _Fields fieldForId(int fieldId) {
+      return _Fields.findByThriftId(fieldId);
+    }
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
+      }
+
+    @Override
+    public String toString() {
+      StringBuilder sb = new StringBuilder("replicateKeyValues_result(");
+      boolean first = true;
+
+      sb.append("e:");
+      if (this.e == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.e);
+      }
+      first = false;
+      sb.append(")");
+      return sb.toString();
+    }
+
+    public void validate() throws org.apache.thrift.TException {
+      // check for required fields
+      // check for sub-struct validity
+    }
+
+    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+      try {
+        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+      try {
+        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private static class replicateKeyValues_resultStandardSchemeFactory implements SchemeFactory {
+      public replicateKeyValues_resultStandardScheme getScheme() {
+        return new replicateKeyValues_resultStandardScheme();
+      }
+    }
+
+    private static class replicateKeyValues_resultStandardScheme extends StandardScheme<replicateKeyValues_result> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, replicateKeyValues_result struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TField schemeField;
+        iprot.readStructBegin();
+        while (true)
+        {
+          schemeField = iprot.readFieldBegin();
+          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+            break;
+          }
+          switch (schemeField.id) {
+            case 1: // E
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.e = new RemoteReplicationException();
+                struct.e.read(iprot);
+                struct.setEIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            default:
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+          }
+          iprot.readFieldEnd();
+        }
+        iprot.readStructEnd();
+
+        // check for required fields of primitive type, which can't be checked in the validate method
+        struct.validate();
+      }
+
+      public void write(org.apache.thrift.protocol.TProtocol oprot, replicateKeyValues_result struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        if (struct.e != null) {
+          oprot.writeFieldBegin(E_FIELD_DESC);
+          struct.e.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        oprot.writeFieldStop();
+        oprot.writeStructEnd();
+      }
+
+    }
+
+    private static class replicateKeyValues_resultTupleSchemeFactory implements SchemeFactory {
+      public replicateKeyValues_resultTupleScheme getScheme() {
+        return new replicateKeyValues_resultTupleScheme();
+      }
+    }
+
+    private static class replicateKeyValues_resultTupleScheme extends TupleScheme<replicateKeyValues_result> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, replicateKeyValues_result struct) throws org.apache.thrift.TException {
+        TTupleProtocol oprot = (TTupleProtocol) prot;
+        BitSet optionals = new BitSet();
+        if (struct.isSetE()) {
+          optionals.set(0);
+        }
+        oprot.writeBitSet(optionals, 1);
+        if (struct.isSetE()) {
+          struct.e.write(oprot);
+        }
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, replicateKeyValues_result struct) throws org.apache.thrift.TException {
+        TTupleProtocol iprot = (TTupleProtocol) prot;
+        BitSet incoming = iprot.readBitSet(1);
+        if (incoming.get(0)) {
+          struct.e = new RemoteReplicationException();
+          struct.e.read(iprot);
+          struct.setEIsSet(true);
+        }
+      }
+    }
+
+  }
+
+}


[16/53] [abbrv] git commit: Merge branch '1.6.0-SNAPSHOT'

Posted by el...@apache.org.
Merge branch '1.6.0-SNAPSHOT'


Project: http://git-wip-us.apache.org/repos/asf/accumulo/repo
Commit: http://git-wip-us.apache.org/repos/asf/accumulo/commit/24f895f3
Tree: http://git-wip-us.apache.org/repos/asf/accumulo/tree/24f895f3
Diff: http://git-wip-us.apache.org/repos/asf/accumulo/diff/24f895f3

Branch: refs/heads/ACCUMULO-378
Commit: 24f895f374e03d60e305bc67b03116c02a5caab4
Parents: bcc9e7e 88f24d2
Author: Bill Havanki <bh...@cloudera.com>
Authored: Mon Apr 7 17:14:09 2014 -0400
Committer: Bill Havanki <bh...@cloudera.com>
Committed: Mon Apr 7 17:14:09 2014 -0400

----------------------------------------------------------------------
 server/gc/pom.xml                               |   5 +
 .../gc/GarbageCollectWriteAheadLogs.java        |  89 ++++++-
 .../accumulo/gc/SimpleGarbageCollector.java     | 134 +++++++++-
 .../gc/GarbageCollectWriteAheadLogsTest.java    | 264 +++++++++++++++++++
 .../gc/SimpleGarbageCollectorOptsTest.java      |  37 +++
 .../accumulo/gc/SimpleGarbageCollectorTest.java | 146 ++++++++++
 6 files changed, 657 insertions(+), 18 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/accumulo/blob/24f895f3/server/gc/pom.xml
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/accumulo/blob/24f895f3/server/gc/src/main/java/org/apache/accumulo/gc/SimpleGarbageCollector.java
----------------------------------------------------------------------


[34/53] [abbrv] ACCUMULO-1879 Move shell into new package and module

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/TableOperation.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/TableOperation.java b/shell/src/main/java/org/apache/accumulo/shell/commands/TableOperation.java
new file mode 100644
index 0000000..032579b
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/TableOperation.java
@@ -0,0 +1,153 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.util.Map;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import org.apache.accumulo.core.client.Instance;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.core.client.impl.Namespaces;
+import org.apache.accumulo.core.client.impl.Tables;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Token;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.OptionGroup;
+import org.apache.commons.cli.Options;
+
+public abstract class TableOperation extends Command {
+
+  protected Option optTablePattern, optTableName, optNamespace;
+  private boolean force = true;
+  private boolean useCommandLine = true;
+
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    // populate the tableSet set with the tables you want to operate on
+    final SortedSet<String> tableSet = new TreeSet<String>();
+    if (cl.hasOption(optTablePattern.getOpt())) {
+      for (String table : shellState.getConnector().tableOperations().list())
+        if (table.matches(cl.getOptionValue(optTablePattern.getOpt()))) {
+          tableSet.add(table);
+        }
+    } else if (cl.hasOption(optTableName.getOpt())) {
+      tableSet.add(cl.getOptionValue(optTableName.getOpt()));
+    } else if (cl.hasOption(optNamespace.getOpt())) {
+      Instance instance = shellState.getInstance();
+      String namespaceId = Namespaces.getNamespaceId(instance, cl.getOptionValue(optNamespace.getOpt()));
+      for (String tableId : Namespaces.getTableIds(instance, namespaceId)) {
+        tableSet.add(Tables.getTableName(instance, tableId));
+      }
+    } else if (useCommandLine && cl.getArgs().length > 0) {
+      for (String tableName : cl.getArgs()) {
+        tableSet.add(tableName);
+      }
+    } else {
+      shellState.checkTableState();
+      tableSet.add(shellState.getTableName());
+    }
+
+    if (tableSet.isEmpty())
+      Shell.log.warn("No tables found that match your criteria");
+
+    boolean more = true;
+    // flush the tables
+    for (String tableName : tableSet) {
+      if (!more) {
+        break;
+      }
+      if (!shellState.getConnector().tableOperations().exists(tableName)) {
+        throw new TableNotFoundException(null, tableName, null);
+      }
+      boolean operate = true;
+      if (!force) {
+        shellState.getReader().flush();
+        String line = shellState.getReader().readLine(getName() + " { " + tableName + " } (yes|no)? ");
+        more = line != null;
+        operate = line != null && (line.equalsIgnoreCase("y") || line.equalsIgnoreCase("yes"));
+      }
+      if (operate) {
+        doTableOp(shellState, tableName);
+      }
+    }
+
+    return 0;
+  }
+
+  protected abstract void doTableOp(Shell shellState, String tableName) throws Exception;
+
+  @Override
+  public String description() {
+    return "makes a best effort to flush tables from memory to disk";
+  }
+
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+
+    optTablePattern = new Option("p", "pattern", true, "regex pattern of table names to operate on");
+    optTablePattern.setArgName("pattern");
+
+    optTableName = new Option(Shell.tableOption, "table", true, "name of a table to operate on");
+    optTableName.setArgName("tableName");
+
+    optNamespace = new Option(Shell.namespaceOption, "namespace", true, "name of a namespace to operate on");
+    optNamespace.setArgName("namespace");
+
+    final OptionGroup opg = new OptionGroup();
+
+    opg.addOption(optTablePattern);
+    opg.addOption(optTableName);
+    opg.addOption(optNamespace);
+
+    o.addOptionGroup(opg);
+
+    return o;
+  }
+
+  @Override
+  public int numArgs() {
+    return useCommandLine ? Shell.NO_FIXED_ARG_LENGTH_CHECK : 0;
+  }
+
+  protected void force() {
+    force = true;
+  }
+
+  protected void noForce() {
+    force = false;
+  }
+
+  protected void disableUnflaggedTableOptions() {
+    useCommandLine = false;
+  }
+
+  @Override
+  public String usage() {
+    return getName() + " [<table>{ <table>}]";
+  }
+
+  @Override
+  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> special) {
+    if (useCommandLine)
+      registerCompletionForTables(root, special);
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/TablePermissionsCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/TablePermissionsCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/TablePermissionsCommand.java
new file mode 100644
index 0000000..75e3fbd
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/TablePermissionsCommand.java
@@ -0,0 +1,44 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.io.IOException;
+
+import org.apache.accumulo.core.security.TablePermission;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+
+public class TablePermissionsCommand extends Command {
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws IOException {
+    for (String p : TablePermission.printableValues()) {
+      shellState.getReader().println(p);
+    }
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "displays a list of valid table permissions";
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/TablesCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/TablesCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/TablesCommand.java
new file mode 100644
index 0000000..5bded8d
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/TablesCommand.java
@@ -0,0 +1,107 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.TreeMap;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.NamespaceNotFoundException;
+import org.apache.accumulo.core.client.impl.Tables;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+import org.apache.commons.collections.MapUtils;
+
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+import com.google.common.collect.Iterators;
+import com.google.common.collect.Maps;
+
+public class TablesCommand extends Command {
+  static final String NAME_AND_ID_FORMAT = "%-20s => %9s%n";
+
+  private Option tableIdOption;
+  private Option sortByTableIdOption;
+  private Option disablePaginationOpt;
+
+  @SuppressWarnings("unchecked")
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException, IOException,
+      NamespaceNotFoundException {
+
+    final String namespace = cl.hasOption(OptUtil.namespaceOpt().getOpt()) ? OptUtil.getNamespaceOpt(cl, shellState) : null;
+    Map<String,String> tables = shellState.getConnector().tableOperations().tableIdMap();
+
+    // filter only specified namespace
+    tables = Maps.filterKeys(tables, new Predicate<String>() {
+      @Override
+      public boolean apply(String tableName) {
+        return namespace == null || Tables.qualify(tableName).getFirst().equals(namespace);
+      }
+    });
+
+    final boolean sortByTableId = cl.hasOption(sortByTableIdOption.getOpt());
+    tables = new TreeMap<String,String>((sortByTableId ? MapUtils.invertMap(tables) : tables));
+
+    Iterator<String> it = Iterators.transform(tables.entrySet().iterator(), new Function<Entry<String,String>,String>() {
+      @Override
+      public String apply(Map.Entry<String,String> entry) {
+        String tableName = String.valueOf(sortByTableId ? entry.getValue() : entry.getKey());
+        String tableId = String.valueOf(sortByTableId ? entry.getKey() : entry.getValue());
+        if (namespace != null)
+          tableName = Tables.qualify(tableName).getSecond();
+        if (cl.hasOption(tableIdOption.getOpt()))
+          return String.format(NAME_AND_ID_FORMAT, tableName, tableId);
+        else
+          return tableName;
+      };
+    });
+
+    shellState.printLines(it, !cl.hasOption(disablePaginationOpt.getOpt()));
+    return 0;
+  }
+
+  @Override
+  public String description() {
+    return "displays a list of all existing tables";
+  }
+
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+    tableIdOption = new Option("l", "list-ids", false, "display internal table ids along with the table name");
+    o.addOption(tableIdOption);
+    sortByTableIdOption = new Option("s", "sort-ids", false, "with -l: sort output by table ids");
+    o.addOption(sortByTableIdOption);
+    disablePaginationOpt = new Option("np", "no-pagination", false, "disable pagination of output");
+    o.addOption(disablePaginationOpt);
+    o.addOption(OptUtil.namespaceOpt("name of namespace to list only its tables"));
+    return o;
+  }
+
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/TraceCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/TraceCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/TraceCommand.java
new file mode 100644
index 0000000..7f63570
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/TraceCommand.java
@@ -0,0 +1,101 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.io.IOException;
+import java.util.Map;
+
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.trace.instrument.Trace;
+import org.apache.accumulo.core.client.Scanner;
+import org.apache.accumulo.core.conf.Property;
+import org.apache.accumulo.core.data.Range;
+import org.apache.accumulo.core.security.Authorizations;
+import org.apache.accumulo.core.trace.TraceDump;
+import org.apache.accumulo.core.trace.TraceDump.Printer;
+import org.apache.accumulo.core.util.BadArgumentException;
+import org.apache.accumulo.core.util.UtilWaitThread;
+import org.apache.commons.cli.CommandLine;
+import org.apache.hadoop.io.Text;
+
+public class TraceCommand extends DebugCommand {
+  
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws IOException {
+    if (cl.getArgs().length == 1) {
+      if (cl.getArgs()[0].equalsIgnoreCase("on")) {
+        Trace.on("shell:" + shellState.getPrincipal());
+      } else if (cl.getArgs()[0].equalsIgnoreCase("off")) {
+        if (Trace.isTracing()) {
+          final long trace = Trace.currentTrace().traceId();
+          Trace.off();
+          StringBuffer sb = new StringBuffer();
+          int traceCount = 0;
+          for (int i = 0; i < 30; i++) {
+            sb = new StringBuffer();
+            try {
+              final Map<String,String> properties = shellState.getConnector().instanceOperations().getSystemConfiguration();
+              final String table = properties.get(Property.TRACE_TABLE.getKey());
+              final String user = shellState.getConnector().whoami();
+              final Authorizations auths = shellState.getConnector().securityOperations().getUserAuthorizations(user);
+              final Scanner scanner = shellState.getConnector().createScanner(table, auths);
+              scanner.setRange(new Range(new Text(Long.toHexString(trace))));
+              final StringBuffer finalSB = sb;
+              traceCount = TraceDump.printTrace(scanner, new Printer() {
+                @Override
+                public void print(final String line) {
+                  try {
+                    finalSB.append(line + "\n");
+                  } catch (Exception ex) {
+                    throw new RuntimeException(ex);
+                  }
+                }
+              });
+              if (traceCount > 0) {
+                shellState.getReader().print(sb.toString());
+                break;
+              }
+            } catch (Exception ex) {
+              shellState.printException(ex);
+            }
+            shellState.getReader().println("Waiting for trace information");
+            shellState.getReader().flush();
+            UtilWaitThread.sleep(500);
+          }
+          if (traceCount < 0) {
+            // display the trace even though there are unrooted spans
+            shellState.getReader().print(sb.toString());
+          }
+        } else {
+          shellState.getReader().println("Not tracing");
+        }
+      } else
+        throw new BadArgumentException("Argument must be 'on' or 'off'", fullCommand, fullCommand.indexOf(cl.getArgs()[0]));
+    } else if (cl.getArgs().length == 0) {
+      shellState.getReader().println(Trace.isTracing() ? "on" : "off");
+    } else {
+      shellState.printException(new IllegalArgumentException("Expected 0 or 1 argument. There were " + cl.getArgs().length + "."));
+      printHelp(shellState);
+      return 1;
+    }
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "turns trace logging on or off";
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/UserCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/UserCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/UserCommand.java
new file mode 100644
index 0000000..491f144
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/UserCommand.java
@@ -0,0 +1,71 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.security.tokens.PasswordToken;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Token;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+
+public class UserCommand extends Command {
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException, IOException {
+    // save old credentials and connection in case of failure
+    String user = cl.getArgs()[0];
+    byte[] pass;
+    
+    // We can't let the wrapping try around the execute method deal
+    // with the exceptions because we have to do something if one
+    // of these methods fails
+    final String p = shellState.readMaskedLine("Enter password for user " + user + ": ", '*');
+    if (p == null) {
+      shellState.getReader().println();
+      return 0;
+    } // user canceled
+    pass = p.getBytes(StandardCharsets.UTF_8);
+    shellState.updateUser(user, new PasswordToken(pass));
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "switches to the specified user";
+  }
+  
+  @Override
+  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> special) {
+    registerCompletionForUsers(root, special);
+  }
+  
+  @Override
+  public String usage() {
+    return getName() + " <username>";
+  }
+  
+  @Override
+  public int numArgs() {
+    return 1;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/UserPermissionsCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/UserPermissionsCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/UserPermissionsCommand.java
new file mode 100644
index 0000000..ad6a20d
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/UserPermissionsCommand.java
@@ -0,0 +1,106 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.io.IOException;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.security.NamespacePermission;
+import org.apache.accumulo.core.security.SystemPermission;
+import org.apache.accumulo.core.security.TablePermission;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+
+public class UserPermissionsCommand extends Command {
+  private Option userOpt;
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException, IOException {
+    final String user = cl.getOptionValue(userOpt.getOpt(), shellState.getConnector().whoami());
+
+    String delim = "";
+    shellState.getReader().print("System permissions: ");
+    for (SystemPermission p : SystemPermission.values()) {
+      if (p != null && shellState.getConnector().securityOperations().hasSystemPermission(user, p)) {
+        shellState.getReader().print(delim + "System." + p.name());
+        delim = ", ";
+      }
+    }
+    shellState.getReader().println();
+
+    boolean runOnce = true;
+    for (String n : shellState.getConnector().namespaceOperations().list()) {
+      delim = "";
+      for (NamespacePermission p : NamespacePermission.values()) {
+        if (p != null && shellState.getConnector().securityOperations().hasNamespacePermission(user, n, p)) {
+          if (runOnce) {
+            shellState.getReader().print("\nNamespace permissions (" + n + "): ");
+            runOnce = false;
+          }
+          shellState.getReader().print(delim + "Namespace." + p.name());
+          delim = ", ";
+        }
+      }
+      runOnce = true;
+    }
+    shellState.getReader().println();
+
+    
+    runOnce = true;
+    for (String t : shellState.getConnector().tableOperations().list()) {
+      delim = "";
+      for (TablePermission p : TablePermission.values()) {
+        if (shellState.getConnector().securityOperations().hasTablePermission(user, t, p) && p != null) {
+          if (runOnce) {
+            shellState.getReader().print("\nTable permissions (" + t + "): ");
+            runOnce = false;
+          }
+          shellState.getReader().print(delim + "Table." + p.name());
+          delim = ", ";
+        }
+
+      }
+      runOnce = true;
+    }
+    shellState.getReader().println();
+
+    return 0;
+  }
+
+  @Override
+  public String description() {
+    return "displays a user's system, table, and namespace permissions";
+  }
+
+  @Override
+  public Options getOptions() {
+    Options o = new Options();
+    userOpt = new Option(Shell.userOption, "user", true, "user to operate on");
+    userOpt.setArgName("user");
+    o.addOption(userOpt);
+    return o;
+  }
+
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/UsersCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/UsersCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/UsersCommand.java
new file mode 100644
index 0000000..5ea61bf
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/UsersCommand.java
@@ -0,0 +1,45 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.io.IOException;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+
+public class UsersCommand extends Command {
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException, IOException {
+    for (String user : shellState.getConnector().securityOperations().listLocalUsers()) {
+      shellState.getReader().println(user);
+    }
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "displays a list of existing users";
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/WhoAmICommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/WhoAmICommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/WhoAmICommand.java
new file mode 100644
index 0000000..f80a621
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/WhoAmICommand.java
@@ -0,0 +1,41 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.io.IOException;
+
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+
+public class WhoAmICommand extends Command {
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws IOException {
+    shellState.getReader().println(shellState.getConnector().whoami());
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "reports the current user name";
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/format/DeleterFormatter.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/format/DeleterFormatter.java b/shell/src/main/java/org/apache/accumulo/shell/format/DeleterFormatter.java
new file mode 100644
index 0000000..b90b55e
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/format/DeleterFormatter.java
@@ -0,0 +1,102 @@
+/*
+ * 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.accumulo.shell.format;
+
+import java.io.IOException;
+import java.util.Map.Entry;
+
+import org.apache.accumulo.core.client.BatchWriter;
+import org.apache.accumulo.core.client.MutationsRejectedException;
+import org.apache.accumulo.core.data.ConstraintViolationSummary;
+import org.apache.accumulo.core.data.Key;
+import org.apache.accumulo.core.data.Mutation;
+import org.apache.accumulo.core.data.Value;
+import org.apache.accumulo.core.security.ColumnVisibility;
+import org.apache.accumulo.core.util.format.DefaultFormatter;
+import org.apache.accumulo.shell.Shell;
+import org.apache.log4j.Logger;
+
+public class DeleterFormatter extends DefaultFormatter {
+  
+  private static final Logger log = Logger.getLogger(DeleterFormatter.class);
+  private BatchWriter writer;
+  private Shell shellState;
+  private boolean printTimestamps;
+  private boolean force;
+  private boolean more;
+  
+  public DeleterFormatter(BatchWriter writer, Iterable<Entry<Key,Value>> scanner, boolean printTimestamps, Shell shellState, boolean force) {
+    super.initialize(scanner, printTimestamps);
+    this.writer = writer;
+    this.shellState = shellState;
+    this.printTimestamps = printTimestamps;
+    this.force = force;
+    this.more = true;
+  }
+  
+  @Override
+  public boolean hasNext() {
+    if (!getScannerIterator().hasNext() || !more) {
+      try {
+        writer.close();
+      } catch (MutationsRejectedException e) {
+        log.error(e.toString());
+        if (Shell.isDebuggingEnabled())
+          for (ConstraintViolationSummary cvs : e.getConstraintViolationSummaries())
+            log.trace(cvs.toString());
+      }
+      return false;
+    }
+    return true;
+  }
+  
+  /**
+   * @return null, because the iteration will provide prompts and handle deletes internally.
+   */
+  @Override
+  public String next() {
+    Entry<Key,Value> next = getScannerIterator().next();
+    Key key = next.getKey();
+    Mutation m = new Mutation(key.getRow());
+    String entryStr = formatEntry(next, printTimestamps);
+    boolean delete = force;
+    try {
+      if (!force) {
+        shellState.getReader().flush();
+        String line = shellState.getReader().readLine("Delete { " + entryStr + " } ? ");
+        more = line != null;
+        delete = line != null && (line.equalsIgnoreCase("y") || line.equalsIgnoreCase("yes"));
+      }
+      if (delete) {
+        m.putDelete(key.getColumnFamily(), key.getColumnQualifier(), new ColumnVisibility(key.getColumnVisibility()), key.getTimestamp());
+        try {
+          writer.addMutation(m);
+        } catch (MutationsRejectedException e) {
+          log.error(e.toString());
+          if (Shell.isDebuggingEnabled())
+            for (ConstraintViolationSummary cvs : e.getConstraintViolationSummaries())
+              log.trace(cvs.toString());
+        }
+      }
+      shellState.getReader().print(String.format("[%s] %s%n", delete ? "DELETED" : "SKIPPED", entryStr));
+    } catch (IOException e) {
+      log.error("Cannot write to console", e);
+      throw new RuntimeException(e);
+    }
+    return null;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/mock/MockShell.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/mock/MockShell.java b/shell/src/main/java/org/apache/accumulo/shell/mock/MockShell.java
new file mode 100644
index 0000000..151648a
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/mock/MockShell.java
@@ -0,0 +1,143 @@
+/*
+ * 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.accumulo.shell.mock;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.charset.StandardCharsets;
+
+import jline.console.ConsoleReader;
+
+import org.apache.accumulo.core.client.mock.MockInstance;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.ShellOptionsJC;
+
+/**
+ * An Accumulo Shell implementation that allows a developer to attach an InputStream and Writer to the Shell for testing purposes.
+ */
+public class MockShell extends Shell {
+  private static final String NEWLINE = "\n";
+  
+  protected InputStream in;
+  protected OutputStream out;
+  
+  public MockShell(InputStream in, OutputStream out) throws IOException {
+    super();
+    this.in = in;
+    this.out = out;
+  }
+  
+  public boolean config(String... args) {
+    configError = super.config(args);
+    
+    // Update the ConsoleReader with the input and output "redirected"
+    try {
+      this.reader = new ConsoleReader(in, out);
+    } catch (Exception e) {
+      printException(e);
+      configError = true;
+    }
+    
+    // Don't need this for testing purposes
+    this.reader.setHistoryEnabled(false);
+    this.reader.setPaginationEnabled(false);
+    
+    // Make the parsing from the client easier;
+    this.verbose = false;
+    return configError;
+  }
+  
+  @Override
+  protected void setInstance(ShellOptionsJC options) {
+    // We always want a MockInstance for this test
+    instance = new MockInstance();
+  }
+  
+  public int start() throws IOException {
+    if (configError)
+      return 1;
+    
+    String input;
+    if (isVerbose())
+      printInfo();
+    
+    if (execFile != null) {
+      java.util.Scanner scanner = new java.util.Scanner(execFile, StandardCharsets.UTF_8.name());
+      try {
+        while (scanner.hasNextLine() && !hasExited()) {
+          execCommand(scanner.nextLine(), true, isVerbose());
+        }
+      } finally {
+        scanner.close();
+      }
+    } else if (execCommand != null) {
+      for (String command : execCommand.split("\n")) {
+        execCommand(command, true, isVerbose());
+      }
+      return exitCode;
+    }
+    
+    while (true) {
+      if (hasExited())
+        return exitCode;
+      
+      reader.setPrompt(getDefaultPrompt());
+      input = reader.readLine();
+      if (input == null) {
+        reader.println();
+        return exitCode;
+      } // user canceled
+      
+      execCommand(input, false, false);
+    }
+  }
+  
+  /**
+   * @param in
+   *          the in to set
+   */
+  public void setConsoleInputStream(InputStream in) {
+    this.in = in;
+  }
+  
+  /**
+   * @param out
+   *          the output stream to set
+   */
+  public void setConsoleWriter(OutputStream out) {
+    this.out = out;
+  }
+  
+  /**
+   * Convenience method to create the byte-array to hand to the console
+   * 
+   * @param commands
+   *          An array of commands to run
+   * @return A byte[] input stream which can be handed to the console.
+   */
+  public static ByteArrayInputStream makeCommands(String... commands) {
+    StringBuilder sb = new StringBuilder(commands.length * 8);
+    
+    for (String command : commands) {
+      sb.append(command).append(NEWLINE);
+    }
+    
+    return new ByteArrayInputStream(sb.toString().getBytes(StandardCharsets.UTF_8));
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/resources/.gitignore
----------------------------------------------------------------------
diff --git a/shell/src/main/resources/.gitignore b/shell/src/main/resources/.gitignore
new file mode 100644
index 0000000..e69de29

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/test/java/org/apache/accumulo/shell/PasswordConverterTest.java
----------------------------------------------------------------------
diff --git a/shell/src/test/java/org/apache/accumulo/shell/PasswordConverterTest.java b/shell/src/test/java/org/apache/accumulo/shell/PasswordConverterTest.java
new file mode 100644
index 0000000..8e03830
--- /dev/null
+++ b/shell/src/test/java/org/apache/accumulo/shell/PasswordConverterTest.java
@@ -0,0 +1,113 @@
+/*
+ * 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.accumulo.shell;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStreamWriter;
+import java.io.PipedInputStream;
+import java.io.PipedOutputStream;
+import java.util.Scanner;
+
+import org.apache.accumulo.shell.ShellOptionsJC.PasswordConverter;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import com.beust.jcommander.JCommander;
+import com.beust.jcommander.Parameter;
+import com.beust.jcommander.ParameterException;
+
+public class PasswordConverterTest {
+  
+  private class Password {
+    @Parameter(names = "--password", converter = PasswordConverter.class)
+    String password;
+  }
+  
+  private String[] argv;
+  private Password password;
+  private static InputStream realIn;
+  
+  @BeforeClass
+  public static void saveIn() {
+    realIn = System.in;
+  }
+  
+  @Before
+  public void setup() throws IOException {
+    argv = new String[] {"--password", ""};
+    password = new Password();
+    
+    PipedInputStream in = new PipedInputStream();
+    PipedOutputStream out = new PipedOutputStream(in);
+    OutputStreamWriter osw = new OutputStreamWriter(out);
+    osw.write("secret");
+    osw.close();
+    
+    System.setIn(in);
+  }
+  
+  @After
+  public void teardown() {
+    System.setIn(realIn);
+  }
+  
+  @Test
+  public void testPass() {
+    String expected = String.valueOf(Math.random());
+    argv[1] = "pass:" + expected;
+    new JCommander(password, argv);
+    assertEquals(expected, password.password);
+  }
+  
+  @Test
+  public void testEnv() {
+    String name = System.getenv().keySet().iterator().next();
+    argv[1] = "env:" + name;
+    new JCommander(password, argv);
+    assertEquals(System.getenv(name), password.password);
+  }
+  
+  @Test
+  public void testFile() throws FileNotFoundException {
+    argv[1] = "file:pom.xml";
+    Scanner scan = new Scanner(new File("pom.xml"));
+    String expected = scan.nextLine();
+    scan.close();
+    new JCommander(password, argv);
+    assertEquals(expected, password.password);
+  }
+  
+  @Test(expected=ParameterException.class)
+  public void testNoFile() throws FileNotFoundException {
+    argv[1] = "file:doesnotexist";
+    new JCommander(password, argv);
+  }
+
+  @Test
+  public void testStdin() {
+    argv[1] = "stdin";
+    new JCommander(password, argv);
+    assertEquals("stdin", password.password);
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/test/java/org/apache/accumulo/shell/ShellConfigTest.java
----------------------------------------------------------------------
diff --git a/shell/src/test/java/org/apache/accumulo/shell/ShellConfigTest.java b/shell/src/test/java/org/apache/accumulo/shell/ShellConfigTest.java
new file mode 100644
index 0000000..27f3247
--- /dev/null
+++ b/shell/src/test/java/org/apache/accumulo/shell/ShellConfigTest.java
@@ -0,0 +1,91 @@
+/*
+ * 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.accumulo.shell;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.io.FileDescriptor;
+import java.io.FileInputStream;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+
+import jline.console.ConsoleReader;
+
+import org.apache.accumulo.core.client.security.tokens.PasswordToken;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.ShellTest.TestOutputStream;
+import org.apache.log4j.Level;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.beust.jcommander.ParameterException;
+
+public class ShellConfigTest {
+  TestOutputStream output;
+  Shell shell;
+  PrintStream out;
+  
+  @Before
+  public void setUp() throws Exception {
+    Shell.log.setLevel(Level.ERROR);
+    
+    out = System.out;
+    output = new TestOutputStream();
+    System.setOut(new PrintStream(output));
+
+    shell = new Shell(new ConsoleReader(new FileInputStream(FileDescriptor.in), output), new PrintWriter(output));
+    shell.setLogErrorsToConsole();
+  }
+  
+  @After
+  public void teardown() throws Exception {
+    shell.shutdown();
+    output.clear();
+    System.setOut(out);
+  }
+  
+  @Test
+  public void testHelp() {
+    assertTrue(shell.config("--help"));
+    assertTrue("Did not print usage", output.get().startsWith("Usage"));
+  }
+  
+  @Test
+  public void testBadArg() {
+    assertTrue(shell.config("--bogus"));
+    assertTrue("Did not print usage", output.get().startsWith("Usage"));
+  }
+  
+  @Test
+  public void testToken() {
+    assertTrue(shell.config("--fake", "-tc", PasswordToken.class.getCanonicalName()));
+    assertTrue(output.get().contains(ParameterException.class.getCanonicalName()));
+  }
+  
+  @Test
+  public void testTokenAndOption() {
+    assertFalse(shell.config("--fake", "-tc", PasswordToken.class.getCanonicalName(), "-u", "foo", "-l", "password=foo"));
+  }
+  
+  @Test
+  public void testTokenAndOptionAndPassword() {
+    assertTrue(shell.config("--fake", "-tc", PasswordToken.class.getCanonicalName(), "-l", "password=foo", "-p", "bar"));
+    assertTrue(output.get().contains(ParameterException.class.getCanonicalName()));
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/test/java/org/apache/accumulo/shell/ShellSetInstanceTest.java
----------------------------------------------------------------------
diff --git a/shell/src/test/java/org/apache/accumulo/shell/ShellSetInstanceTest.java b/shell/src/test/java/org/apache/accumulo/shell/ShellSetInstanceTest.java
new file mode 100644
index 0000000..463f97d
--- /dev/null
+++ b/shell/src/test/java/org/apache/accumulo/shell/ShellSetInstanceTest.java
@@ -0,0 +1,244 @@
+/*
+ * 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.accumulo.shell;
+
+import static org.easymock.EasyMock.anyObject;
+import static org.easymock.EasyMock.expect;
+import static org.powermock.api.easymock.PowerMock.createMock;
+import static org.powermock.api.easymock.PowerMock.expectLastCall;
+import static org.powermock.api.easymock.PowerMock.expectNew;
+import static org.powermock.api.easymock.PowerMock.mockStatic;
+import static org.powermock.api.easymock.PowerMock.replay;
+import static org.powermock.api.easymock.PowerMock.verify;
+
+import java.io.FileDescriptor;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.util.Collections;
+import java.util.List;
+import java.util.UUID;
+
+import jline.console.ConsoleReader;
+
+import org.apache.accumulo.core.client.ClientConfiguration;
+import org.apache.accumulo.core.client.ClientConfiguration.ClientProperty;
+import org.apache.accumulo.core.client.ZooKeeperInstance;
+import org.apache.accumulo.core.client.mock.MockInstance;
+import org.apache.accumulo.core.conf.AccumuloConfiguration;
+import org.apache.accumulo.core.conf.ConfigSanityCheck;
+import org.apache.accumulo.core.conf.Property;
+import org.apache.accumulo.core.conf.SiteConfiguration;
+import org.apache.accumulo.core.zookeeper.ZooUtil;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.ShellOptionsJC;
+import org.apache.hadoop.fs.Path;
+import org.apache.log4j.Level;
+import org.easymock.EasyMock;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+@RunWith(PowerMockRunner.class)
+@PrepareForTest({Shell.class, ZooUtil.class, ConfigSanityCheck.class})
+public class ShellSetInstanceTest {
+  public static class TestOutputStream extends OutputStream {
+    StringBuilder sb = new StringBuilder();
+
+    @Override
+    public void write(int b) throws IOException {
+      sb.append((char) (0xff & b));
+    }
+
+    public String get() {
+      return sb.toString();
+    }
+
+    public void clear() {
+      sb.setLength(0);
+    }
+  }
+
+  @BeforeClass
+  public static void setupClass() {
+    // This is necessary because PowerMock messes with Hadoop's ability to
+    // determine the current user (see security.UserGroupInformation).
+    System.setProperty("HADOOP_USER_NAME", "test");
+  }
+  @AfterClass
+  public static void teardownClass() {
+    System.clearProperty("HADOOP_USER_NAME");
+  }
+
+  private TestOutputStream output;
+  private Shell shell;
+
+  @Before
+  public void setup() throws IOException {
+    Shell.log.setLevel(Level.OFF);
+    output = new TestOutputStream();
+    shell = new Shell(new ConsoleReader(new FileInputStream(FileDescriptor.in), output), new PrintWriter(output));
+    shell.setLogErrorsToConsole();
+  }
+  @After
+  public void tearDown() {
+    shell.shutdown();
+    SiteConfiguration.clearInstance();
+  }
+
+  @Test
+  public void testSetInstance_Fake() throws Exception {
+    ShellOptionsJC opts = createMock(ShellOptionsJC.class);
+    expect(opts.isFake()).andReturn(true);
+    replay(opts);
+    MockInstance theInstance = createMock(MockInstance.class);
+    expectNew(MockInstance.class, "fake").andReturn(theInstance);
+    replay(theInstance, MockInstance.class);
+
+    shell.setInstance(opts);
+    verify(theInstance, MockInstance.class);
+  }
+  @Test
+  public void testSetInstance_HdfsZooInstance_Explicit() throws Exception {
+    testSetInstance_HdfsZooInstance(true, false, false);
+  }
+  @Test
+  public void testSetInstance_HdfsZooInstance_InstanceGiven() throws Exception {
+    testSetInstance_HdfsZooInstance(false, true, false);
+  }
+  @Test
+  public void testSetInstance_HdfsZooInstance_HostsGiven() throws Exception {
+    testSetInstance_HdfsZooInstance(false, false, true);
+  }
+  @Test
+  public void testSetInstance_HdfsZooInstance_Implicit() throws Exception {
+    testSetInstance_HdfsZooInstance(false, false, false);
+  }
+  
+  @SuppressWarnings("deprecation")
+  private void testSetInstance_HdfsZooInstance(boolean explicitHdfs, boolean onlyInstance, boolean onlyHosts)
+    throws Exception {
+    ClientConfiguration clientConf = createMock(ClientConfiguration.class);
+    ShellOptionsJC opts = createMock(ShellOptionsJC.class);
+    expect(opts.isFake()).andReturn(false);
+    expect(opts.getClientConfiguration()).andReturn(clientConf);
+    expect(opts.isHdfsZooInstance()).andReturn(explicitHdfs);
+    if (!explicitHdfs) {
+      expect(opts.getZooKeeperInstance())
+        .andReturn(Collections.<String>emptyList());
+      if (onlyInstance) {
+        expect(opts.getZooKeeperInstanceName()).andReturn("instance");
+        expect(clientConf.withInstance("instance")).andReturn(clientConf);
+      } else {
+        expect(opts.getZooKeeperInstanceName()).andReturn(null);
+      }
+      if (onlyHosts) {
+        expect(opts.getZooKeeperHosts()).andReturn("host3,host4");
+        expect(clientConf.withZkHosts("host3,host4")).andReturn(clientConf);
+      } else {
+        expect(opts.getZooKeeperHosts()).andReturn(null);
+      }
+    }
+    replay(opts);
+
+    if (!onlyInstance) {
+      expect(clientConf.get(ClientProperty.INSTANCE_NAME)).andReturn(null);
+    }
+
+    mockStatic(ConfigSanityCheck.class);
+    ConfigSanityCheck.validate(EasyMock.<AccumuloConfiguration>anyObject());
+    expectLastCall().atLeastOnce();
+    replay(ConfigSanityCheck.class);
+
+    if (!onlyHosts) {
+      expect(clientConf.containsKey(Property.INSTANCE_ZK_HOST.getKey())).andReturn(true).atLeastOnce();
+      expect(clientConf.getString(Property.INSTANCE_ZK_HOST.getKey())).andReturn("host1,host2").atLeastOnce();
+      expect(clientConf.withZkHosts("host1,host2")).andReturn(clientConf);
+    }
+    if (!onlyInstance) {
+      expect(clientConf.containsKey(Property.INSTANCE_VOLUMES.getKey())).andReturn(false).atLeastOnce();
+      expect(clientConf.containsKey(Property.INSTANCE_DFS_DIR.getKey())).andReturn(true).atLeastOnce();
+      expect(clientConf.containsKey(Property.INSTANCE_DFS_URI.getKey())).andReturn(true).atLeastOnce();
+      expect(clientConf.getString(Property.INSTANCE_DFS_URI.getKey())).andReturn("hdfs://nn1").atLeastOnce();
+      expect(clientConf.getString(Property.INSTANCE_DFS_DIR.getKey())).andReturn("/dfs").atLeastOnce();
+    }
+
+    UUID randomUUID = null;
+    if (!onlyInstance) {
+      mockStatic(ZooUtil.class);
+      randomUUID = UUID.randomUUID();
+      expect(ZooUtil.getInstanceIDFromHdfs(anyObject(Path.class), anyObject(AccumuloConfiguration.class)))
+        .andReturn(randomUUID.toString());
+      replay(ZooUtil.class);
+      expect(clientConf.withInstance(randomUUID)).andReturn(clientConf);
+    }
+    replay(clientConf);
+
+    ZooKeeperInstance theInstance = createMock(ZooKeeperInstance.class);
+    
+    expectNew(ZooKeeperInstance.class, clientConf).andReturn(theInstance);
+    replay(theInstance, ZooKeeperInstance.class);
+
+    shell.setInstance(opts);
+    verify(theInstance, ZooKeeperInstance.class);
+  }
+  @Test
+  public void testSetInstance_ZKInstance_DashZ() throws Exception {
+    testSetInstance_ZKInstance(true);
+  }
+  @Test
+  public void testSetInstance_ZKInstance_DashZIandZH() throws Exception {
+    testSetInstance_ZKInstance(false);
+  }
+  private void testSetInstance_ZKInstance(boolean dashZ) throws Exception {
+    ClientConfiguration clientConf = createMock(ClientConfiguration.class);
+    ShellOptionsJC opts = createMock(ShellOptionsJC.class);
+    expect(opts.isFake()).andReturn(false);
+    expect(opts.getClientConfiguration()).andReturn(clientConf);
+    expect(opts.isHdfsZooInstance()).andReturn(false);
+    if (dashZ) {
+      expect(clientConf.withInstance("foo")).andReturn(clientConf);
+      expect(clientConf.withZkHosts("host1,host2")).andReturn(clientConf);
+      List<String> zl = new java.util.ArrayList<String>();
+      zl.add("foo");
+      zl.add("host1,host2");
+      expect(opts.getZooKeeperInstance()).andReturn(zl);
+      expectLastCall().anyTimes();
+    } else {
+      expect(clientConf.withInstance("bar")).andReturn(clientConf);
+      expect(clientConf.withZkHosts("host3,host4")).andReturn(clientConf);
+      expect(opts.getZooKeeperInstance()).andReturn(Collections.<String>emptyList());
+      expect(opts.getZooKeeperInstanceName()).andReturn("bar");
+      expect(opts.getZooKeeperHosts()).andReturn("host3,host4");
+    }
+    replay(clientConf);
+    replay(opts);
+
+    ZooKeeperInstance theInstance = createMock(ZooKeeperInstance.class);
+    expectNew(ZooKeeperInstance.class, clientConf).andReturn(theInstance);
+    replay(theInstance, ZooKeeperInstance.class);
+
+    shell.setInstance(opts);
+    verify(theInstance, ZooKeeperInstance.class);
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/test/java/org/apache/accumulo/shell/ShellTest.java
----------------------------------------------------------------------
diff --git a/shell/src/test/java/org/apache/accumulo/shell/ShellTest.java b/shell/src/test/java/org/apache/accumulo/shell/ShellTest.java
new file mode 100644
index 0000000..ef12baa
--- /dev/null
+++ b/shell/src/test/java/org/apache/accumulo/shell/ShellTest.java
@@ -0,0 +1,282 @@
+/*
+ * 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.accumulo.shell;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.TimeZone;
+
+import jline.console.ConsoleReader;
+
+import org.apache.accumulo.core.util.format.DateStringFormatter;
+import org.apache.accumulo.shell.Shell;
+import org.apache.log4j.Level;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class ShellTest {
+  public static class TestOutputStream extends OutputStream {
+    StringBuilder sb = new StringBuilder();
+
+    @Override
+    public void write(int b) throws IOException {
+      sb.append((char) (0xff & b));
+    }
+
+    public String get() {
+      return sb.toString();
+    }
+
+    public void clear() {
+      sb.setLength(0);
+    }
+  }
+
+  public static class StringInputStream extends InputStream {
+    private String source = "";
+    private int offset = 0;
+
+    @Override
+    public int read() throws IOException {
+      if (offset == source.length())
+        return '\n';
+      else
+        return source.charAt(offset++);
+    }
+
+    public void set(String other) {
+      source = other;
+      offset = 0;
+    }
+  }
+
+  private StringInputStream input;
+  private TestOutputStream output;
+  private Shell shell;
+
+  void exec(String cmd) throws IOException {
+    output.clear();
+    shell.execCommand(cmd, true, true);
+  }
+
+  void exec(String cmd, boolean expectGoodExit) throws IOException {
+    exec(cmd);
+    if (expectGoodExit)
+      assertGoodExit("", true);
+    else
+      assertBadExit("", true);
+  }
+
+  void exec(String cmd, boolean expectGoodExit, String expectString) throws IOException {
+    exec(cmd, expectGoodExit, expectString, true);
+  }
+
+  void exec(String cmd, boolean expectGoodExit, String expectString, boolean stringPresent) throws IOException {
+    exec(cmd);
+    if (expectGoodExit)
+      assertGoodExit(expectString, stringPresent);
+    else
+      assertBadExit(expectString, stringPresent);
+  }
+
+  @Before
+  public void setup() throws IOException {
+    TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
+    Shell.log.setLevel(Level.OFF);
+    output = new TestOutputStream();
+    input = new StringInputStream();
+    PrintWriter pw = new PrintWriter(new OutputStreamWriter(output));
+    shell = new Shell(new ConsoleReader(input, output), pw);
+    shell.setLogErrorsToConsole();
+    shell.config("--fake", "-u", "test", "-p", "secret");
+  }
+
+  @After
+  public void teardown() {
+    shell.shutdown();
+  }
+
+  void assertGoodExit(String s, boolean stringPresent) {
+    Shell.log.debug(output.get());
+    assertEquals(shell.getExitCode(), 0);
+    if (s.length() > 0)
+      assertEquals(s + " present in " + output.get() + " was not " + stringPresent, stringPresent, output.get().contains(s));
+  }
+
+  void assertBadExit(String s, boolean stringPresent) {
+    Shell.log.debug(output.get());
+    assertTrue(shell.getExitCode() > 0);
+    if (s.length() > 0)
+      assertEquals(s + " present in " + output.get() + " was not " + stringPresent, stringPresent, output.get().contains(s));
+    shell.resetExitCode();
+  }
+
+  @Test
+  public void aboutTest() throws IOException {
+    Shell.log.debug("Starting about test -----------------------------------");
+    exec("about", true, "Shell - Apache Accumulo Interactive Shell");
+    exec("about -v", true, "Current user:");
+    exec("about arg", false, "java.lang.IllegalArgumentException: Expected 0 arguments");
+  }
+
+  @Test
+  public void addGetSplitsTest() throws IOException {
+    Shell.log.debug("Starting addGetSplits test ----------------------------");
+    exec("addsplits arg", false, "java.lang.IllegalStateException: Not in a table context");
+    exec("createtable test", true);
+    exec("addsplits 1 \\x80", true);
+    exec("getsplits", true, "1\n\\x80");
+    exec("deletetable test -f", true, "Table: [test] has been deleted");
+  }
+
+  @Test
+  public void insertDeleteScanTest() throws IOException {
+    Shell.log.debug("Starting insertDeleteScan test ------------------------");
+    exec("insert r f q v", false, "java.lang.IllegalStateException: Not in a table context");
+    exec("delete r f q", false, "java.lang.IllegalStateException: Not in a table context");
+    exec("createtable test", true);
+    exec("insert r f q v", true);
+    exec("scan", true, "r f:q []    v");
+    exec("delete r f q", true);
+    exec("scan", true, "r f:q []    v", false);
+    exec("insert \\x90 \\xa0 \\xb0 \\xc0\\xd0\\xe0\\xf0", true);
+    exec("scan", true, "\\x90 \\xA0:\\xB0 []    \\xC0\\xD0");
+    exec("scan -f 2", true, "\\x90 \\xA0:\\xB0 []    \\xC0\\xD0");
+    exec("scan -f 2", true, "\\x90 \\xA0:\\xB0 []    \\xC0\\xD0\\xE0", false);
+    exec("scan -b \\x90 -e \\x90 -c \\xA0", true, "\\x90 \\xA0:\\xB0 []    \\xC0");
+    exec("scan -b \\x90 -e \\x90 -c \\xA0:\\xB0", true, "\\x90 \\xA0:\\xB0 []    \\xC0");
+    exec("scan -b \\x90 -be", true, "\\x90 \\xA0:\\xB0 []    \\xC0", false);
+    exec("scan -e \\x90 -ee", true, "\\x90 \\xA0:\\xB0 []    \\xC0", false);
+    exec("scan -b \\x90\\x00", true, "\\x90 \\xA0:\\xB0 []    \\xC0", false);
+    exec("scan -e \\x8f", true, "\\x90 \\xA0:\\xB0 []    \\xC0", false);
+    exec("delete \\x90 \\xa0 \\xb0", true);
+    exec("scan", true, "\\x90 \\xA0:\\xB0 []    \\xC0", false);
+    exec("deletetable test -f", true, "Table: [test] has been deleted");
+  }
+
+  @Test
+  public void authsTest() throws Exception {
+    Shell.log.debug("Starting auths test --------------------------");
+    exec("setauths x,y,z", false, "Missing required option");
+    exec("setauths -s x,y,z -u notauser", false, "user does not exist");
+    exec("setauths -s y,z,x", true);
+    exec("getauths -u notauser", false, "user does not exist");
+    exec("getauths", true, "x,y,z");
+    exec("addauths -u notauser", false, "Missing required option");
+    exec("addauths -u notauser -s foo", false, "user does not exist");
+    exec("addauths -s a", true);
+    exec("getauths", true, "a,x,y,z");
+    exec("setauths -c", true);
+  }
+
+  @Test
+  public void userTest() throws Exception {
+    Shell.log.debug("Starting user test --------------------------");
+    // Test cannot be done via junit because createuser only prompts for password
+    // exec("createuser root", false, "user exists");
+  }
+
+  @Test
+  public void duContextTest() throws Exception {
+    Shell.log.debug("Starting du context test --------------------------");
+    exec("createtable t", true);
+    exec("du", true, "0 [t]");
+    exec("deletetable t -f", true, "Table: [t] has been deleted");
+  }
+
+  @Test
+  public void duTest() throws IOException {
+    Shell.log.debug("Starting DU test --------------------------");
+    exec("createtable t", true);
+    exec("du t", true, "0 [t]");
+    exec("deletetable t -f", true, "Table: [t] has been deleted");
+  }
+
+  @Test
+  public void duPatternTest() throws IOException {
+    Shell.log.debug("Starting DU with pattern test --------------------------");
+    exec("createtable t", true);
+    exec("createtable tt", true);
+    exec("du -p t.*", true, "0 [t, tt]");
+    exec("deletetable t -f", true, "Table: [t] has been deleted");
+    exec("deletetable tt -f", true, "Table: [tt] has been deleted");
+  }
+
+  @Test
+  public void scanDateStringFormatterTest() throws IOException {
+    Shell.log.debug("Starting scan dateStringFormatter test --------------------------");
+    exec("createtable t", true);
+    exec("insert r f q v -ts 0", true);
+    DateFormat dateFormat = new SimpleDateFormat(DateStringFormatter.DATE_FORMAT);
+    String expected = String.format("r f:q [] %s    v", dateFormat.format(new Date(0)));
+    exec("scan -fm org.apache.accumulo.core.util.format.DateStringFormatter -st", true, expected);
+    exec("deletetable t -f", true, "Table: [t] has been deleted");
+  }
+
+  @Test
+  public void commentTest() throws IOException {
+    Shell.log.debug("Starting comment test --------------------------");
+    exec("#", true, "Unknown command", false);
+    exec("# foo", true, "Unknown command", false);
+    exec("- foo", true, "Unknown command", true);
+  }
+
+  @Test
+  public void execFileTest() throws IOException {
+    Shell.log.debug("Starting exec file test --------------------------");
+    shell.config("--fake", "-u", "test", "-p", "secret", "-f", "src/test/resources/shelltest.txt");
+    assertEquals(0, shell.start());
+    assertGoodExit("Unknown command", false);
+  }
+
+  @Test
+  public void setIterTest() throws IOException {
+    Shell.log.debug("Starting setiter test --------------------------");
+    exec("createtable t", true);
+
+    String cmdJustClass = "setiter -class VersioningIterator -p 1";
+    exec(cmdJustClass, false, "java.lang.IllegalArgumentException", false);
+    exec(cmdJustClass, false, "fully qualified package name", true);
+
+    String cmdFullPackage = "setiter -class o.a.a.foo -p 1";
+    exec(cmdFullPackage, false, "java.lang.IllegalArgumentException", false);
+    exec(cmdFullPackage, false, "class not found", true);
+
+    String cmdNoOption = "setiter -class java.lang.String -p 1";
+    exec(cmdNoOption, false, "loaded successfully but does not implement SortedKeyValueIterator", true);
+
+    input.set("\n\n");
+    exec("setiter -scan -class org.apache.accumulo.core.iterators.ColumnFamilyCounter -p 30 -name foo", true);
+    
+    input.set("bar\nname value\n");
+    exec("setiter -scan -class org.apache.accumulo.core.iterators.ColumnFamilyCounter -p 31", true);
+    
+    //TODO can't verify this as config -t fails, functionality verified in ShellServerIT
+    
+    exec("deletetable t -f", true, "Table: [t] has been deleted");
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/test/java/org/apache/accumulo/shell/ShellUtilTest.java
----------------------------------------------------------------------
diff --git a/shell/src/test/java/org/apache/accumulo/shell/ShellUtilTest.java b/shell/src/test/java/org/apache/accumulo/shell/ShellUtilTest.java
new file mode 100644
index 0000000..4e99336
--- /dev/null
+++ b/shell/src/test/java/org/apache/accumulo/shell/ShellUtilTest.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.accumulo.shell;
+
+import static org.junit.Assert.*;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.util.List;
+
+import org.apache.accumulo.shell.ShellUtil;
+import org.apache.commons.codec.binary.Base64;
+import org.apache.commons.io.FileUtils;
+import org.apache.hadoop.io.Text;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+
+import com.google.common.collect.ImmutableList;
+
+public class ShellUtilTest {
+
+  @Rule
+  public TemporaryFolder folder = new TemporaryFolder(new File(System.getProperty("user.dir") + "/target"));
+
+  // String with 3 lines, with one empty line
+  private static final String FILEDATA = "line1\n\nline2";
+
+  @Test
+  public void testWithoutDecode() throws IOException {
+    File testFile = new File(folder.getRoot(), "testFileNoDecode.txt");
+    FileUtils.writeStringToFile(testFile, FILEDATA);
+    List<Text> output = ShellUtil.scanFile(testFile.getAbsolutePath(), false);
+    assertEquals(ImmutableList.of(new Text("line1"), new Text("line2")), output);
+  }
+
+  @Test
+  public void testWithDecode() throws IOException {
+    File testFile = new File(folder.getRoot(), "testFileWithDecode.txt");
+    FileUtils.writeStringToFile(testFile, FILEDATA);
+    List<Text> output = ShellUtil.scanFile(testFile.getAbsolutePath(), true);
+    assertEquals(
+        ImmutableList.of(new Text(Base64.decodeBase64("line1".getBytes(StandardCharsets.UTF_8))), new Text(Base64.decodeBase64("line2".getBytes(StandardCharsets.UTF_8)))),
+        output);
+  }
+
+  @Test(expected = FileNotFoundException.class)
+  public void testWithMissingFile() throws FileNotFoundException {
+    ShellUtil.scanFile("missingFile.txt", false);
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/test/java/org/apache/accumulo/shell/command/FormatterCommandTest.java
----------------------------------------------------------------------
diff --git a/shell/src/test/java/org/apache/accumulo/shell/command/FormatterCommandTest.java b/shell/src/test/java/org/apache/accumulo/shell/command/FormatterCommandTest.java
new file mode 100644
index 0000000..203f08f
--- /dev/null
+++ b/shell/src/test/java/org/apache/accumulo/shell/command/FormatterCommandTest.java
@@ -0,0 +1,184 @@
+/*
+ * 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.accumulo.shell.command;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Iterator;
+import java.util.Map.Entry;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.TableExistsException;
+import org.apache.accumulo.core.data.Key;
+import org.apache.accumulo.core.data.Value;
+import org.apache.accumulo.core.util.format.Formatter;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.mock.MockShell;
+import org.apache.log4j.Level;
+import org.apache.log4j.Logger;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * Uses the MockShell to test the shell output with Formatters
+ */
+public class FormatterCommandTest {
+  ByteArrayOutputStream out = null;
+  InputStream in = null;
+  
+  @Test
+  public void test() throws IOException, AccumuloException, AccumuloSecurityException, TableExistsException, ClassNotFoundException {
+    // Keep the Shell AUDIT log off the test output
+    Logger.getLogger(Shell.class).setLevel(Level.WARN);
+    
+    final String[] args = new String[] {"--fake", "-u", "root", "-p", ""};
+    
+    final String[] commands = createCommands();
+    
+    in = MockShell.makeCommands(commands);
+    out = new ByteArrayOutputStream();
+    
+    final MockShell shell = new MockShell(in, out);
+    shell.config(args);
+    
+    // Can't call createtable in the shell with MockAccumulo
+    shell.getConnector().tableOperations().create("test");
+    
+    try {
+      shell.start();
+    } catch (Exception e) {
+      Assert.fail("Exception while running commands: " + e.getMessage());
+    }
+    
+    shell.getReader().flush();
+    
+    final String[] output = new String(out.toByteArray()).split("\n\r");
+    
+    boolean formatterOn = false;
+    
+    final String[] expectedDefault = new String[] {"row cf:cq []    1234abcd", "row cf1:cq1 []    9876fedc", "row2 cf:cq []    13579bdf",
+        "row2 cf1:cq []    2468ace"};
+    
+    final String[] expectedFormatted = new String[] {"row cf:cq []    0x31 0x32 0x33 0x34 0x61 0x62 0x63 0x64",
+        "row cf1:cq1 []    0x39 0x38 0x37 0x36 0x66 0x65 0x64 0x63", "row2 cf:cq []    0x31 0x33 0x35 0x37 0x39 0x62 0x64 0x66",
+        "row2 cf1:cq []    0x32 0x34 0x36 0x38 0x61 0x63 0x65"};
+    
+    int outputIndex = 0;
+    while (outputIndex < output.length) {
+      final String line = output[outputIndex];
+      
+      if (line.startsWith("root@mock-instance")) {
+        if (line.contains("formatter")) {
+          formatterOn = true;
+        }
+        
+        outputIndex++;
+      } else if (line.startsWith("row")) {
+        int expectedIndex = 0;
+        String[] comparisonData;
+        
+        // Pick the type of data we expect (formatted or default)
+        if (formatterOn) {
+          comparisonData = expectedFormatted;
+        } else {
+          comparisonData = expectedDefault;
+        }
+        
+        // Ensure each output is what we expected
+        while (expectedIndex + outputIndex < output.length && expectedIndex < expectedFormatted.length) {
+          Assert.assertEquals(comparisonData[expectedIndex].trim(), output[expectedIndex + outputIndex].trim());
+          expectedIndex++;
+        }
+        
+        outputIndex += expectedIndex;
+      }
+    }
+  }
+  
+  private String[] createCommands() {
+    return new String[] {"table test", "insert row cf cq 1234abcd", "insert row cf1 cq1 9876fedc", "insert row2 cf cq 13579bdf", "insert row2 cf1 cq 2468ace",
+        "scan", "formatter -t test -f org.apache.accumulo.core.util.shell.command.FormatterCommandTest$HexFormatter", "scan"};
+  }
+  
+  /**
+   * <p>
+   * Simple <code>Formatter</code> that will convert each character in the Value from decimal to hexadecimal. Will automatically skip over characters in the
+   * value which do not fall within the [0-9,a-f] range.
+   * </p>
+   * 
+   * <p>
+   * Example: <code>'0'</code> will be displayed as <code>'0x30'</code>
+   * </p>
+   */
+  public static class HexFormatter implements Formatter {
+    private Iterator<Entry<Key,Value>> iter = null;
+    private boolean printTs = false;
+    
+    private final static String tab = "\t";
+    private final static String newline = "\n";
+    
+    public HexFormatter() {}
+    
+    @Override
+    public boolean hasNext() {
+      return this.iter.hasNext();
+    }
+    
+    @Override
+    public String next() {
+      final Entry<Key,Value> entry = iter.next();
+      
+      String key;
+      
+      // Observe the timestamps
+      if (printTs) {
+        key = entry.getKey().toString();
+      } else {
+        key = entry.getKey().toStringNoTime();
+      }
+      
+      final Value v = entry.getValue();
+      
+      // Approximate how much space we'll need
+      final StringBuilder sb = new StringBuilder(key.length() + v.getSize() * 5);
+      
+      sb.append(key).append(tab);
+      
+      for (byte b : v.get()) {
+        if ((b >= 48 && b <= 57) || (b >= 97 || b <= 102)) {
+          sb.append(String.format("0x%x ", Integer.valueOf(b)));
+        }
+      }
+      
+      sb.append(newline);
+      
+      return sb.toString();
+    }
+    
+    @Override
+    public void remove() {}
+    
+    @Override
+    public void initialize(final Iterable<Entry<Key,Value>> scanner, final boolean printTimestamps) {
+      this.iter = scanner.iterator();
+      this.printTs = printTimestamps;
+    }
+  }
+  
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/test/java/org/apache/accumulo/shell/format/DeleterFormatterTest.java
----------------------------------------------------------------------
diff --git a/shell/src/test/java/org/apache/accumulo/shell/format/DeleterFormatterTest.java b/shell/src/test/java/org/apache/accumulo/shell/format/DeleterFormatterTest.java
new file mode 100644
index 0000000..e5b7394
--- /dev/null
+++ b/shell/src/test/java/org/apache/accumulo/shell/format/DeleterFormatterTest.java
@@ -0,0 +1,177 @@
+/*
+ * 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.accumulo.shell.format;
+
+import static org.easymock.EasyMock.anyObject;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.createNiceMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.expectLastCall;
+import static org.easymock.EasyMock.replay;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+import java.util.Collections;
+import java.util.Map;
+import java.util.TreeMap;
+
+import jline.UnsupportedTerminal;
+import jline.console.ConsoleReader;
+
+import org.apache.accumulo.core.client.BatchWriter;
+import org.apache.accumulo.core.client.MutationsRejectedException;
+import org.apache.accumulo.core.data.Key;
+import org.apache.accumulo.core.data.Mutation;
+import org.apache.accumulo.core.data.Value;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.format.DeleterFormatter;
+import org.junit.Before;
+import org.junit.Test;
+
+public class DeleterFormatterTest {
+  DeleterFormatter formatter;
+  Map<Key,Value> data;
+  BatchWriter writer;
+  BatchWriter exceptionWriter;
+  Shell shellState;
+
+  ByteArrayOutputStream baos;
+  ConsoleReader reader;
+
+  SettableInputStream input;
+
+  class SettableInputStream extends InputStream {
+    ByteArrayInputStream bais;
+
+    @Override
+    public int read() throws IOException {
+      return bais.read();
+    }
+
+    public void set(String in) {
+      bais = new ByteArrayInputStream(in.getBytes(StandardCharsets.UTF_8));
+    }
+  };
+
+  @Before
+  public void setUp() throws IOException, MutationsRejectedException {
+    input = new SettableInputStream();
+    baos = new ByteArrayOutputStream();
+
+    MutationsRejectedException mre = createMock(MutationsRejectedException.class);
+
+    writer = createNiceMock(BatchWriter.class);
+    exceptionWriter = createNiceMock(BatchWriter.class);
+    exceptionWriter.close();
+    expectLastCall().andThrow(mre);
+    exceptionWriter.addMutation(anyObject(Mutation.class));
+    expectLastCall().andThrow(mre);
+
+    shellState = createNiceMock(Shell.class);
+
+    reader = new ConsoleReader(input, baos, new UnsupportedTerminal());
+    expect(shellState.getReader()).andReturn(reader).anyTimes();
+
+    replay(writer, exceptionWriter, shellState);
+
+    data = new TreeMap<Key,Value>();
+    data.put(new Key("r", "cf", "cq"), new Value("value".getBytes(StandardCharsets.UTF_8)));
+  }
+
+  @Test
+  public void testEmpty() {
+    formatter = new DeleterFormatter(writer, Collections.<Key,Value> emptyMap().entrySet(), true, shellState, true);
+    assertFalse(formatter.hasNext());
+  }
+
+  @Test
+  public void testSingle() throws IOException {
+    formatter = new DeleterFormatter(writer, data.entrySet(), true, shellState, true);
+
+    assertTrue(formatter.hasNext());
+    assertNull(formatter.next());
+
+    verify("[DELETED]", " r ", "cf", "cq", "value");
+  }
+
+  @Test
+  public void testNo() throws IOException {
+    input.set("no\n");
+    data.put(new Key("z"), new Value("v2".getBytes(StandardCharsets.UTF_8)));
+    formatter = new DeleterFormatter(writer, data.entrySet(), true, shellState, false);
+
+    assertTrue(formatter.hasNext());
+    assertNull(formatter.next());
+
+    verify("[SKIPPED]", " r ", "cf", "cq", "value");
+
+    assertTrue(formatter.hasNext());
+  }
+
+  @Test
+  public void testNoConfirmation() throws IOException {
+    input.set("");
+    data.put(new Key("z"), new Value("v2".getBytes(StandardCharsets.UTF_8)));
+    formatter = new DeleterFormatter(writer, data.entrySet(), true, shellState, false);
+
+    assertTrue(formatter.hasNext());
+    assertNull(formatter.next());
+
+    verify("[SKIPPED]", " r ", "cf", "cq", "value");
+
+    assertFalse(formatter.hasNext());
+  }
+
+  @Test
+  public void testYes() throws IOException {
+    input.set("y\nyes\n");
+    data.put(new Key("z"), new Value("v2".getBytes(StandardCharsets.UTF_8)));
+    formatter = new DeleterFormatter(writer, data.entrySet(), true, shellState, false);
+
+    assertTrue(formatter.hasNext());
+    assertNull(formatter.next());
+    verify("[DELETED]", " r ", "cf", "cq", "value");
+
+    assertTrue(formatter.hasNext());
+    assertNull(formatter.next());
+    verify("[DELETED]", " z ", "v2");
+  }
+
+  @Test
+  public void testMutationException() {
+    formatter = new DeleterFormatter(exceptionWriter, data.entrySet(), true, shellState, true);
+
+    assertTrue(formatter.hasNext());
+    assertNull(formatter.next());
+    assertFalse(formatter.hasNext());
+  }
+
+  private void verify(String... chunks) throws IOException {
+    reader.flush();
+
+    String output = baos.toString();
+    for (String chunk : chunks) {
+      assertTrue(output.contains(chunk));
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/test/resources/log4j.properties
----------------------------------------------------------------------
diff --git a/shell/src/test/resources/log4j.properties b/shell/src/test/resources/log4j.properties
new file mode 100644
index 0000000..9f968f8
--- /dev/null
+++ b/shell/src/test/resources/log4j.properties
@@ -0,0 +1,28 @@
+# 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.
+
+log4j.rootLogger=INFO, CA
+log4j.appender.CA=org.apache.log4j.ConsoleAppender
+log4j.appender.CA.layout=org.apache.log4j.PatternLayout
+log4j.appender.CA.layout.ConversionPattern=[%t] %-5p %c %x - %m%n
+
+log4j.logger.org.apache.accumulo.core.iterators.system.VisibilityFilter=FATAL
+log4j.logger.org.apache.accumulo.core.iterators.user.TransformingIteratorTest$IllegalVisCompactionKeyTransformingIterator=FATAL
+log4j.logger.org.apache.accumulo.core.iterators.user.TransformingIteratorTest$IllegalVisKeyTransformingIterator=FATAL
+log4j.logger.org.apache.commons.vfs2.impl.DefaultFileSystemManager=WARN
+log4j.logger.org.apache.hadoop.mapred=ERROR
+log4j.logger.org.apache.hadoop.mapreduce.lib.output.FileOutputCommitter=ERROR
+log4j.logger.org.apache.hadoop.util.ProcessTree=ERROR
+log4j.logger.org.apache.accumulo.core.util.format=FATAL

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/test/resources/shelltest.txt
----------------------------------------------------------------------
diff --git a/shell/src/test/resources/shelltest.txt b/shell/src/test/resources/shelltest.txt
new file mode 100644
index 0000000..19b6f61
--- /dev/null
+++ b/shell/src/test/resources/shelltest.txt
@@ -0,0 +1,16 @@
+# 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.
+exit
+foo

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/start/src/main/java/org/apache/accumulo/start/Main.java
----------------------------------------------------------------------
diff --git a/start/src/main/java/org/apache/accumulo/start/Main.java b/start/src/main/java/org/apache/accumulo/start/Main.java
index 3c7da95..f34cd30 100644
--- a/start/src/main/java/org/apache/accumulo/start/Main.java
+++ b/start/src/main/java/org/apache/accumulo/start/Main.java
@@ -54,7 +54,7 @@ public class Main {
       } else if (args[0].equals("tserver")) {
         runTMP = cl.loadClass("org.apache.accumulo.tserver.TabletServer");
       } else if (args[0].equals("shell")) {
-        runTMP = cl.loadClass("org.apache.accumulo.core.util.shell.Shell");
+        runTMP = cl.loadClass("org.apache.accumulo.shell.Shell");
       } else if (args[0].equals("init")) {
         runTMP = cl.loadClass("org.apache.accumulo.server.init.Initialize");
       } else if (args[0].equals("admin")) {

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/test/src/test/java/org/apache/accumulo/test/ShellServerIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/accumulo/test/ShellServerIT.java b/test/src/test/java/org/apache/accumulo/test/ShellServerIT.java
index b3d44e3..bff8c3a 100644
--- a/test/src/test/java/org/apache/accumulo/test/ShellServerIT.java
+++ b/test/src/test/java/org/apache/accumulo/test/ShellServerIT.java
@@ -56,7 +56,7 @@ import org.apache.accumulo.core.metadata.MetadataTable;
 import org.apache.accumulo.core.metadata.RootTable;
 import org.apache.accumulo.core.security.Authorizations;
 import org.apache.accumulo.core.util.UtilWaitThread;
-import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.shell.Shell;
 import org.apache.accumulo.test.functional.FunctionalTestUtils;
 import org.apache.accumulo.test.functional.SimpleMacIT;
 import org.apache.accumulo.test.functional.SlowIterator;


[43/53] [abbrv] ACCUMULO-1879 Move shell into new package and module

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/FormatterCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/FormatterCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/FormatterCommand.java
deleted file mode 100644
index 631c6e6..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/FormatterCommand.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.accumulo.core.util.shell.commands;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.conf.Property;
-import org.apache.accumulo.core.util.format.Formatter;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-
-public class FormatterCommand extends ShellPluginConfigurationCommand {
-  
-  private Option interpeterOption;
-
-  public FormatterCommand() {
-    super("formatter", Property.TABLE_FORMATTER_CLASS, "f");
-  }
-
-  @Override
-  public String description() {
-    return "specifies a formatter to use for displaying table entries";
-  }
-
-  public static Class<? extends Formatter> getCurrentFormatter(final String tableName, final Shell shellState) {
-    return ShellPluginConfigurationCommand.getPluginClass(tableName, shellState, Formatter.class, Property.TABLE_FORMATTER_CLASS);
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options options = super.getOptions();
-    
-    interpeterOption = new Option("i", "interpeter", false, "configure class as interpreter also");
-    
-    options.addOption(interpeterOption);
-    
-    return options;
-  }
-  
-  protected void setPlugin(final CommandLine cl, final Shell shellState, final String tableName, final String className) throws AccumuloException, AccumuloSecurityException {
-    super.setPlugin(cl, shellState, tableName, className);
-    if (cl.hasOption(interpeterOption.getOpt())) {
-      shellState.getConnector().tableOperations().setProperty(tableName, Property.TABLE_INTERPRETER_CLASS.toString(), className);
-    }
-  }
-  
-  protected void removePlugin(final CommandLine cl, final Shell shellState, final String tableName) throws AccumuloException, AccumuloSecurityException {
-    super.removePlugin(cl, shellState, tableName);
-    if (cl.hasOption(interpeterOption.getOpt())) {
-      shellState.getConnector().tableOperations().removeProperty(tableName, Property.TABLE_INTERPRETER_CLASS.toString());
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/GetAuthsCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/GetAuthsCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/GetAuthsCommand.java
deleted file mode 100644
index e40a83f..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/GetAuthsCommand.java
+++ /dev/null
@@ -1,67 +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.accumulo.core.util.shell.commands;
-
-import java.io.IOException;
-import java.util.SortedSet;
-import java.util.TreeSet;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.security.Authorizations;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-import org.apache.commons.lang.StringUtils;
-
-public class GetAuthsCommand extends Command {
-  private Option userOpt;
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException, IOException {
-    final String user = cl.getOptionValue(userOpt.getOpt(), shellState.getConnector().whoami());
-    // Sort authorizations
-    Authorizations auths = shellState.getConnector().securityOperations().getUserAuthorizations(user);
-    SortedSet<String> set = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
-    for (byte[] auth : auths) {
-      set.add(new String(auth));
-    }
-    shellState.getReader().println(StringUtils.join(set, ','));
-    return 0;
-  }
-  
-  @Override
-  public String description() {
-    return "displays the maximum scan authorizations for a user";
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-    userOpt = new Option(Shell.userOption, "user", true, "user to operate on");
-    userOpt.setArgName("user");
-    o.addOption(userOpt);
-    return o;
-  }
-  
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/GetGroupsCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/GetGroupsCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/GetGroupsCommand.java
deleted file mode 100644
index bef2e5c..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/GetGroupsCommand.java
+++ /dev/null
@@ -1,60 +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.accumulo.core.util.shell.commands;
-
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-
-import org.apache.accumulo.core.util.LocalityGroupUtil;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Options;
-import org.apache.hadoop.io.Text;
-
-public class GetGroupsCommand extends Command {
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    final String tableName = OptUtil.getTableOpt(cl, shellState);
-    
-    final Map<String,Set<Text>> groups = shellState.getConnector().tableOperations().getLocalityGroups(tableName);
-    
-    for (Entry<String,Set<Text>> entry : groups.entrySet()) {
-      shellState.getReader().println(entry.getKey() + "=" + LocalityGroupUtil.encodeColumnFamilies(entry.getValue()));
-    }
-    return 0;
-  }
-  
-  @Override
-  public String description() {
-    return "gets the locality groups for a given table";
-  }
-  
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options opts = new Options();
-    opts.addOption(OptUtil.tableOpt("table to fetch locality groups from"));
-    return opts;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/GetSplitsCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/GetSplitsCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/GetSplitsCommand.java
deleted file mode 100644
index 92c7c5d..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/GetSplitsCommand.java
+++ /dev/null
@@ -1,155 +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.accumulo.core.util.shell.commands;
-
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.util.Iterator;
-import java.util.Map.Entry;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.Scanner;
-import org.apache.accumulo.core.client.TableNotFoundException;
-import org.apache.accumulo.core.data.Key;
-import org.apache.accumulo.core.data.KeyExtent;
-import org.apache.accumulo.core.data.Range;
-import org.apache.accumulo.core.data.Value;
-import org.apache.accumulo.core.metadata.MetadataTable;
-import org.apache.accumulo.core.metadata.RootTable;
-import org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection;
-import org.apache.accumulo.core.security.Authorizations;
-import org.apache.accumulo.core.util.TextUtil;
-import org.apache.accumulo.core.util.format.BinaryFormatter;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.accumulo.core.util.shell.Shell.PrintFile;
-import org.apache.accumulo.core.util.shell.Shell.PrintLine;
-import org.apache.accumulo.core.util.shell.Shell.PrintShell;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-import org.apache.commons.codec.binary.Base64;
-import org.apache.hadoop.io.Text;
-
-public class GetSplitsCommand extends Command {
-  
-  private Option outputFileOpt, maxSplitsOpt, base64Opt, verboseOpt;
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws IOException, AccumuloException, AccumuloSecurityException,
-      TableNotFoundException {
-    final String tableName = OptUtil.getTableOpt(cl, shellState);
-    
-    final String outputFile = cl.getOptionValue(outputFileOpt.getOpt());
-    final String m = cl.getOptionValue(maxSplitsOpt.getOpt());
-    final int maxSplits = m == null ? 0 : Integer.parseInt(m);
-    final boolean encode = cl.hasOption(base64Opt.getOpt());
-    final boolean verbose = cl.hasOption(verboseOpt.getOpt());
-    
-    final PrintLine p = outputFile == null ? new PrintShell(shellState.getReader()) : new PrintFile(outputFile);
-    
-    try {
-      if (!verbose) {
-        for (Text row : maxSplits > 0 ? shellState.getConnector().tableOperations().listSplits(tableName, maxSplits) : shellState.getConnector()
-            .tableOperations().listSplits(tableName)) {
-          p.print(encode(encode, row));
-        }
-      } else {
-        String systemTableToCheck = MetadataTable.NAME.equals(tableName) ? RootTable.NAME : MetadataTable.NAME;
-        final Scanner scanner = shellState.getConnector().createScanner(systemTableToCheck, Authorizations.EMPTY);
-        TabletsSection.TabletColumnFamily.PREV_ROW_COLUMN.fetch(scanner);
-        final Text start = new Text(shellState.getConnector().tableOperations().tableIdMap().get(tableName));
-        final Text end = new Text(start);
-        end.append(new byte[] {'<'}, 0, 1);
-        scanner.setRange(new Range(start, end));
-        for (Iterator<Entry<Key,Value>> iterator = scanner.iterator(); iterator.hasNext();) {
-          final Entry<Key,Value> next = iterator.next();
-          if (TabletsSection.TabletColumnFamily.PREV_ROW_COLUMN.hasColumns(next.getKey())) {
-            KeyExtent extent = new KeyExtent(next.getKey().getRow(), next.getValue());
-            final String pr = encode(encode, extent.getPrevEndRow());
-            final String er = encode(encode, extent.getEndRow());
-            final String line = String.format("%-26s (%s, %s%s", obscuredTabletName(extent), pr == null ? "-inf" : pr, er == null ? "+inf" : er,
-                er == null ? ") Default Tablet " : "]");
-            p.print(line);
-          }
-        }
-      }
-      
-    } finally {
-      p.close();
-    }
-    
-    return 0;
-  }
-  
-  private static String encode(final boolean encode, final Text text) {
-    if (text == null) {
-      return null;
-    }
-    BinaryFormatter.getlength(text.getLength());
-    return encode ? new String(Base64.encodeBase64(TextUtil.getBytes(text)), StandardCharsets.UTF_8) : BinaryFormatter.appendText(new StringBuilder(), text).toString();
-  }
-  
-  private static String obscuredTabletName(final KeyExtent extent) {
-    MessageDigest digester;
-    try {
-      digester = MessageDigest.getInstance("MD5");
-    } catch (NoSuchAlgorithmException e) {
-      throw new RuntimeException(e);
-    }
-    if (extent.getEndRow() != null && extent.getEndRow().getLength() > 0) {
-      digester.update(extent.getEndRow().getBytes(), 0, extent.getEndRow().getLength());
-    }
-    return new String(Base64.encodeBase64(digester.digest()), StandardCharsets.UTF_8);
-  }
-  
-  @Override
-  public String description() {
-    return "retrieves the current split points for tablets in the current table";
-  }
-  
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options opts = new Options();
-    
-    outputFileOpt = new Option("o", "output", true, "local file to write the splits to");
-    outputFileOpt.setArgName("file");
-    
-    maxSplitsOpt = new Option("m", "max", true, "maximum number of splits to return (evenly spaced)");
-    maxSplitsOpt.setArgName("num");
-    
-    base64Opt = new Option("b64", "base64encoded", false, "encode the split points");
-    
-    verboseOpt = new Option("v", "verbose", false, "print out the tablet information with start/end rows");
-    
-    opts.addOption(outputFileOpt);
-    opts.addOption(maxSplitsOpt);
-    opts.addOption(base64Opt);
-    opts.addOption(verboseOpt);
-    opts.addOption(OptUtil.tableOpt("table to get splits for"));
-    
-    return opts;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/GrantCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/GrantCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/GrantCommand.java
deleted file mode 100644
index de719fd..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/GrantCommand.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.accumulo.core.util.shell.commands;
-
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.accumulo.core.security.NamespacePermission;
-import org.apache.accumulo.core.security.SystemPermission;
-import org.apache.accumulo.core.security.TablePermission;
-import org.apache.accumulo.core.util.BadArgumentException;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.accumulo.core.util.shell.Token;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.OptionGroup;
-import org.apache.commons.cli.Options;
-
-public class GrantCommand extends TableOperation {
-  {
-    disableUnflaggedTableOptions();
-  }
-
-  private Option systemOpt, userOpt;
-  private String user;
-  private String[] permission;
-
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    user = cl.hasOption(userOpt.getOpt()) ? cl.getOptionValue(userOpt.getOpt()) : shellState.getConnector().whoami();
-
-    permission = cl.getArgs()[0].split("\\.", 2);
-    if (cl.hasOption(systemOpt.getOpt()) && permission[0].equalsIgnoreCase("System")) {
-      try {
-        shellState.getConnector().securityOperations().grantSystemPermission(user, SystemPermission.valueOf(permission[1]));
-        Shell.log.debug("Granted " + user + " the " + permission[1] + " permission");
-      } catch (IllegalArgumentException e) {
-        throw new BadArgumentException("No such system permission", fullCommand, fullCommand.indexOf(cl.getArgs()[0]));
-      }
-    } else if (permission[0].equalsIgnoreCase("Table")) {
-      super.execute(fullCommand, cl, shellState);
-    } else if (permission[0].equalsIgnoreCase("Namespace")) {
-      if (cl.hasOption(optNamespace.getOpt())) {
-        try {
-          shellState.getConnector().securityOperations()
-              .grantNamespacePermission(user, cl.getOptionValue(optNamespace.getOpt()), NamespacePermission.valueOf(permission[1]));
-        } catch (IllegalArgumentException e) {
-          throw new BadArgumentException("No such namespace permission", fullCommand, fullCommand.indexOf(cl.getArgs()[0]));
-        }
-      } else {
-        throw new BadArgumentException("No namespace specified to apply permission to", fullCommand, fullCommand.indexOf(cl.getArgs()[0]));
-      }
-    } else {
-      throw new BadArgumentException("Unrecognized permission", fullCommand, fullCommand.indexOf(cl.getArgs()[0]));
-    }
-    return 0;
-  }
-
-  @Override
-  protected void doTableOp(final Shell shellState, final String tableName) throws Exception {
-    try {
-      shellState.getConnector().securityOperations().grantTablePermission(user, tableName, TablePermission.valueOf(permission[1]));
-      Shell.log.debug("Granted " + user + " the " + permission[1] + " permission on table " + tableName);
-    } catch (IllegalArgumentException e) {
-      throw new IllegalArgumentException("No such table permission", e);
-    }
-  }
-
-  @Override
-  public String description() {
-    return "grants system, table, or namespace permissions for a user";
-  }
-
-  @Override
-  public String usage() {
-    return getName() + " <permission>";
-  }
-
-  @Override
-  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> completionSet) {
-    final Token cmd = new Token(getName());
-    cmd.addSubcommand(new Token(TablePermission.printableValues()));
-    cmd.addSubcommand(new Token(SystemPermission.printableValues()));
-    cmd.addSubcommand(new Token(NamespacePermission.printableValues()));
-    root.addSubcommand(cmd);
-  }
-
-  @Override
-  public Options getOptions() {
-    super.getOptions();
-    final Options o = new Options();
-
-    final OptionGroup group = new OptionGroup();
-
-    systemOpt = new Option("s", "system", false, "grant a system permission");
-
-    optNamespace = new Option(Shell.namespaceOption, "namespace", true, "name of a namespace to operate on");
-    optNamespace.setArgName("namespace");
-
-    group.addOption(systemOpt);
-    group.addOption(optTableName);
-    group.addOption(optTablePattern);
-    group.addOption(optNamespace);
-
-    o.addOptionGroup(group);
-    userOpt = new Option(Shell.userOption, "user", true, "user to operate on");
-    userOpt.setArgName("username");
-    userOpt.setRequired(true);
-    o.addOption(userOpt);
-
-    return o;
-  }
-
-  @Override
-  public int numArgs() {
-    return 1;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/GrepCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/GrepCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/GrepCommand.java
deleted file mode 100644
index c2ff232..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/GrepCommand.java
+++ /dev/null
@@ -1,111 +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.accumulo.core.util.shell.commands;
-
-import java.io.IOException;
-import java.util.Collections;
-import java.util.concurrent.TimeUnit;
-
-import org.apache.accumulo.core.client.BatchScanner;
-import org.apache.accumulo.core.client.IteratorSetting;
-import org.apache.accumulo.core.iterators.user.GrepIterator;
-import org.apache.accumulo.core.security.Authorizations;
-import org.apache.accumulo.core.util.format.Formatter;
-import org.apache.accumulo.core.util.interpret.ScanInterpreter;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.PrintFile;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.MissingArgumentException;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-
-public class GrepCommand extends ScanCommand {
-  
-  private Option numThreadsOpt;
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    final PrintFile printFile = getOutputFile(cl);
-    
-    final String tableName = OptUtil.getTableOpt(cl, shellState);
-    
-    if (cl.getArgList().isEmpty()) {
-      throw new MissingArgumentException("No terms specified");
-    }
-    final Class<? extends Formatter> formatter = getFormatter(cl, tableName, shellState);
-    final ScanInterpreter interpeter = getInterpreter(cl, tableName, shellState);
-    
-    // handle first argument, if present, the authorizations list to
-    // scan with
-    int numThreads = 20;
-    if (cl.hasOption(numThreadsOpt.getOpt())) {
-      numThreads = Integer.parseInt(cl.getOptionValue(numThreadsOpt.getOpt()));
-    }
-    final Authorizations auths = getAuths(cl, shellState);
-    final BatchScanner scanner = shellState.getConnector().createBatchScanner(tableName, auths, numThreads);
-    scanner.setRanges(Collections.singletonList(getRange(cl, interpeter)));
-    
-    scanner.setTimeout(getTimeout(cl), TimeUnit.MILLISECONDS);
-    
-    for (int i = 0; i < cl.getArgs().length; i++) {
-      setUpIterator(Integer.MAX_VALUE - cl.getArgs().length + i, "grep" + i, cl.getArgs()[i], scanner, cl);
-    }
-    try {
-      // handle columns
-      fetchColumns(cl, scanner, interpeter);
-      
-      // output the records
-      printRecords(cl, shellState, scanner, formatter, printFile);
-    } finally {
-      scanner.close();
-    }
-    
-    return 0;
-  }
-  
-  protected void setUpIterator(final int prio, final String name, final String term, final BatchScanner scanner, CommandLine cl) throws IOException {
-    if (prio < 0) {
-      throw new IllegalArgumentException("Priority < 0 " + prio);
-    }
-    final IteratorSetting grep = new IteratorSetting(prio, name, GrepIterator.class);
-    GrepIterator.setTerm(grep, term);
-    scanner.addScanIterator(grep);
-  }
-  
-  @Override
-  public String description() {
-    return "searches each row, column family, column qualifier and value in a table for a substring (not a regular expression), in parallel, on the server side";
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options opts = super.getOptions();
-    numThreadsOpt = new Option("nt", "num-threads", true, "number of threads to use");
-    opts.addOption(numThreadsOpt);
-    return opts;
-  }
-  
-  @Override
-  public String usage() {
-    return getName() + " <term>{ <term>}";
-  }
-  
-  @Override
-  public int numArgs() {
-    return Shell.NO_FIXED_ARG_LENGTH_CHECK;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/HelpCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/HelpCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/HelpCommand.java
deleted file mode 100644
index 9881e00..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/HelpCommand.java
+++ /dev/null
@@ -1,129 +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.accumulo.core.util.shell.commands;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.accumulo.core.util.shell.ShellCommandException;
-import org.apache.accumulo.core.util.shell.Token;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-
-public class HelpCommand extends Command {
-  private Option disablePaginationOpt;
-  private Option noWrapOpt;
-  
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws ShellCommandException, IOException {
-    int numColumns = shellState.getReader().getTerminal().getWidth();
-    if (cl.hasOption(noWrapOpt.getOpt())) {
-      numColumns = Integer.MAX_VALUE;
-    }
-    // print help summary
-    if (cl.getArgs().length == 0) {
-      int i = 0;
-      for (String cmd : shellState.commandFactory.keySet()) {
-        i = Math.max(i, cmd.length());
-      }
-      if (numColumns < 40) {
-        throw new IllegalArgumentException("numColumns must be at least 40 (was " + numColumns + ")");
-      }
-      final ArrayList<String> output = new ArrayList<String>();
-      for (Entry<String,Command[]> cmdGroup : shellState.commandGrouping.entrySet()) {
-        output.add(cmdGroup.getKey());
-        for (Command c : cmdGroup.getValue()) {
-          String n = c.getName();
-          String s = c.description();
-          if (s == null) {
-            s = "";
-          }
-          int beginIndex = 0;
-          int endIndex = s.length();
-          while (beginIndex < endIndex && s.charAt(beginIndex) == ' ')
-            beginIndex++;
-          String dash = "-";
-          while (endIndex > beginIndex && endIndex - beginIndex + i + 5 > numColumns) {
-            endIndex = s.lastIndexOf(" ", numColumns + beginIndex - i - 5);
-            if (endIndex == -1 || endIndex < beginIndex) {
-              endIndex = numColumns + beginIndex - i - 5 - 1;
-              output.add(String.format("%-" + i + "s  %s  %s-", n, dash, s.substring(beginIndex, endIndex)));
-              dash = " ";
-              beginIndex = endIndex;
-            } else {
-              output.add(String.format("%-" + i + "s  %s  %s", n, dash, s.substring(beginIndex, endIndex)));
-              dash = " ";
-              beginIndex = endIndex + 1;
-            }
-            n = "";
-            endIndex = s.length();
-            while (beginIndex < endIndex && s.charAt(beginIndex) == ' ') {
-              beginIndex++;
-            }
-          }
-          output.add(String.format("%-" + i + "s  %s  %s", n, dash, s.substring(beginIndex, endIndex)));
-        }
-        output.add("");
-      }
-      shellState.printLines(output.iterator(), !cl.hasOption(disablePaginationOpt.getOpt()));
-    }
-    
-    // print help for every command on command line
-    for (String cmd : cl.getArgs()) {
-      final Command c = shellState.commandFactory.get(cmd);
-      if (c == null) {
-        shellState.getReader().println(String.format("Unknown command \"%s\".  Enter \"help\" for a list possible commands.", cmd));
-      } else {
-        c.printHelp(shellState, numColumns);
-      }
-    }
-    return 0;
-  }
-  
-  public String description() {
-    return "provides information about the available commands";
-  }
-  
-  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> special) {
-    registerCompletionForCommands(root, special);
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-    disablePaginationOpt = new Option("np", "no-pagination", false, "disable pagination of output");
-    o.addOption(disablePaginationOpt);
-    noWrapOpt = new Option("nw", "no-wrap", false, "disable wrapping of output");
-    o.addOption(noWrapOpt);
-    return o;
-  }
-  
-  @Override
-  public String usage() {
-    return getName() + " [ <command>{ <command>} ]";
-  }
-  
-  @Override
-  public int numArgs() {
-    return Shell.NO_FIXED_ARG_LENGTH_CHECK;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/HiddenCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/HiddenCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/HiddenCommand.java
deleted file mode 100644
index c1615ea..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/HiddenCommand.java
+++ /dev/null
@@ -1,62 +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.accumulo.core.util.shell.commands;
-
-import java.nio.charset.StandardCharsets;
-import java.security.SecureRandom;
-import java.util.Random;
-
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.accumulo.core.util.shell.ShellCommandException;
-import org.apache.accumulo.core.util.shell.ShellCommandException.ErrorCode;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.codec.binary.Base64;
-
-public class HiddenCommand extends Command {
-  private static Random rand = new SecureRandom();
-  
-  @Override
-  public String description() {
-    return "The first rule of Accumulo is: \"You don't talk about Accumulo.\"";
-  }
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    if (rand.nextInt(10) == 0) {
-      shellState.getReader().beep();
-      shellState.getReader().println();
-      shellState.getReader().println(
-          new String(Base64.decodeBase64(("ICAgICAgIC4tLS4KICAgICAgLyAvXCBcCiAgICAgKCAvLS1cICkKICAgICAuPl8gIF88LgogICAgLyB8ICd8ICcgXAog"
-              + "ICAvICB8Xy58Xy4gIFwKICAvIC98ICAgICAgfFwgXAogfCB8IHwgfFwvfCB8IHwgfAogfF98IHwgfCAgfCB8IHxffAogICAgIC8gIF9fICBcCiAgICAvICAv"
-              + "ICBcICBcCiAgIC8gIC8gICAgXCAgXF8KIHwvICAvICAgICAgXCB8IHwKIHxfXy8gICAgICAgIFx8X3wK").getBytes(StandardCharsets.UTF_8)), StandardCharsets.UTF_8));
-    } else {
-      throw new ShellCommandException(ErrorCode.UNRECOGNIZED_COMMAND, getName());
-    }
-    return 0;
-  }
-  
-  @Override
-  public int numArgs() {
-    return Shell.NO_FIXED_ARG_LENGTH_CHECK;
-  }
-  
-  @Override
-  public String getName() {
-    return "accvmvlo";
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/HistoryCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/HistoryCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/HistoryCommand.java
deleted file mode 100644
index 9531d90..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/HistoryCommand.java
+++ /dev/null
@@ -1,82 +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.accumulo.core.util.shell.commands;
-
-import java.io.IOException;
-import java.util.Iterator;
-import java.util.ListIterator;
-
-import jline.console.history.History.Entry;
-
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-import org.apache.commons.collections.iterators.AbstractIteratorDecorator;
-
-public class HistoryCommand extends Command {
-  private Option clearHist;
-  private Option disablePaginationOpt;
-  
-  @SuppressWarnings("unchecked")
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws IOException {
-    if (cl.hasOption(clearHist.getOpt())) {
-      shellState.getReader().getHistory().clear();
-    } else {
-      ListIterator<Entry> it = shellState.getReader().getHistory().entries();
-      shellState.printLines(new HistoryLineIterator(it), !cl.hasOption(disablePaginationOpt.getOpt()));
-    }
-    
-    return 0;
-  }
-  
-  /**
-   * Decorator that converts an Iterator<History.Entry> to an Iterator<String>.
-   */
-  private static class HistoryLineIterator extends AbstractIteratorDecorator {
-    public HistoryLineIterator(Iterator<Entry> iterator) {
-      super(iterator);
-    }
-    
-    @Override
-    public String next() {
-      return super.next().toString();
-    }
-  }
-  
-  @Override
-  public String description() {
-    return ("generates a list of commands previously executed");
-  }
-  
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-    clearHist = new Option("c", "clear", false, "clear history file");
-    o.addOption(clearHist);
-    disablePaginationOpt = new Option("np", "no-pagination", false, "disable pagination of output");
-    o.addOption(disablePaginationOpt);
-    return o;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ImportDirectoryCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ImportDirectoryCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ImportDirectoryCommand.java
deleted file mode 100644
index 13db3a4..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ImportDirectoryCommand.java
+++ /dev/null
@@ -1,58 +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.accumulo.core.util.shell.commands;
-
-import java.io.IOException;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.TableNotFoundException;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-
-public class ImportDirectoryCommand extends Command {
-  
-  @Override
-  public String description() {
-    return "bulk imports an entire directory of data files to the current table.  The boolean argument determines if accumulo sets the time.";
-  }
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws IOException, AccumuloException, AccumuloSecurityException,
-      TableNotFoundException {
-    shellState.checkTableState();
-    
-    String dir = cl.getArgs()[0];
-    String failureDir = cl.getArgs()[1];
-    final boolean setTime = Boolean.parseBoolean(cl.getArgs()[2]);
-
-    shellState.getConnector().tableOperations().importDirectory(shellState.getTableName(), dir, failureDir, setTime);
-    return 0;
-  }
-  
-  @Override
-  public int numArgs() {
-    return 3;
-  }
-  
-  @Override
-  public String usage() {
-    return getName() + " <directory> <failureDirectory> true|false";
-  }
-  
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ImportTableCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ImportTableCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ImportTableCommand.java
deleted file mode 100644
index 571c45b..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ImportTableCommand.java
+++ /dev/null
@@ -1,51 +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.accumulo.core.util.shell.commands;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.TableExistsException;
-import org.apache.accumulo.core.client.TableNotFoundException;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-
-public class ImportTableCommand extends Command {
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException, TableNotFoundException,
-      TableExistsException {
-    
-    shellState.getConnector().tableOperations().importTable(cl.getArgs()[0], cl.getArgs()[1]);
-    return 0;
-  }
-  
-  @Override
-  public String usage() {
-    return getName() + " <table name> <import dir>";
-  }
-  
-  @Override
-  public String description() {
-    return "imports a table";
-  }
-  
-  @Override
-  public int numArgs() {
-    return 2;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/InfoCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/InfoCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/InfoCommand.java
deleted file mode 100644
index 57de6b1..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/InfoCommand.java
+++ /dev/null
@@ -1,19 +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.accumulo.core.util.shell.commands;
-
-public class InfoCommand extends AboutCommand {}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/InsertCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/InsertCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/InsertCommand.java
deleted file mode 100644
index a97db05..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/InsertCommand.java
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.accumulo.core.util.shell.commands;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.concurrent.TimeUnit;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.BatchWriter;
-import org.apache.accumulo.core.client.BatchWriterConfig;
-import org.apache.accumulo.core.client.MutationsRejectedException;
-import org.apache.accumulo.core.client.TableNotFoundException;
-import org.apache.accumulo.core.client.security.SecurityErrorCode;
-import org.apache.accumulo.core.conf.AccumuloConfiguration;
-import org.apache.accumulo.core.data.ConstraintViolationSummary;
-import org.apache.accumulo.core.data.KeyExtent;
-import org.apache.accumulo.core.data.Mutation;
-import org.apache.accumulo.core.data.Value;
-import org.apache.accumulo.core.security.ColumnVisibility;
-import org.apache.accumulo.core.tabletserver.thrift.ConstraintViolationException;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-import org.apache.hadoop.io.Text;
-
-public class InsertCommand extends Command {
-  private Option insertOptAuths, timestampOpt;
-  private Option timeoutOption;
-  
-  protected long getTimeout(final CommandLine cl) {
-    if (cl.hasOption(timeoutOption.getLongOpt())) {
-      return AccumuloConfiguration.getTimeInMillis(cl.getOptionValue(timeoutOption.getLongOpt()));
-    }
-    
-    return Long.MAX_VALUE;
-  }
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException,
-      TableNotFoundException, IOException, ConstraintViolationException {
-    shellState.checkTableState();
-    
-    final Mutation m = new Mutation(new Text(cl.getArgs()[0].getBytes(Shell.CHARSET)));
-    final Text colf = new Text(cl.getArgs()[1].getBytes(Shell.CHARSET));
-    final Text colq = new Text(cl.getArgs()[2].getBytes(Shell.CHARSET));
-    final Value val = new Value(cl.getArgs()[3].getBytes(Shell.CHARSET));
-    
-    if (cl.hasOption(insertOptAuths.getOpt())) {
-      final ColumnVisibility le = new ColumnVisibility(cl.getOptionValue(insertOptAuths.getOpt()));
-      Shell.log.debug("Authorization label will be set to: " + le.toString());
-      
-      if (cl.hasOption(timestampOpt.getOpt()))
-        m.put(colf, colq, le, Long.parseLong(cl.getOptionValue(timestampOpt.getOpt())), val);
-      else
-        m.put(colf, colq, le, val);
-    } else if (cl.hasOption(timestampOpt.getOpt()))
-      m.put(colf, colq, Long.parseLong(cl.getOptionValue(timestampOpt.getOpt())), val);
-    else
-      m.put(colf, colq, val);
-    
-    final BatchWriter bw = shellState.getConnector().createBatchWriter(shellState.getTableName(),
-        new BatchWriterConfig().setMaxMemory(Math.max(m.estimatedMemoryUsed(), 1024)).setMaxWriteThreads(1).setTimeout(getTimeout(cl), TimeUnit.MILLISECONDS));
-    bw.addMutation(m);
-    try {
-      bw.close();
-    } catch (MutationsRejectedException e) {
-      final ArrayList<String> lines = new ArrayList<String>();
-      if (e.getAuthorizationFailuresMap().isEmpty() == false) {
-        lines.add("	Authorization Failures:");
-      }
-      for (Entry<KeyExtent,Set<SecurityErrorCode>> entry : e.getAuthorizationFailuresMap().entrySet()) {
-        lines.add("		" + entry);
-      }
-      if (e.getConstraintViolationSummaries().isEmpty() == false) {
-        lines.add("	Constraint Failures:");
-      }
-      for (ConstraintViolationSummary cvs : e.getConstraintViolationSummaries()) {
-        lines.add("		" + cvs.toString());
-      }
-      
-      if (lines.size() == 0 || e.getUnknownExceptions() > 0) {
-        // must always print something
-        lines.add(" " + e.getClass().getName() + " : " + e.getMessage());
-        if (e.getCause() != null)
-          lines.add("   Caused by : " + e.getCause().getClass().getName() + " : " + e.getCause().getMessage());
-      }
-      
-      shellState.printLines(lines.iterator(), false);
-      
-      return 1;
-    }
-    return 0;
-  }
-  
-  @Override
-  public String description() {
-    return "inserts a record";
-  }
-  
-  @Override
-  public String usage() {
-    return getName() + " <row> <colfamily> <colqualifier> <value>";
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-    insertOptAuths = new Option("l", "visibility-label", true, "formatted visibility");
-    insertOptAuths.setArgName("expression");
-    o.addOption(insertOptAuths);
-    
-    timestampOpt = new Option("ts", "timestamp", true, "timestamp to use for insert");
-    timestampOpt.setArgName("timestamp");
-    o.addOption(timestampOpt);
-    
-    timeoutOption = new Option(null, "timeout", true,
-        "time before insert should fail if no data is written. If no unit is given assumes seconds.  Units d,h,m,s,and ms are supported.  e.g. 30s or 100ms");
-    timeoutOption.setArgName("timeout");
-    o.addOption(timeoutOption);
-    
-    return o;
-  }
-  
-  @Override
-  public int numArgs() {
-    return 4;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/InterpreterCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/InterpreterCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/InterpreterCommand.java
deleted file mode 100644
index 090bd7f..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/InterpreterCommand.java
+++ /dev/null
@@ -1,40 +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.accumulo.core.util.shell.commands;
-
-import org.apache.accumulo.core.conf.Property;
-import org.apache.accumulo.core.util.interpret.ScanInterpreter;
-import org.apache.accumulo.core.util.shell.Shell;
-
-/**
- * 
- */
-public class InterpreterCommand extends ShellPluginConfigurationCommand {
-  
-  public InterpreterCommand() {
-    super("interpreter", Property.TABLE_INTERPRETER_CLASS, "i");
-  }
-  
-  @Override
-  public String description() {
-    return "specifies a scan interpreter to interpret scan range and column arguments";
-  }
-  
-  public static Class<? extends ScanInterpreter> getCurrentInterpreter(final String tableName, final Shell shellState) {
-    return ShellPluginConfigurationCommand.getPluginClass(tableName, shellState, ScanInterpreter.class, Property.TABLE_INTERPRETER_CLASS);
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ListCompactionsCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ListCompactionsCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ListCompactionsCommand.java
deleted file mode 100644
index baa59a0..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ListCompactionsCommand.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.accumulo.core.util.shell.commands;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.accumulo.core.client.admin.InstanceOperations;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-
-public class ListCompactionsCommand extends Command {
-  
-  private Option tserverOption, disablePaginationOpt;
-  
-  @Override
-  public String description() {
-    return "lists what compactions are currently running in accumulo. See the accumulo.core.client.admin.ActiveCompaciton javadoc for more information about columns.";
-  }
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    
-    List<String> tservers;
-    
-    final InstanceOperations instanceOps = shellState.getConnector().instanceOperations();
-    
-    final boolean paginate = !cl.hasOption(disablePaginationOpt.getOpt());
-    
-    if (cl.hasOption(tserverOption.getOpt())) {
-      tservers = new ArrayList<String>();
-      tservers.add(cl.getOptionValue(tserverOption.getOpt()));
-    } else {
-      tservers = instanceOps.getTabletServers();
-    }
-    
-    shellState.printLines(new ActiveCompactionIterator(tservers, instanceOps), paginate);
-    
-    return 0;
-  }
-  
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options opts = new Options();
-    
-    tserverOption = new Option("ts", "tabletServer", true, "tablet server to list compactions for");
-    tserverOption.setArgName("tablet server");
-    opts.addOption(tserverOption);
-    
-    disablePaginationOpt = new Option("np", "no-pagination", false, "disable pagination of output");
-    opts.addOption(disablePaginationOpt);
-    
-    return opts;
-  }
-  
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ListIterCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ListIterCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ListIterCommand.java
deleted file mode 100644
index 9aac389..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ListIterCommand.java
+++ /dev/null
@@ -1,140 +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.accumulo.core.util.shell.commands;
-
-import java.util.EnumMap;
-import java.util.EnumSet;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-
-import org.apache.accumulo.core.client.IteratorSetting;
-import org.apache.accumulo.core.iterators.IteratorUtil.IteratorScope;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.OptionGroup;
-import org.apache.commons.cli.Options;
-
-public class ListIterCommand extends Command {
-  private Option nameOpt, allScopesOpt;
-  private Map<IteratorScope,Option> scopeOpts;
-
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-
-    boolean tables = cl.hasOption(OptUtil.tableOpt().getOpt()) || !shellState.getTableName().isEmpty();
-    boolean namespaces = cl.hasOption(OptUtil.namespaceOpt().getOpt());
-
-    final Map<String,EnumSet<IteratorScope>> iterators;
-    if (namespaces) {
-      iterators = shellState.getConnector().namespaceOperations().listIterators(OptUtil.getNamespaceOpt(cl, shellState));
-    } else if (tables) {
-      iterators = shellState.getConnector().tableOperations().listIterators(OptUtil.getTableOpt(cl, shellState));
-    } else {
-      throw new IllegalArgumentException("No table or namespace specified");
-    }
-
-    if (cl.hasOption(nameOpt.getOpt())) {
-      final String name = cl.getOptionValue(nameOpt.getOpt());
-      if (!iterators.containsKey(name)) {
-        Shell.log.warn("no iterators found that match your criteria");
-        return 0;
-      }
-      final EnumSet<IteratorScope> scopes = iterators.get(name);
-      iterators.clear();
-      iterators.put(name, scopes);
-    }
-
-    final boolean allScopes = cl.hasOption(allScopesOpt.getOpt());
-    Set<IteratorScope> desiredScopes = new HashSet<IteratorScope>();
-    for (IteratorScope scope : IteratorScope.values()) {
-      if (allScopes || cl.hasOption(scopeOpts.get(scope).getOpt()))
-        desiredScopes.add(scope);
-    }
-    if (desiredScopes.isEmpty()) {
-      throw new IllegalArgumentException("You must select at least one scope to configure");
-    }
-    final StringBuilder sb = new StringBuilder("-\n");
-    for (Entry<String,EnumSet<IteratorScope>> entry : iterators.entrySet()) {
-      final String name = entry.getKey();
-      final EnumSet<IteratorScope> scopes = entry.getValue();
-      for (IteratorScope scope : scopes) {
-        if (desiredScopes.contains(scope)) {
-          IteratorSetting setting;
-          if (namespaces) {
-            setting = shellState.getConnector().namespaceOperations().getIteratorSetting(OptUtil.getNamespaceOpt(cl, shellState), name, scope);
-          } else if (tables) {
-            setting = shellState.getConnector().tableOperations().getIteratorSetting(OptUtil.getTableOpt(cl, shellState), name, scope);
-          } else {
-            throw new IllegalArgumentException("No table or namespace specified");
-          }
-          sb.append("-    Iterator ").append(setting.getName()).append(", ").append(scope).append(" scope options:\n");
-          sb.append("-        ").append("iteratorPriority").append(" = ").append(setting.getPriority()).append("\n");
-          sb.append("-        ").append("iteratorClassName").append(" = ").append(setting.getIteratorClass()).append("\n");
-          for (Entry<String,String> optEntry : setting.getOptions().entrySet()) {
-            sb.append("-        ").append(optEntry.getKey()).append(" = ").append(optEntry.getValue()).append("\n");
-          }
-        }
-      }
-    }
-    sb.append("-");
-    shellState.getReader().println(sb.toString());
-
-    return 0;
-  }
-
-  @Override
-  public String description() {
-    return "lists table-specific or namespace-specific iterators configured in this shell session";
-  }
-
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-
-    nameOpt = new Option("n", "name", true, "iterator to list");
-    nameOpt.setArgName("itername");
-
-    allScopesOpt = new Option("all", "all-scopes", false, "list from all scopes");
-    o.addOption(allScopesOpt);
-    
-    scopeOpts = new EnumMap<IteratorScope,Option>(IteratorScope.class);
-    scopeOpts.put(IteratorScope.minc, new Option(IteratorScope.minc.name(), "minor-compaction", false, "list iterator for minor compaction scope"));
-    scopeOpts.put(IteratorScope.majc, new Option(IteratorScope.majc.name(), "major-compaction", false, "list iterator for major compaction scope"));
-    scopeOpts.put(IteratorScope.scan, new Option(IteratorScope.scan.name(), "scan-time", false, "list iterator for scan scope"));
-
-    OptionGroup grp = new OptionGroup();
-    grp.addOption(OptUtil.tableOpt("table to list the configured iterators on"));
-    grp.addOption(OptUtil.namespaceOpt("namespace to list the configured iterators on"));
-    o.addOptionGroup(grp);
-    o.addOption(nameOpt);
-
-    for (Option opt : scopeOpts.values()) {
-      o.addOption(opt);
-    }
-
-    return o;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ListScansCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ListScansCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ListScansCommand.java
deleted file mode 100644
index e4a2692..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ListScansCommand.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.accumulo.core.util.shell.commands;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.accumulo.core.client.admin.InstanceOperations;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-
-public class ListScansCommand extends Command {
-  
-  private Option tserverOption, disablePaginationOpt;
-  
-  @Override
-  public String description() {
-    return "lists what scans are currently running in accumulo. See the accumulo.core.client.admin.ActiveScan javadoc for more information about columns.";
-  }
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    
-    List<String> tservers;
-    
-    final InstanceOperations instanceOps = shellState.getConnector().instanceOperations();
-    
-    final boolean paginate = !cl.hasOption(disablePaginationOpt.getOpt());
-    
-    if (cl.hasOption(tserverOption.getOpt())) {
-      tservers = new ArrayList<String>();
-      tservers.add(cl.getOptionValue(tserverOption.getOpt()));
-    } else {
-      tservers = instanceOps.getTabletServers();
-    }
-    
-    shellState.printLines(new ActiveScanIterator(tservers, instanceOps), paginate);
-    
-    return 0;
-  }
-  
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options opts = new Options();
-    
-    tserverOption = new Option("ts", "tabletServer", true, "tablet server to list scans for");
-    tserverOption.setArgName("tablet server");
-    opts.addOption(tserverOption);
-    
-    disablePaginationOpt = new Option("np", "no-pagination", false, "disable pagination of output");
-    opts.addOption(disablePaginationOpt);
-    
-    return opts;
-  }
-  
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ListShellIterCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ListShellIterCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ListShellIterCommand.java
deleted file mode 100644
index 7f6ad84..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ListShellIterCommand.java
+++ /dev/null
@@ -1,105 +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.accumulo.core.util.shell.commands;
-
-import java.util.List;
-import java.util.Map.Entry;
-import java.util.Set;
-
-import org.apache.accumulo.core.client.IteratorSetting;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-
-/**
- * 
- */
-public class ListShellIterCommand extends Command {
-  
-  private Option nameOpt, profileOpt;
-
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    if (shellState.iteratorProfiles.size() == 0)
-      return 0;
-    
-    final StringBuilder sb = new StringBuilder();
-
-    String profile = null;
-    if (cl.hasOption(profileOpt.getOpt()))
-      profile = cl.getOptionValue(profileOpt.getOpt());
-
-    String name = null;
-    if (cl.hasOption(nameOpt.getOpt()))
-      name = cl.getOptionValue(nameOpt.getOpt());
-
-    Set<Entry<String,List<IteratorSetting>>> es = shellState.iteratorProfiles.entrySet();
-    for (Entry<String,List<IteratorSetting>> entry : es) {
-      if (profile != null && !profile.equals(entry.getKey()))
-        continue;
-
-      sb.append("-\n");
-      sb.append("- Profile : " + entry.getKey() + "\n");
-      for (IteratorSetting setting : entry.getValue()) {
-        if (name != null && !name.equals(setting.getName()))
-          continue;
-
-        sb.append("-    Iterator ").append(setting.getName()).append(", ").append(" options:\n");
-        sb.append("-        ").append("iteratorPriority").append(" = ").append(setting.getPriority()).append("\n");
-        sb.append("-        ").append("iteratorClassName").append(" = ").append(setting.getIteratorClass()).append("\n");
-        for (Entry<String,String> optEntry : setting.getOptions().entrySet()) {
-          sb.append("-        ").append(optEntry.getKey()).append(" = ").append(optEntry.getValue()).append("\n");
-        }
-      }
-    }
-    
-    if (sb.length() > 0) {
-      sb.append("-\n");
-    }
-
-    shellState.getReader().print(sb.toString());
-
-    return 0;
-  }
-  
-  public String description() {
-    return "lists iterators profiles configured in shell";
-  }
-  
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-    
-    profileOpt = new Option("pn", "profile", true, "iterator profile name");
-    profileOpt.setArgName("profile");
-
-    nameOpt = new Option("n", "name", true, "iterator to list");
-    nameOpt.setArgName("itername");
-    
-    o.addOption(profileOpt);
-    o.addOption(nameOpt);
-
-    return o;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/MaxRowCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/MaxRowCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/MaxRowCommand.java
deleted file mode 100644
index ddb6cc1..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/MaxRowCommand.java
+++ /dev/null
@@ -1,55 +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.accumulo.core.util.shell.commands;
-
-import org.apache.accumulo.core.data.Range;
-import org.apache.accumulo.core.security.Authorizations;
-import org.apache.accumulo.core.util.interpret.ScanInterpreter;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.commons.cli.CommandLine;
-import org.apache.hadoop.io.Text;
-
-public class MaxRowCommand extends ScanCommand {
-  
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    final String tableName = OptUtil.getTableOpt(cl, shellState);
-    
-    final ScanInterpreter interpeter = getInterpreter(cl, tableName, shellState);
-    
-    final Range range = getRange(cl, interpeter);
-    final Authorizations auths = getAuths(cl, shellState);
-    final Text startRow = range.getStartKey() == null ? null : range.getStartKey().getRow();
-    final Text endRow = range.getEndKey() == null ? null : range.getEndKey().getRow();
-    
-    try {
-      final Text max = shellState.getConnector().tableOperations()
-          .getMaxRow(tableName, auths, startRow, range.isStartKeyInclusive(), endRow, range.isEndKeyInclusive());
-      if (max != null) {
-        shellState.getReader().println(max.toString());
-      }
-    } catch (Exception e) {
-      e.printStackTrace();
-    }
-    
-    return 0;
-  }
-  
-  @Override
-  public String description() {
-    return "finds the max row in a table within a given range";
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/MergeCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/MergeCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/MergeCommand.java
deleted file mode 100644
index 9774e36..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/MergeCommand.java
+++ /dev/null
@@ -1,111 +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.accumulo.core.util.shell.commands;
-
-import java.io.IOException;
-
-import org.apache.accumulo.core.conf.AccumuloConfiguration;
-import org.apache.accumulo.core.util.Merge;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-import org.apache.hadoop.io.Text;
-
-public class MergeCommand extends Command {
-  private Option verboseOpt, forceOpt, sizeOpt, allOpt;
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    boolean verbose = shellState.isVerbose();
-    boolean force = false;
-    boolean all = false;
-    long size = -1;
-    final String tableName = OptUtil.getTableOpt(cl, shellState);
-    final Text startRow = OptUtil.getStartRow(cl);
-    final Text endRow = OptUtil.getEndRow(cl);
-    if (cl.hasOption(verboseOpt.getOpt())) {
-      verbose = true;
-    }
-    if (cl.hasOption(forceOpt.getOpt())) {
-      force = true;
-    }
-    if (cl.hasOption(allOpt.getOpt())) {
-      all = true;
-    }
-    if (cl.hasOption(sizeOpt.getOpt())) {
-      size = AccumuloConfiguration.getMemoryInBytes(cl.getOptionValue(sizeOpt.getOpt()));
-    }
-    if (startRow == null && endRow == null && size < 0 && !all) {
-      shellState.getReader().flush();
-      String line = shellState.getReader().readLine("Merge the entire table { " + tableName + " } into one tablet (yes|no)? ");
-      if (line == null)
-        return 0;
-      if (!line.equalsIgnoreCase("y") && !line.equalsIgnoreCase("yes"))
-        return 0;
-    }
-    if (size < 0) {
-      shellState.getConnector().tableOperations().merge(tableName, startRow, endRow);
-    } else {
-      final boolean finalVerbose = verbose;
-      final Merge merge = new Merge() {
-        protected void message(String fmt, Object... args) {
-          if (finalVerbose) {
-            try {
-              shellState.getReader().println(String.format(fmt, args));
-            } catch (IOException ex) {
-              throw new RuntimeException(ex);
-            }
-          }
-        }
-      };
-      merge.mergomatic(shellState.getConnector(), tableName, startRow, endRow, size, force);
-    }
-    return 0;
-  }
-  
-  @Override
-  public String description() {
-    return "merges tablets in a table";
-  }
-  
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-    verboseOpt = new Option("v", "verbose", false, "verbose output during merge");
-    sizeOpt = new Option("s", "size", true, "merge tablets to the given size over the entire table");
-    forceOpt = new Option("f", "force", false, "merge small tablets to large tablets, even if it goes over the given size");
-    allOpt = new Option("", "all", false, "allow an entire table to be merged into one tablet without prompting the user for confirmation");
-    Option startRowOpt = OptUtil.startRowOpt();
-    startRowOpt.setDescription("begin row (NOT inclusive)");
-    o.addOption(startRowOpt);
-    o.addOption(OptUtil.endRowOpt());
-    o.addOption(OptUtil.tableOpt("table to be merged"));
-    o.addOption(verboseOpt);
-    o.addOption(sizeOpt);
-    o.addOption(forceOpt);
-    o.addOption(allOpt);
-    return o;
-  }
-  
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/NamespacePermissionsCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/NamespacePermissionsCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/NamespacePermissionsCommand.java
deleted file mode 100644
index 2dcba55..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/NamespacePermissionsCommand.java
+++ /dev/null
@@ -1,44 +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.accumulo.core.util.shell.commands;
-
-import java.io.IOException;
-
-import org.apache.accumulo.core.security.NamespacePermission;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-
-public class NamespacePermissionsCommand extends Command {
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws IOException {
-    for (String p : NamespacePermission.printableValues()) {
-      shellState.getReader().println(p);
-    }
-    return 0;
-  }
-
-  @Override
-  public String description() {
-    return "displays a list of valid namespace permissions";
-  }
-
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/NamespacesCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/NamespacesCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/NamespacesCommand.java
deleted file mode 100644
index 16ee645..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/NamespacesCommand.java
+++ /dev/null
@@ -1,83 +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.accumulo.core.util.shell.commands;
-
-import java.io.IOException;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.TreeMap;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.impl.Namespaces;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-
-import com.google.common.base.Function;
-import com.google.common.collect.Iterators;
-
-public class NamespacesCommand extends Command {
-  private Option disablePaginationOpt, namespaceIdOption;
-
-  private static final String DEFAULT_NAMESPACE_DISPLAY_NAME = "\"\"";
-
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException, IOException {
-    Map<String,String> namespaces = new TreeMap<String,String>(shellState.getConnector().namespaceOperations().namespaceIdMap());
-
-    Iterator<String> it = Iterators.transform(namespaces.entrySet().iterator(), new Function<Entry<String,String>,String>() {
-      @Override
-      public String apply(Map.Entry<String,String> entry) {
-        String name = entry.getKey();
-        if (Namespaces.DEFAULT_NAMESPACE.equals(name))
-          name = DEFAULT_NAMESPACE_DISPLAY_NAME;
-        String id = entry.getValue();
-        if (cl.hasOption(namespaceIdOption.getOpt()))
-          return String.format(TablesCommand.NAME_AND_ID_FORMAT, name, id);
-        else
-          return name;
-      };
-    });
-
-    shellState.printLines(it, !cl.hasOption(disablePaginationOpt.getOpt()));
-    return 0;
-  }
-
-  @Override
-  public String description() {
-    return "displays a list of all existing namespaces";
-  }
-
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-    namespaceIdOption = new Option("l", "list-ids", false, "display internal namespace ids along with the name");
-    o.addOption(namespaceIdOption);
-    disablePaginationOpt = new Option("np", "no-pagination", false, "disable pagination of output");
-    o.addOption(disablePaginationOpt);
-    return o;
-  }
-
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/NoTableCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/NoTableCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/NoTableCommand.java
deleted file mode 100644
index afdab53..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/NoTableCommand.java
+++ /dev/null
@@ -1,40 +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.accumulo.core.util.shell.commands;
-
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-
-public class NoTableCommand extends Command {
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    shellState.setTableName("");
-    
-    return 0;
-  }
-  
-  @Override
-  public String description() {
-    return "returns to a tableless shell state";
-  }
-  
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-}


[04/53] [abbrv] ACCUMULO-1897 Move shell into new package and module

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/ImportDirectoryCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/ImportDirectoryCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/ImportDirectoryCommand.java
new file mode 100644
index 0000000..56c27c2
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/ImportDirectoryCommand.java
@@ -0,0 +1,58 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.io.IOException;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+
+public class ImportDirectoryCommand extends Command {
+  
+  @Override
+  public String description() {
+    return "bulk imports an entire directory of data files to the current table.  The boolean argument determines if accumulo sets the time.";
+  }
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws IOException, AccumuloException, AccumuloSecurityException,
+      TableNotFoundException {
+    shellState.checkTableState();
+    
+    String dir = cl.getArgs()[0];
+    String failureDir = cl.getArgs()[1];
+    final boolean setTime = Boolean.parseBoolean(cl.getArgs()[2]);
+
+    shellState.getConnector().tableOperations().importDirectory(shellState.getTableName(), dir, failureDir, setTime);
+    return 0;
+  }
+  
+  @Override
+  public int numArgs() {
+    return 3;
+  }
+  
+  @Override
+  public String usage() {
+    return getName() + " <directory> <failureDirectory> true|false";
+  }
+  
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/ImportTableCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/ImportTableCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/ImportTableCommand.java
new file mode 100644
index 0000000..46c941f
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/ImportTableCommand.java
@@ -0,0 +1,51 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.TableExistsException;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+
+public class ImportTableCommand extends Command {
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException, TableNotFoundException,
+      TableExistsException {
+    
+    shellState.getConnector().tableOperations().importTable(cl.getArgs()[0], cl.getArgs()[1]);
+    return 0;
+  }
+  
+  @Override
+  public String usage() {
+    return getName() + " <table name> <import dir>";
+  }
+  
+  @Override
+  public String description() {
+    return "imports a table";
+  }
+  
+  @Override
+  public int numArgs() {
+    return 2;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/InfoCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/InfoCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/InfoCommand.java
new file mode 100644
index 0000000..df5cfbb
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/InfoCommand.java
@@ -0,0 +1,19 @@
+/*
+ * 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.accumulo.shell.commands;
+
+public class InfoCommand extends AboutCommand {}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/InsertCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/InsertCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/InsertCommand.java
new file mode 100644
index 0000000..19ae5b8
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/InsertCommand.java
@@ -0,0 +1,148 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.BatchWriter;
+import org.apache.accumulo.core.client.BatchWriterConfig;
+import org.apache.accumulo.core.client.MutationsRejectedException;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.core.client.security.SecurityErrorCode;
+import org.apache.accumulo.core.conf.AccumuloConfiguration;
+import org.apache.accumulo.core.data.ConstraintViolationSummary;
+import org.apache.accumulo.core.data.KeyExtent;
+import org.apache.accumulo.core.data.Mutation;
+import org.apache.accumulo.core.data.Value;
+import org.apache.accumulo.core.security.ColumnVisibility;
+import org.apache.accumulo.core.tabletserver.thrift.ConstraintViolationException;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+import org.apache.hadoop.io.Text;
+
+public class InsertCommand extends Command {
+  private Option insertOptAuths, timestampOpt;
+  private Option timeoutOption;
+  
+  protected long getTimeout(final CommandLine cl) {
+    if (cl.hasOption(timeoutOption.getLongOpt())) {
+      return AccumuloConfiguration.getTimeInMillis(cl.getOptionValue(timeoutOption.getLongOpt()));
+    }
+    
+    return Long.MAX_VALUE;
+  }
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException,
+      TableNotFoundException, IOException, ConstraintViolationException {
+    shellState.checkTableState();
+    
+    final Mutation m = new Mutation(new Text(cl.getArgs()[0].getBytes(Shell.CHARSET)));
+    final Text colf = new Text(cl.getArgs()[1].getBytes(Shell.CHARSET));
+    final Text colq = new Text(cl.getArgs()[2].getBytes(Shell.CHARSET));
+    final Value val = new Value(cl.getArgs()[3].getBytes(Shell.CHARSET));
+    
+    if (cl.hasOption(insertOptAuths.getOpt())) {
+      final ColumnVisibility le = new ColumnVisibility(cl.getOptionValue(insertOptAuths.getOpt()));
+      Shell.log.debug("Authorization label will be set to: " + le.toString());
+      
+      if (cl.hasOption(timestampOpt.getOpt()))
+        m.put(colf, colq, le, Long.parseLong(cl.getOptionValue(timestampOpt.getOpt())), val);
+      else
+        m.put(colf, colq, le, val);
+    } else if (cl.hasOption(timestampOpt.getOpt()))
+      m.put(colf, colq, Long.parseLong(cl.getOptionValue(timestampOpt.getOpt())), val);
+    else
+      m.put(colf, colq, val);
+    
+    final BatchWriter bw = shellState.getConnector().createBatchWriter(shellState.getTableName(),
+        new BatchWriterConfig().setMaxMemory(Math.max(m.estimatedMemoryUsed(), 1024)).setMaxWriteThreads(1).setTimeout(getTimeout(cl), TimeUnit.MILLISECONDS));
+    bw.addMutation(m);
+    try {
+      bw.close();
+    } catch (MutationsRejectedException e) {
+      final ArrayList<String> lines = new ArrayList<String>();
+      if (e.getAuthorizationFailuresMap().isEmpty() == false) {
+        lines.add("	Authorization Failures:");
+      }
+      for (Entry<KeyExtent,Set<SecurityErrorCode>> entry : e.getAuthorizationFailuresMap().entrySet()) {
+        lines.add("		" + entry);
+      }
+      if (e.getConstraintViolationSummaries().isEmpty() == false) {
+        lines.add("	Constraint Failures:");
+      }
+      for (ConstraintViolationSummary cvs : e.getConstraintViolationSummaries()) {
+        lines.add("		" + cvs.toString());
+      }
+      
+      if (lines.size() == 0 || e.getUnknownExceptions() > 0) {
+        // must always print something
+        lines.add(" " + e.getClass().getName() + " : " + e.getMessage());
+        if (e.getCause() != null)
+          lines.add("   Caused by : " + e.getCause().getClass().getName() + " : " + e.getCause().getMessage());
+      }
+      
+      shellState.printLines(lines.iterator(), false);
+      
+      return 1;
+    }
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "inserts a record";
+  }
+  
+  @Override
+  public String usage() {
+    return getName() + " <row> <colfamily> <colqualifier> <value>";
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+    insertOptAuths = new Option("l", "visibility-label", true, "formatted visibility");
+    insertOptAuths.setArgName("expression");
+    o.addOption(insertOptAuths);
+    
+    timestampOpt = new Option("ts", "timestamp", true, "timestamp to use for insert");
+    timestampOpt.setArgName("timestamp");
+    o.addOption(timestampOpt);
+    
+    timeoutOption = new Option(null, "timeout", true,
+        "time before insert should fail if no data is written. If no unit is given assumes seconds.  Units d,h,m,s,and ms are supported.  e.g. 30s or 100ms");
+    timeoutOption.setArgName("timeout");
+    o.addOption(timeoutOption);
+    
+    return o;
+  }
+  
+  @Override
+  public int numArgs() {
+    return 4;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/InterpreterCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/InterpreterCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/InterpreterCommand.java
new file mode 100644
index 0000000..9d79601
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/InterpreterCommand.java
@@ -0,0 +1,40 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import org.apache.accumulo.core.conf.Property;
+import org.apache.accumulo.core.util.interpret.ScanInterpreter;
+import org.apache.accumulo.shell.Shell;
+
+/**
+ * 
+ */
+public class InterpreterCommand extends ShellPluginConfigurationCommand {
+  
+  public InterpreterCommand() {
+    super("interpreter", Property.TABLE_INTERPRETER_CLASS, "i");
+  }
+  
+  @Override
+  public String description() {
+    return "specifies a scan interpreter to interpret scan range and column arguments";
+  }
+  
+  public static Class<? extends ScanInterpreter> getCurrentInterpreter(final String tableName, final Shell shellState) {
+    return ShellPluginConfigurationCommand.getPluginClass(tableName, shellState, ScanInterpreter.class, Property.TABLE_INTERPRETER_CLASS);
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/ListCompactionsCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/ListCompactionsCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/ListCompactionsCommand.java
new file mode 100644
index 0000000..809ef8c
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/ListCompactionsCommand.java
@@ -0,0 +1,78 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.accumulo.core.client.admin.InstanceOperations;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+
+public class ListCompactionsCommand extends Command {
+  
+  private Option tserverOption, disablePaginationOpt;
+  
+  @Override
+  public String description() {
+    return "lists what compactions are currently running in accumulo. See the accumulo.core.client.admin.ActiveCompaciton javadoc for more information about columns.";
+  }
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    
+    List<String> tservers;
+    
+    final InstanceOperations instanceOps = shellState.getConnector().instanceOperations();
+    
+    final boolean paginate = !cl.hasOption(disablePaginationOpt.getOpt());
+    
+    if (cl.hasOption(tserverOption.getOpt())) {
+      tservers = new ArrayList<String>();
+      tservers.add(cl.getOptionValue(tserverOption.getOpt()));
+    } else {
+      tservers = instanceOps.getTabletServers();
+    }
+    
+    shellState.printLines(new ActiveCompactionIterator(tservers, instanceOps), paginate);
+    
+    return 0;
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options opts = new Options();
+    
+    tserverOption = new Option("ts", "tabletServer", true, "tablet server to list compactions for");
+    tserverOption.setArgName("tablet server");
+    opts.addOption(tserverOption);
+    
+    disablePaginationOpt = new Option("np", "no-pagination", false, "disable pagination of output");
+    opts.addOption(disablePaginationOpt);
+    
+    return opts;
+  }
+  
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/ListIterCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/ListIterCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/ListIterCommand.java
new file mode 100644
index 0000000..fcebd1f
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/ListIterCommand.java
@@ -0,0 +1,140 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.util.EnumMap;
+import java.util.EnumSet;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import org.apache.accumulo.core.client.IteratorSetting;
+import org.apache.accumulo.core.iterators.IteratorUtil.IteratorScope;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.OptionGroup;
+import org.apache.commons.cli.Options;
+
+public class ListIterCommand extends Command {
+  private Option nameOpt, allScopesOpt;
+  private Map<IteratorScope,Option> scopeOpts;
+
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+
+    boolean tables = cl.hasOption(OptUtil.tableOpt().getOpt()) || !shellState.getTableName().isEmpty();
+    boolean namespaces = cl.hasOption(OptUtil.namespaceOpt().getOpt());
+
+    final Map<String,EnumSet<IteratorScope>> iterators;
+    if (namespaces) {
+      iterators = shellState.getConnector().namespaceOperations().listIterators(OptUtil.getNamespaceOpt(cl, shellState));
+    } else if (tables) {
+      iterators = shellState.getConnector().tableOperations().listIterators(OptUtil.getTableOpt(cl, shellState));
+    } else {
+      throw new IllegalArgumentException("No table or namespace specified");
+    }
+
+    if (cl.hasOption(nameOpt.getOpt())) {
+      final String name = cl.getOptionValue(nameOpt.getOpt());
+      if (!iterators.containsKey(name)) {
+        Shell.log.warn("no iterators found that match your criteria");
+        return 0;
+      }
+      final EnumSet<IteratorScope> scopes = iterators.get(name);
+      iterators.clear();
+      iterators.put(name, scopes);
+    }
+
+    final boolean allScopes = cl.hasOption(allScopesOpt.getOpt());
+    Set<IteratorScope> desiredScopes = new HashSet<IteratorScope>();
+    for (IteratorScope scope : IteratorScope.values()) {
+      if (allScopes || cl.hasOption(scopeOpts.get(scope).getOpt()))
+        desiredScopes.add(scope);
+    }
+    if (desiredScopes.isEmpty()) {
+      throw new IllegalArgumentException("You must select at least one scope to configure");
+    }
+    final StringBuilder sb = new StringBuilder("-\n");
+    for (Entry<String,EnumSet<IteratorScope>> entry : iterators.entrySet()) {
+      final String name = entry.getKey();
+      final EnumSet<IteratorScope> scopes = entry.getValue();
+      for (IteratorScope scope : scopes) {
+        if (desiredScopes.contains(scope)) {
+          IteratorSetting setting;
+          if (namespaces) {
+            setting = shellState.getConnector().namespaceOperations().getIteratorSetting(OptUtil.getNamespaceOpt(cl, shellState), name, scope);
+          } else if (tables) {
+            setting = shellState.getConnector().tableOperations().getIteratorSetting(OptUtil.getTableOpt(cl, shellState), name, scope);
+          } else {
+            throw new IllegalArgumentException("No table or namespace specified");
+          }
+          sb.append("-    Iterator ").append(setting.getName()).append(", ").append(scope).append(" scope options:\n");
+          sb.append("-        ").append("iteratorPriority").append(" = ").append(setting.getPriority()).append("\n");
+          sb.append("-        ").append("iteratorClassName").append(" = ").append(setting.getIteratorClass()).append("\n");
+          for (Entry<String,String> optEntry : setting.getOptions().entrySet()) {
+            sb.append("-        ").append(optEntry.getKey()).append(" = ").append(optEntry.getValue()).append("\n");
+          }
+        }
+      }
+    }
+    sb.append("-");
+    shellState.getReader().println(sb.toString());
+
+    return 0;
+  }
+
+  @Override
+  public String description() {
+    return "lists table-specific or namespace-specific iterators configured in this shell session";
+  }
+
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+
+    nameOpt = new Option("n", "name", true, "iterator to list");
+    nameOpt.setArgName("itername");
+
+    allScopesOpt = new Option("all", "all-scopes", false, "list from all scopes");
+    o.addOption(allScopesOpt);
+    
+    scopeOpts = new EnumMap<IteratorScope,Option>(IteratorScope.class);
+    scopeOpts.put(IteratorScope.minc, new Option(IteratorScope.minc.name(), "minor-compaction", false, "list iterator for minor compaction scope"));
+    scopeOpts.put(IteratorScope.majc, new Option(IteratorScope.majc.name(), "major-compaction", false, "list iterator for major compaction scope"));
+    scopeOpts.put(IteratorScope.scan, new Option(IteratorScope.scan.name(), "scan-time", false, "list iterator for scan scope"));
+
+    OptionGroup grp = new OptionGroup();
+    grp.addOption(OptUtil.tableOpt("table to list the configured iterators on"));
+    grp.addOption(OptUtil.namespaceOpt("namespace to list the configured iterators on"));
+    o.addOptionGroup(grp);
+    o.addOption(nameOpt);
+
+    for (Option opt : scopeOpts.values()) {
+      o.addOption(opt);
+    }
+
+    return o;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/ListScansCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/ListScansCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/ListScansCommand.java
new file mode 100644
index 0000000..598503e
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/ListScansCommand.java
@@ -0,0 +1,78 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.accumulo.core.client.admin.InstanceOperations;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+
+public class ListScansCommand extends Command {
+  
+  private Option tserverOption, disablePaginationOpt;
+  
+  @Override
+  public String description() {
+    return "lists what scans are currently running in accumulo. See the accumulo.core.client.admin.ActiveScan javadoc for more information about columns.";
+  }
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    
+    List<String> tservers;
+    
+    final InstanceOperations instanceOps = shellState.getConnector().instanceOperations();
+    
+    final boolean paginate = !cl.hasOption(disablePaginationOpt.getOpt());
+    
+    if (cl.hasOption(tserverOption.getOpt())) {
+      tservers = new ArrayList<String>();
+      tservers.add(cl.getOptionValue(tserverOption.getOpt()));
+    } else {
+      tservers = instanceOps.getTabletServers();
+    }
+    
+    shellState.printLines(new ActiveScanIterator(tservers, instanceOps), paginate);
+    
+    return 0;
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options opts = new Options();
+    
+    tserverOption = new Option("ts", "tabletServer", true, "tablet server to list scans for");
+    tserverOption.setArgName("tablet server");
+    opts.addOption(tserverOption);
+    
+    disablePaginationOpt = new Option("np", "no-pagination", false, "disable pagination of output");
+    opts.addOption(disablePaginationOpt);
+    
+    return opts;
+  }
+  
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/ListShellIterCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/ListShellIterCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/ListShellIterCommand.java
new file mode 100644
index 0000000..59f8f46
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/ListShellIterCommand.java
@@ -0,0 +1,105 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.util.List;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import org.apache.accumulo.core.client.IteratorSetting;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+
+/**
+ * 
+ */
+public class ListShellIterCommand extends Command {
+  
+  private Option nameOpt, profileOpt;
+
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    if (shellState.iteratorProfiles.size() == 0)
+      return 0;
+    
+    final StringBuilder sb = new StringBuilder();
+
+    String profile = null;
+    if (cl.hasOption(profileOpt.getOpt()))
+      profile = cl.getOptionValue(profileOpt.getOpt());
+
+    String name = null;
+    if (cl.hasOption(nameOpt.getOpt()))
+      name = cl.getOptionValue(nameOpt.getOpt());
+
+    Set<Entry<String,List<IteratorSetting>>> es = shellState.iteratorProfiles.entrySet();
+    for (Entry<String,List<IteratorSetting>> entry : es) {
+      if (profile != null && !profile.equals(entry.getKey()))
+        continue;
+
+      sb.append("-\n");
+      sb.append("- Profile : " + entry.getKey() + "\n");
+      for (IteratorSetting setting : entry.getValue()) {
+        if (name != null && !name.equals(setting.getName()))
+          continue;
+
+        sb.append("-    Iterator ").append(setting.getName()).append(", ").append(" options:\n");
+        sb.append("-        ").append("iteratorPriority").append(" = ").append(setting.getPriority()).append("\n");
+        sb.append("-        ").append("iteratorClassName").append(" = ").append(setting.getIteratorClass()).append("\n");
+        for (Entry<String,String> optEntry : setting.getOptions().entrySet()) {
+          sb.append("-        ").append(optEntry.getKey()).append(" = ").append(optEntry.getValue()).append("\n");
+        }
+      }
+    }
+    
+    if (sb.length() > 0) {
+      sb.append("-\n");
+    }
+
+    shellState.getReader().print(sb.toString());
+
+    return 0;
+  }
+  
+  public String description() {
+    return "lists iterators profiles configured in shell";
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+    
+    profileOpt = new Option("pn", "profile", true, "iterator profile name");
+    profileOpt.setArgName("profile");
+
+    nameOpt = new Option("n", "name", true, "iterator to list");
+    nameOpt.setArgName("itername");
+    
+    o.addOption(profileOpt);
+    o.addOption(nameOpt);
+
+    return o;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/MaxRowCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/MaxRowCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/MaxRowCommand.java
new file mode 100644
index 0000000..1794b57
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/MaxRowCommand.java
@@ -0,0 +1,55 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import org.apache.accumulo.core.data.Range;
+import org.apache.accumulo.core.security.Authorizations;
+import org.apache.accumulo.core.util.interpret.ScanInterpreter;
+import org.apache.accumulo.shell.Shell;
+import org.apache.commons.cli.CommandLine;
+import org.apache.hadoop.io.Text;
+
+public class MaxRowCommand extends ScanCommand {
+  
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    final String tableName = OptUtil.getTableOpt(cl, shellState);
+    
+    final ScanInterpreter interpeter = getInterpreter(cl, tableName, shellState);
+    
+    final Range range = getRange(cl, interpeter);
+    final Authorizations auths = getAuths(cl, shellState);
+    final Text startRow = range.getStartKey() == null ? null : range.getStartKey().getRow();
+    final Text endRow = range.getEndKey() == null ? null : range.getEndKey().getRow();
+    
+    try {
+      final Text max = shellState.getConnector().tableOperations()
+          .getMaxRow(tableName, auths, startRow, range.isStartKeyInclusive(), endRow, range.isEndKeyInclusive());
+      if (max != null) {
+        shellState.getReader().println(max.toString());
+      }
+    } catch (Exception e) {
+      e.printStackTrace();
+    }
+    
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "finds the max row in a table within a given range";
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/MergeCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/MergeCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/MergeCommand.java
new file mode 100644
index 0000000..33d63fa
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/MergeCommand.java
@@ -0,0 +1,111 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.io.IOException;
+
+import org.apache.accumulo.core.conf.AccumuloConfiguration;
+import org.apache.accumulo.core.util.Merge;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+import org.apache.hadoop.io.Text;
+
+public class MergeCommand extends Command {
+  private Option verboseOpt, forceOpt, sizeOpt, allOpt;
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    boolean verbose = shellState.isVerbose();
+    boolean force = false;
+    boolean all = false;
+    long size = -1;
+    final String tableName = OptUtil.getTableOpt(cl, shellState);
+    final Text startRow = OptUtil.getStartRow(cl);
+    final Text endRow = OptUtil.getEndRow(cl);
+    if (cl.hasOption(verboseOpt.getOpt())) {
+      verbose = true;
+    }
+    if (cl.hasOption(forceOpt.getOpt())) {
+      force = true;
+    }
+    if (cl.hasOption(allOpt.getOpt())) {
+      all = true;
+    }
+    if (cl.hasOption(sizeOpt.getOpt())) {
+      size = AccumuloConfiguration.getMemoryInBytes(cl.getOptionValue(sizeOpt.getOpt()));
+    }
+    if (startRow == null && endRow == null && size < 0 && !all) {
+      shellState.getReader().flush();
+      String line = shellState.getReader().readLine("Merge the entire table { " + tableName + " } into one tablet (yes|no)? ");
+      if (line == null)
+        return 0;
+      if (!line.equalsIgnoreCase("y") && !line.equalsIgnoreCase("yes"))
+        return 0;
+    }
+    if (size < 0) {
+      shellState.getConnector().tableOperations().merge(tableName, startRow, endRow);
+    } else {
+      final boolean finalVerbose = verbose;
+      final Merge merge = new Merge() {
+        protected void message(String fmt, Object... args) {
+          if (finalVerbose) {
+            try {
+              shellState.getReader().println(String.format(fmt, args));
+            } catch (IOException ex) {
+              throw new RuntimeException(ex);
+            }
+          }
+        }
+      };
+      merge.mergomatic(shellState.getConnector(), tableName, startRow, endRow, size, force);
+    }
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "merges tablets in a table";
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+    verboseOpt = new Option("v", "verbose", false, "verbose output during merge");
+    sizeOpt = new Option("s", "size", true, "merge tablets to the given size over the entire table");
+    forceOpt = new Option("f", "force", false, "merge small tablets to large tablets, even if it goes over the given size");
+    allOpt = new Option("", "all", false, "allow an entire table to be merged into one tablet without prompting the user for confirmation");
+    Option startRowOpt = OptUtil.startRowOpt();
+    startRowOpt.setDescription("begin row (NOT inclusive)");
+    o.addOption(startRowOpt);
+    o.addOption(OptUtil.endRowOpt());
+    o.addOption(OptUtil.tableOpt("table to be merged"));
+    o.addOption(verboseOpt);
+    o.addOption(sizeOpt);
+    o.addOption(forceOpt);
+    o.addOption(allOpt);
+    return o;
+  }
+  
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/NamespacePermissionsCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/NamespacePermissionsCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/NamespacePermissionsCommand.java
new file mode 100644
index 0000000..99ba6ad
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/NamespacePermissionsCommand.java
@@ -0,0 +1,44 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.io.IOException;
+
+import org.apache.accumulo.core.security.NamespacePermission;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+
+public class NamespacePermissionsCommand extends Command {
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws IOException {
+    for (String p : NamespacePermission.printableValues()) {
+      shellState.getReader().println(p);
+    }
+    return 0;
+  }
+
+  @Override
+  public String description() {
+    return "displays a list of valid namespace permissions";
+  }
+
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/NamespacesCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/NamespacesCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/NamespacesCommand.java
new file mode 100644
index 0000000..d822cf6
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/NamespacesCommand.java
@@ -0,0 +1,83 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.TreeMap;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.impl.Namespaces;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+
+import com.google.common.base.Function;
+import com.google.common.collect.Iterators;
+
+public class NamespacesCommand extends Command {
+  private Option disablePaginationOpt, namespaceIdOption;
+
+  private static final String DEFAULT_NAMESPACE_DISPLAY_NAME = "\"\"";
+
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException, IOException {
+    Map<String,String> namespaces = new TreeMap<String,String>(shellState.getConnector().namespaceOperations().namespaceIdMap());
+
+    Iterator<String> it = Iterators.transform(namespaces.entrySet().iterator(), new Function<Entry<String,String>,String>() {
+      @Override
+      public String apply(Map.Entry<String,String> entry) {
+        String name = entry.getKey();
+        if (Namespaces.DEFAULT_NAMESPACE.equals(name))
+          name = DEFAULT_NAMESPACE_DISPLAY_NAME;
+        String id = entry.getValue();
+        if (cl.hasOption(namespaceIdOption.getOpt()))
+          return String.format(TablesCommand.NAME_AND_ID_FORMAT, name, id);
+        else
+          return name;
+      };
+    });
+
+    shellState.printLines(it, !cl.hasOption(disablePaginationOpt.getOpt()));
+    return 0;
+  }
+
+  @Override
+  public String description() {
+    return "displays a list of all existing namespaces";
+  }
+
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+    namespaceIdOption = new Option("l", "list-ids", false, "display internal namespace ids along with the name");
+    o.addOption(namespaceIdOption);
+    disablePaginationOpt = new Option("np", "no-pagination", false, "disable pagination of output");
+    o.addOption(disablePaginationOpt);
+    return o;
+  }
+
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/NoTableCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/NoTableCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/NoTableCommand.java
new file mode 100644
index 0000000..7ff6358
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/NoTableCommand.java
@@ -0,0 +1,40 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+
+public class NoTableCommand extends Command {
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    shellState.setTableName("");
+    
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "returns to a tableless shell state";
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/OfflineCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/OfflineCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/OfflineCommand.java
new file mode 100644
index 0000000..6ac397c
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/OfflineCommand.java
@@ -0,0 +1,61 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.core.metadata.MetadataTable;
+import org.apache.accumulo.shell.Shell;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+
+public class OfflineCommand extends TableOperation {
+  
+  private boolean wait;
+  private Option waitOpt;
+  
+  @Override
+  public String description() {
+    return "starts the process of taking table offline";
+  }
+  
+  protected void doTableOp(final Shell shellState, final String tableName) throws AccumuloException, AccumuloSecurityException, TableNotFoundException {
+    if (tableName.equals(MetadataTable.NAME)) {
+      Shell.log.info("  You cannot take the " + MetadataTable.NAME + " offline.");
+    } else {
+      shellState.getConnector().tableOperations().offline(tableName, wait);
+      Shell.log.info("Offline of table " + tableName + (wait ? " completed." : " initiated..."));
+    }
+  }
+  
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    wait = cl.hasOption(waitOpt.getLongOpt());
+    return super.execute(fullCommand, cl, shellState);
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options opts = super.getOptions();
+    waitOpt = new Option("w", "wait", false, "wait for offline to finish");
+    opts.addOption(waitOpt); 
+    return opts;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/OnlineCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/OnlineCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/OnlineCommand.java
new file mode 100644
index 0000000..ace069f
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/OnlineCommand.java
@@ -0,0 +1,61 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.core.metadata.RootTable;
+import org.apache.accumulo.shell.Shell;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+
+public class OnlineCommand extends TableOperation {
+  
+  private boolean wait;
+  private Option waitOpt;
+  
+  @Override
+  public String description() {
+    return "starts the process of putting a table online";
+  }
+  
+  @Override
+  protected void doTableOp(final Shell shellState, final String tableName) throws AccumuloException, AccumuloSecurityException, TableNotFoundException {
+    if (tableName.equals(RootTable.NAME)) {
+      Shell.log.info("  The " + RootTable.NAME + " is always online.");
+    } else {
+      shellState.getConnector().tableOperations().online(tableName, wait);
+      Shell.log.info("Online of table " + tableName + (wait ? " completed." : " initiated..."));
+    }
+  }
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    wait = cl.hasOption(waitOpt.getLongOpt());
+    return super.execute(fullCommand, cl, shellState);
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options opts = super.getOptions();
+    waitOpt = new Option("w", "wait", false, "wait for online to finish");
+    opts.addOption(waitOpt); 
+    return opts;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/OptUtil.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/OptUtil.java b/shell/src/main/java/org/apache/accumulo/shell/commands/OptUtil.java
new file mode 100644
index 0000000..6243761
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/OptUtil.java
@@ -0,0 +1,146 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.io.UnsupportedEncodingException;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.NamespaceNotFoundException;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.shell.Shell;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.OptionGroup;
+import org.apache.hadoop.io.Text;
+
+public abstract class OptUtil {
+  public static final String START_ROW_OPT = "b";
+  public static final String END_ROW_OPT = "e";
+
+  public static String getTableOpt(final CommandLine cl, final Shell shellState) throws TableNotFoundException {
+    String tableName;
+
+    if (cl.hasOption(Shell.tableOption)) {
+      tableName = cl.getOptionValue(Shell.tableOption);
+      if (!shellState.getConnector().tableOperations().exists(tableName)) {
+        throw new TableNotFoundException(tableName, tableName, "specified table that doesn't exist");
+      }
+    } else {
+      shellState.checkTableState();
+      tableName = shellState.getTableName();
+    }
+
+    return tableName;
+  }
+
+  public static String getNamespaceOpt(final CommandLine cl, final Shell shellState) throws NamespaceNotFoundException, AccumuloException,
+      AccumuloSecurityException {
+    String namespace = null;
+    if (cl.hasOption(Shell.namespaceOption)) {
+      namespace = cl.getOptionValue(Shell.namespaceOption);
+      if (!shellState.getConnector().namespaceOperations().exists(namespace)) {
+        throw new NamespaceNotFoundException(namespace, namespace, "specified namespace that doesn't exist");
+      }
+    } else {
+      throw new NamespaceNotFoundException(null, null, "no namespace specified");
+    }
+    return namespace;
+  }
+
+  public static Option tableOpt() {
+    return tableOpt("tableName");
+  }
+
+  public static Option tableOpt(final String description) {
+    final Option tableOpt = new Option(Shell.tableOption, "table", true, description);
+    tableOpt.setArgName("table");
+    tableOpt.setRequired(false);
+    return tableOpt;
+  }
+
+  public static Option namespaceOpt() {
+    return namespaceOpt("namespace");
+  }
+
+  public static Option namespaceOpt(final String description) {
+    final Option namespaceOpt = new Option(Shell.namespaceOption, "namespace", true, description);
+    namespaceOpt.setArgName("namespace");
+    namespaceOpt.setRequired(false);
+    return namespaceOpt;
+  }
+
+  public static enum AdlOpt {
+    ADD("a"), DELETE("d"), LIST("l");
+
+    public final String opt;
+
+    private AdlOpt(String opt) {
+      this.opt = opt;
+    }
+  }
+
+  public static AdlOpt getAldOpt(final CommandLine cl) {
+    if (cl.hasOption(AdlOpt.ADD.opt)) {
+      return AdlOpt.ADD;
+    } else if (cl.hasOption(AdlOpt.DELETE.opt)) {
+      return AdlOpt.DELETE;
+    } else {
+      return AdlOpt.LIST;
+    }
+  }
+
+  public static OptionGroup addListDeleteGroup(final String name) {
+    final Option addOpt = new Option(AdlOpt.ADD.opt, "add", false, "add " + name);
+    final Option deleteOpt = new Option(AdlOpt.DELETE.opt, "delete", false, "delete " + name);
+    final Option listOpt = new Option(AdlOpt.LIST.opt, "list", false, "list " + name + "(s)");
+    final OptionGroup og = new OptionGroup();
+    og.addOption(addOpt);
+    og.addOption(deleteOpt);
+    og.addOption(listOpt);
+    og.setRequired(true);
+    return og;
+  }
+
+  public static Option startRowOpt() {
+    final Option o = new Option(START_ROW_OPT, "begin-row", true, "begin row (inclusive)");
+    o.setArgName("begin-row");
+    return o;
+  }
+
+  public static Option endRowOpt() {
+    final Option o = new Option(END_ROW_OPT, "end-row", true, "end row (inclusive)");
+    o.setArgName("end-row");
+    return o;
+  }
+
+  public static Text getStartRow(final CommandLine cl) throws UnsupportedEncodingException {
+    if (cl.hasOption(START_ROW_OPT)) {
+      return new Text(cl.getOptionValue(START_ROW_OPT).getBytes(Shell.CHARSET));
+    } else {
+      return null;
+    }
+  }
+
+  public static Text getEndRow(final CommandLine cl) throws UnsupportedEncodingException {
+    if (cl.hasOption(END_ROW_OPT)) {
+      return new Text(cl.getOptionValue(END_ROW_OPT).getBytes(Shell.CHARSET));
+    } else {
+      return null;
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/PasswdCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/PasswdCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/PasswdCommand.java
new file mode 100644
index 0000000..c1ef990
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/PasswdCommand.java
@@ -0,0 +1,96 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.impl.thrift.SecurityErrorCode;
+import org.apache.accumulo.core.client.security.tokens.PasswordToken;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+
+public class PasswdCommand extends Command {
+  private Option userOpt;
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException, IOException {
+    final String currentUser = shellState.getConnector().whoami();
+    final String user = cl.getOptionValue(userOpt.getOpt(), currentUser);
+    
+    String password = null;
+    String passwordConfirm = null;
+    String oldPassword = null;
+    
+    oldPassword = shellState.readMaskedLine("Enter current password for '" + currentUser + "': ", '*');
+    if (oldPassword == null) {
+      shellState.getReader().println();
+      return 0;
+    } // user canceled
+    
+    if (!shellState.getConnector().securityOperations().authenticateUser(currentUser, new PasswordToken(oldPassword)))
+      throw new AccumuloSecurityException(user, SecurityErrorCode.BAD_CREDENTIALS);
+    
+    password = shellState.readMaskedLine("Enter new password for '" + user + "': ", '*');
+    if (password == null) {
+      shellState.getReader().println();
+      return 0;
+    } // user canceled
+    passwordConfirm = shellState.readMaskedLine("Please confirm new password for '" + user + "': ", '*');
+    if (passwordConfirm == null) {
+      shellState.getReader().println();
+      return 0;
+    } // user canceled
+    
+    if (!password.equals(passwordConfirm)) {
+      throw new IllegalArgumentException("Passwords do not match");
+    }
+    byte[] pass = password.getBytes(StandardCharsets.UTF_8);
+    shellState.getConnector().securityOperations().changeLocalUserPassword(user, new PasswordToken(pass));
+    // update the current credentials if the password changed was for
+    // the current user
+    if (shellState.getConnector().whoami().equals(user)) {
+      shellState.updateUser(user, new PasswordToken(pass));
+    }
+    Shell.log.debug("Changed password for user " + user);
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "changes a user's password";
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+    userOpt = new Option(Shell.userOption, "user", true, "user to operate on");
+    userOpt.setArgName("user");
+    o.addOption(userOpt);
+    return o;
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/PingCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/PingCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/PingCommand.java
new file mode 100644
index 0000000..ef7a9e4
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/PingCommand.java
@@ -0,0 +1,82 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.accumulo.core.client.admin.InstanceOperations;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+
+/**
+ * 
+ */
+public class PingCommand extends Command {
+  
+  private Option tserverOption, disablePaginationOpt;
+  
+  @Override
+  public String description() {
+    return "ping tablet servers";
+  }
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    
+    List<String> tservers;
+    
+    final InstanceOperations instanceOps = shellState.getConnector().instanceOperations();
+    
+    final boolean paginate = !cl.hasOption(disablePaginationOpt.getOpt());
+    
+    if (cl.hasOption(tserverOption.getOpt())) {
+      tservers = new ArrayList<String>();
+      tservers.add(cl.getOptionValue(tserverOption.getOpt()));
+    } else {
+      tservers = instanceOps.getTabletServers();
+    }
+    
+    shellState.printLines(new PingIterator(tservers, instanceOps), paginate);
+    
+    return 0;
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options opts = new Options();
+    
+    tserverOption = new Option("ts", "tabletServer", true, "tablet server to ping");
+    tserverOption.setArgName("tablet server");
+    opts.addOption(tserverOption);
+    
+    disablePaginationOpt = new Option("np", "no-pagination", false, "disable pagination of output");
+    opts.addOption(disablePaginationOpt);
+    
+    return opts;
+  }
+  
+}
+

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/PingIterator.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/PingIterator.java b/shell/src/main/java/org/apache/accumulo/shell/commands/PingIterator.java
new file mode 100644
index 0000000..e414ed4
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/PingIterator.java
@@ -0,0 +1,58 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.admin.InstanceOperations;
+
+class PingIterator implements Iterator<String> {
+  
+  private Iterator<String> iter;
+  private InstanceOperations instanceOps;
+
+  PingIterator(List<String> tservers, InstanceOperations instanceOps) {
+    iter = tservers.iterator();
+    this.instanceOps = instanceOps;
+  }
+  
+  @Override
+  public boolean hasNext() {
+    return iter.hasNext();
+  }
+  
+  @Override
+  public String next() {
+    String tserver = iter.next();
+    
+    try {
+      instanceOps.ping(tserver);
+    } catch (AccumuloException e) {
+      return tserver + " ERROR " + e.getMessage();
+    }
+    
+    return tserver + " OK";
+  }
+  
+  @Override
+  public void remove() {
+    throw new UnsupportedOperationException();
+  }
+  
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/QuestionCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/QuestionCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/QuestionCommand.java
new file mode 100644
index 0000000..ae6b0a1
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/QuestionCommand.java
@@ -0,0 +1,24 @@
+/*
+ * 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.accumulo.shell.commands;
+
+public class QuestionCommand extends HelpCommand {
+  @Override
+  public String getName() {
+    return "?";
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/QuitCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/QuitCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/QuitCommand.java
new file mode 100644
index 0000000..3ad2274
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/QuitCommand.java
@@ -0,0 +1,19 @@
+/*
+ * 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.accumulo.shell.commands;
+
+public class QuitCommand extends ExitCommand {}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/QuotedStringTokenizer.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/QuotedStringTokenizer.java b/shell/src/main/java/org/apache/accumulo/shell/commands/QuotedStringTokenizer.java
new file mode 100644
index 0000000..ecc51eb
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/QuotedStringTokenizer.java
@@ -0,0 +1,141 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.io.UnsupportedEncodingException;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Iterator;
+
+import org.apache.accumulo.core.util.BadArgumentException;
+import org.apache.accumulo.shell.Shell;
+
+/**
+ * A basic tokenizer for generating tokens from a string. It understands quoted strings and escaped quote characters.
+ * 
+ * You can use the escape sequence '\' to escape single quotes, double quotes, and spaces only, in addition to the escape character itself.
+ * 
+ * The behavior is the same for single and double quoted strings. (i.e. '\'' is the same as "\'")
+ */
+
+public class QuotedStringTokenizer implements Iterable<String> {
+  private ArrayList<String> tokens;
+  private String input;
+  
+  public QuotedStringTokenizer(final String t) throws BadArgumentException {
+    tokens = new ArrayList<String>();
+    this.input = t;
+    try {
+      createTokens();
+    } catch (UnsupportedEncodingException e) {
+      throw new IllegalArgumentException(e.getMessage());
+    }
+  }
+  
+  public String[] getTokens() {
+    return tokens.toArray(new String[tokens.size()]);
+  }
+  
+  private void createTokens() throws BadArgumentException, UnsupportedEncodingException {
+    boolean inQuote = false;
+    boolean inEscapeSequence = false;
+    String hexChars = null;
+    char inQuoteChar = '"';
+    
+    final byte[] token = new byte[input.length()];
+    int tokenLength = 0;
+    final byte[] inputBytes = input.getBytes(StandardCharsets.UTF_8);
+    for (int i = 0; i < input.length(); ++i) {
+      final char ch = input.charAt(i);
+      
+      // if I ended up in an escape sequence, check for valid escapable character, and add it as a literal
+      if (inEscapeSequence) {
+        inEscapeSequence = false;
+        if (ch == 'x') {
+          hexChars = "";
+        } else if (ch == ' ' || ch == '\'' || ch == '"' || ch == '\\') {
+          token[tokenLength++] = inputBytes[i];
+        } else {
+          throw new BadArgumentException("can only escape single quotes, double quotes, the space character, the backslash, and hex input", input, i);
+        }
+      }
+      // in a hex escape sequence
+      else if (hexChars != null) {
+        final int digit = Character.digit(ch, 16);
+        if (digit < 0) {
+          throw new BadArgumentException("expected hex character", input, i);
+        }
+        hexChars += ch;
+        if (hexChars.length() == 2) {
+          byte b;
+          try {
+            b = (byte) (0xff & Short.parseShort(hexChars, 16));
+            if (!Character.isValidCodePoint(0xff & b))
+              throw new NumberFormatException();
+          } catch (NumberFormatException e) {
+            throw new BadArgumentException("unsupported non-ascii character", input, i);
+          }
+          token[tokenLength++] = b;
+          hexChars = null;
+        }
+      }
+      // in a quote, either end the quote, start escape, or continue a token
+      else if (inQuote) {
+        if (ch == inQuoteChar) {
+          inQuote = false;
+          tokens.add(new String(token, 0, tokenLength, Shell.CHARSET));
+          tokenLength = 0;
+        } else if (ch == '\\') {
+          inEscapeSequence = true;
+        } else {
+          token[tokenLength++] = inputBytes[i];
+        }
+      }
+      // not in a quote, either enter a quote, end a token, start escape, or continue a token
+      else {
+        if (ch == '\'' || ch == '"') {
+          if (tokenLength > 0) {
+            tokens.add(new String(token, 0, tokenLength, Shell.CHARSET));
+            tokenLength = 0;
+          }
+          inQuote = true;
+          inQuoteChar = ch;
+        } else if (ch == ' ' && tokenLength > 0) {
+          tokens.add(new String(token, 0, tokenLength, Shell.CHARSET));
+          tokenLength = 0;
+        } else if (ch == '\\') {
+          inEscapeSequence = true;
+        } else if (ch != ' ') {
+          token[tokenLength++] = inputBytes[i];
+        }
+      }
+    }
+    if (inQuote) {
+      throw new BadArgumentException("missing terminating quote", input, input.length());
+    } else if (inEscapeSequence || hexChars != null) {
+      throw new BadArgumentException("escape sequence not complete", input, input.length());
+    }
+    if (tokenLength > 0) {
+      tokens.add(new String(token, 0, tokenLength, Shell.CHARSET));
+    }
+  }
+  
+  @Override
+  public Iterator<String> iterator() {
+    return tokens.iterator();
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/RenameNamespaceCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/RenameNamespaceCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/RenameNamespaceCommand.java
new file mode 100644
index 0000000..f456a30
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/RenameNamespaceCommand.java
@@ -0,0 +1,79 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.NamespaceExistsException;
+import org.apache.accumulo.core.client.NamespaceNotFoundException;
+import org.apache.accumulo.core.client.TableExistsException;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.core.client.impl.Namespaces;
+import org.apache.accumulo.core.client.impl.Tables;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Token;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+
+public class RenameNamespaceCommand extends Command {
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException,
+      TableNotFoundException, TableExistsException, NamespaceNotFoundException, NamespaceExistsException {
+    String old = cl.getArgs()[0];
+    String newer = cl.getArgs()[1];
+    boolean resetContext = false;
+    String currentTableId = "";
+    if (!(shellState.getTableName() == null) && !shellState.getTableName().isEmpty()) {
+      String namespaceId = Namespaces.getNamespaceId(shellState.getInstance(), old);
+      List<String> tableIds = Namespaces.getTableIds(shellState.getInstance(), namespaceId);
+      currentTableId = Tables.getTableId(shellState.getInstance(), shellState.getTableName());
+      resetContext = tableIds.contains(currentTableId);
+    }
+
+    shellState.getConnector().namespaceOperations().rename(old, newer);
+
+    if (resetContext) {
+      shellState.setTableName(Tables.getTableName(shellState.getInstance(), currentTableId));
+    }
+
+    return 0;
+  }
+
+  @Override
+  public String usage() {
+    return getName() + " <current namespace> <new namespace>";
+  }
+
+  @Override
+  public String description() {
+    return "renames a namespace";
+  }
+
+  @Override
+  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> special) {
+    registerCompletionForNamespaces(root, special);
+  }
+
+  @Override
+  public int numArgs() {
+    return 2;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/RenameTableCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/RenameTableCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/RenameTableCommand.java
new file mode 100644
index 0000000..a810320
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/RenameTableCommand.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.accumulo.shell.commands;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.TableExistsException;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.core.client.impl.Tables;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Token;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+
+public class RenameTableCommand extends Command {
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException,
+      TableNotFoundException, TableExistsException {
+    shellState.getConnector().tableOperations().rename(cl.getArgs()[0], cl.getArgs()[1]);
+    if (shellState.getTableName().equals(Tables.qualified(cl.getArgs()[0]))) {
+      shellState.setTableName(cl.getArgs()[1]);
+    }
+    return 0;
+  }
+
+  @Override
+  public String usage() {
+    return getName() + " <current table name> <new table name>";
+  }
+
+  @Override
+  public String description() {
+    return "renames a table";
+  }
+
+  @Override
+  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> completionSet) {
+    registerCompletionForTables(root, completionSet);
+  }
+
+  @Override
+  public int numArgs() {
+    return 2;
+  }
+}


[52/53] [abbrv] git commit: ACCUMULO-2650 Initial round of configuration parameters

Posted by el...@apache.org.
ACCUMULO-2650 Initial round of configuration parameters


Project: http://git-wip-us.apache.org/repos/asf/accumulo/repo
Commit: http://git-wip-us.apache.org/repos/asf/accumulo/commit/e01c8d99
Tree: http://git-wip-us.apache.org/repos/asf/accumulo/tree/e01c8d99
Diff: http://git-wip-us.apache.org/repos/asf/accumulo/diff/e01c8d99

Branch: refs/heads/ACCUMULO-378
Commit: e01c8d99b992795474bf4eac8f9d8a5978f540e4
Parents: d257001
Author: Josh Elser <el...@apache.org>
Authored: Mon Apr 7 22:58:41 2014 -0400
Committer: Josh Elser <el...@apache.org>
Committed: Mon Apr 7 23:01:24 2014 -0400

----------------------------------------------------------------------
 .../java/org/apache/accumulo/core/conf/Property.java | 15 +++++++++++++++
 1 file changed, 15 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/accumulo/blob/e01c8d99/core/src/main/java/org/apache/accumulo/core/conf/Property.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/conf/Property.java b/core/src/main/java/org/apache/accumulo/core/conf/Property.java
index 0502aae..7506022 100644
--- a/core/src/main/java/org/apache/accumulo/core/conf/Property.java
+++ b/core/src/main/java/org/apache/accumulo/core/conf/Property.java
@@ -437,6 +437,21 @@ public enum Property {
   GENERAL_MAVEN_PROJECT_BASEDIR(AccumuloClassLoader.MAVEN_PROJECT_BASEDIR_PROPERTY_NAME, AccumuloClassLoader.DEFAULT_MAVEN_PROJECT_BASEDIR_VALUE,
       PropertyType.ABSOLUTEPATH, "Set this to automatically add maven target/classes directories to your dynamic classpath"),
 
+  @Experimental
+  REPLICATION_PREFIX("replication.", null, PropertyType.PREFIX, "Properties in this category affect the replication of data to other Accumulo instances."),
+  @Experimental
+  REPLICATION_ENABLED("replication.enabled", "false", PropertyType.BOOLEAN, "Global switch to enable replication for the given instance"),
+  @Experimental
+  REPLICATION_SLAVES("replication.slave.", null, PropertyType.PREFIX, "Properties in this category control what systems data can be replicated to"),
+  @Experimental
+  REPLICATION_TABLES("replication.table.", null, PropertyType.PREFIX, "Properties in this category control table-specific replication configuration"),
+  @Experimental
+  REPLICATION_TABLET_SCAN_INTERVAL("replication.tablet.interval", "30s", PropertyType.TIMEDURATION, "Amount of time to sleep before scanning tablets for new replication data"),
+  @Experimental
+  REPLICATION_BATCH_SIZE("replication.batch.size", "1000", PropertyType.COUNT, "Maximum number of updates (WAL) or key-value pairs (RFile) to send in one replication task"),
+  @Experimental
+  REPLICATION_SEND_THREAD_POOL_SIZE("replication.send.threads", "1", PropertyType.COUNT, "Size of threadpool used to start replication to slaves"),
+  
   ;
 
   private String key, defaultValue, description;


[07/53] [abbrv] ACCUMULO-1897 Move shell into new package and module

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/Shell.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/Shell.java b/shell/src/main/java/org/apache/accumulo/shell/Shell.java
new file mode 100644
index 0000000..48d8bd0
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/Shell.java
@@ -0,0 +1,1168 @@
+/*
+ * 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.accumulo.shell;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.net.InetAddress;
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.UUID;
+
+import jline.console.ConsoleReader;
+import jline.console.UserInterruptException;
+import jline.console.history.FileHistory;
+
+import org.apache.accumulo.core.Constants;
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.ClientConfiguration;
+import org.apache.accumulo.core.client.ClientConfiguration.ClientProperty;
+import org.apache.accumulo.core.client.Connector;
+import org.apache.accumulo.core.client.Instance;
+import org.apache.accumulo.core.client.IteratorSetting;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.core.client.ZooKeeperInstance;
+import org.apache.accumulo.core.client.impl.ServerConfigurationUtil;
+import org.apache.accumulo.core.client.impl.Tables;
+import org.apache.accumulo.core.client.mock.MockInstance;
+import org.apache.accumulo.core.client.security.tokens.AuthenticationToken;
+import org.apache.accumulo.core.client.security.tokens.PasswordToken;
+import org.apache.accumulo.core.conf.AccumuloConfiguration;
+import org.apache.accumulo.core.conf.DefaultConfiguration;
+import org.apache.accumulo.core.conf.Property;
+import org.apache.accumulo.core.conf.SiteConfiguration;
+import org.apache.accumulo.core.data.Key;
+import org.apache.accumulo.core.data.Value;
+import org.apache.accumulo.core.data.thrift.TConstraintViolationSummary;
+import org.apache.accumulo.core.tabletserver.thrift.ConstraintViolationException;
+import org.apache.accumulo.core.trace.DistributedTrace;
+import org.apache.accumulo.core.util.BadArgumentException;
+import org.apache.accumulo.core.util.format.BinaryFormatter;
+import org.apache.accumulo.core.util.format.DefaultFormatter;
+import org.apache.accumulo.core.util.format.Formatter;
+import org.apache.accumulo.core.util.format.FormatterFactory;
+import org.apache.accumulo.core.volume.VolumeConfiguration;
+import org.apache.accumulo.core.zookeeper.ZooUtil;
+import org.apache.accumulo.fate.zookeeper.ZooReader;
+import org.apache.accumulo.shell.commands.AboutCommand;
+import org.apache.accumulo.shell.commands.AddAuthsCommand;
+import org.apache.accumulo.shell.commands.AddSplitsCommand;
+import org.apache.accumulo.shell.commands.AuthenticateCommand;
+import org.apache.accumulo.shell.commands.ByeCommand;
+import org.apache.accumulo.shell.commands.ClasspathCommand;
+import org.apache.accumulo.shell.commands.ClearCommand;
+import org.apache.accumulo.shell.commands.CloneTableCommand;
+import org.apache.accumulo.shell.commands.ClsCommand;
+import org.apache.accumulo.shell.commands.CompactCommand;
+import org.apache.accumulo.shell.commands.ConfigCommand;
+import org.apache.accumulo.shell.commands.ConstraintCommand;
+import org.apache.accumulo.shell.commands.CreateNamespaceCommand;
+import org.apache.accumulo.shell.commands.CreateTableCommand;
+import org.apache.accumulo.shell.commands.CreateUserCommand;
+import org.apache.accumulo.shell.commands.DUCommand;
+import org.apache.accumulo.shell.commands.DebugCommand;
+import org.apache.accumulo.shell.commands.DeleteCommand;
+import org.apache.accumulo.shell.commands.DeleteIterCommand;
+import org.apache.accumulo.shell.commands.DeleteManyCommand;
+import org.apache.accumulo.shell.commands.DeleteNamespaceCommand;
+import org.apache.accumulo.shell.commands.DeleteRowsCommand;
+import org.apache.accumulo.shell.commands.DeleteScanIterCommand;
+import org.apache.accumulo.shell.commands.DeleteShellIterCommand;
+import org.apache.accumulo.shell.commands.DeleteTableCommand;
+import org.apache.accumulo.shell.commands.DeleteUserCommand;
+import org.apache.accumulo.shell.commands.DropTableCommand;
+import org.apache.accumulo.shell.commands.DropUserCommand;
+import org.apache.accumulo.shell.commands.EGrepCommand;
+import org.apache.accumulo.shell.commands.ExecfileCommand;
+import org.apache.accumulo.shell.commands.ExitCommand;
+import org.apache.accumulo.shell.commands.ExportTableCommand;
+import org.apache.accumulo.shell.commands.ExtensionCommand;
+import org.apache.accumulo.shell.commands.FateCommand;
+import org.apache.accumulo.shell.commands.FlushCommand;
+import org.apache.accumulo.shell.commands.FormatterCommand;
+import org.apache.accumulo.shell.commands.GetAuthsCommand;
+import org.apache.accumulo.shell.commands.GetGroupsCommand;
+import org.apache.accumulo.shell.commands.GetSplitsCommand;
+import org.apache.accumulo.shell.commands.GrantCommand;
+import org.apache.accumulo.shell.commands.GrepCommand;
+import org.apache.accumulo.shell.commands.HelpCommand;
+import org.apache.accumulo.shell.commands.HiddenCommand;
+import org.apache.accumulo.shell.commands.HistoryCommand;
+import org.apache.accumulo.shell.commands.ImportDirectoryCommand;
+import org.apache.accumulo.shell.commands.ImportTableCommand;
+import org.apache.accumulo.shell.commands.InfoCommand;
+import org.apache.accumulo.shell.commands.InsertCommand;
+import org.apache.accumulo.shell.commands.InterpreterCommand;
+import org.apache.accumulo.shell.commands.ListCompactionsCommand;
+import org.apache.accumulo.shell.commands.ListIterCommand;
+import org.apache.accumulo.shell.commands.ListScansCommand;
+import org.apache.accumulo.shell.commands.ListShellIterCommand;
+import org.apache.accumulo.shell.commands.MaxRowCommand;
+import org.apache.accumulo.shell.commands.MergeCommand;
+import org.apache.accumulo.shell.commands.NamespacePermissionsCommand;
+import org.apache.accumulo.shell.commands.NamespacesCommand;
+import org.apache.accumulo.shell.commands.NoTableCommand;
+import org.apache.accumulo.shell.commands.OfflineCommand;
+import org.apache.accumulo.shell.commands.OnlineCommand;
+import org.apache.accumulo.shell.commands.PasswdCommand;
+import org.apache.accumulo.shell.commands.PingCommand;
+import org.apache.accumulo.shell.commands.QuestionCommand;
+import org.apache.accumulo.shell.commands.QuitCommand;
+import org.apache.accumulo.shell.commands.QuotedStringTokenizer;
+import org.apache.accumulo.shell.commands.RenameNamespaceCommand;
+import org.apache.accumulo.shell.commands.RenameTableCommand;
+import org.apache.accumulo.shell.commands.RevokeCommand;
+import org.apache.accumulo.shell.commands.ScanCommand;
+import org.apache.accumulo.shell.commands.ScriptCommand;
+import org.apache.accumulo.shell.commands.SetAuthsCommand;
+import org.apache.accumulo.shell.commands.SetGroupsCommand;
+import org.apache.accumulo.shell.commands.SetIterCommand;
+import org.apache.accumulo.shell.commands.SetScanIterCommand;
+import org.apache.accumulo.shell.commands.SetShellIterCommand;
+import org.apache.accumulo.shell.commands.SleepCommand;
+import org.apache.accumulo.shell.commands.SystemPermissionsCommand;
+import org.apache.accumulo.shell.commands.TableCommand;
+import org.apache.accumulo.shell.commands.TablePermissionsCommand;
+import org.apache.accumulo.shell.commands.TablesCommand;
+import org.apache.accumulo.shell.commands.TraceCommand;
+import org.apache.accumulo.shell.commands.UserCommand;
+import org.apache.accumulo.shell.commands.UserPermissionsCommand;
+import org.apache.accumulo.shell.commands.UsersCommand;
+import org.apache.accumulo.shell.commands.WhoAmICommand;
+import org.apache.commons.cli.BasicParser;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.HelpFormatter;
+import org.apache.commons.cli.MissingOptionException;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+import org.apache.commons.cli.ParseException;
+import org.apache.hadoop.fs.Path;
+import org.apache.log4j.Level;
+import org.apache.log4j.Logger;
+
+import com.beust.jcommander.JCommander;
+import com.beust.jcommander.ParameterException;
+
+/**
+ * A convenient console interface to perform basic accumulo functions Includes auto-complete, help, and quoted strings with escape sequences
+ */
+public class Shell extends ShellOptions {
+  public static final Logger log = Logger.getLogger(Shell.class);
+  private static final Logger audit = Logger.getLogger(Shell.class.getName() + ".audit");
+
+  public static final String CHARSET = "ISO-8859-1";
+  public static final int NO_FIXED_ARG_LENGTH_CHECK = -1;
+  public static final String COMMENT_PREFIX = "#";
+  public static final String HISTORY_DIR_NAME = ".accumulo";
+  public static final String HISTORY_FILE_NAME = "shell_history.txt";
+  private static final String SHELL_DESCRIPTION = "Shell - Apache Accumulo Interactive Shell";
+
+  protected int exitCode = 0;
+  private String tableName;
+  protected Instance instance;
+  private Connector connector;
+  protected ConsoleReader reader;
+  private String principal;
+  private AuthenticationToken token;
+  private final Class<? extends Formatter> defaultFormatterClass = DefaultFormatter.class;
+  private final Class<? extends Formatter> binaryFormatterClass = BinaryFormatter.class;
+  public Map<String,List<IteratorSetting>> scanIteratorOptions = new HashMap<String,List<IteratorSetting>>();
+  public Map<String,List<IteratorSetting>> iteratorProfiles = new HashMap<String,List<IteratorSetting>>();
+
+  private Token rootToken;
+  public final Map<String,Command> commandFactory = new TreeMap<String,Command>();
+  public final Map<String,Command[]> commandGrouping = new TreeMap<String,Command[]>();
+  protected boolean configError = false;
+
+  // exit if true
+  private boolean exit = false;
+
+  // file to execute commands from
+  protected File execFile = null;
+  // single command to execute from the command line
+  protected String execCommand = null;
+  protected boolean verbose = true;
+
+  private boolean tabCompletion;
+  private boolean disableAuthTimeout;
+  private long authTimeout;
+  private long lastUserActivity = System.currentTimeMillis();
+  private boolean logErrorsToConsole = false;
+  private PrintWriter writer = null;
+  private boolean masking = false;
+
+  public Shell() throws IOException {
+    this(new ConsoleReader(), new PrintWriter(
+        new OutputStreamWriter(System.out,
+        System.getProperty("jline.WindowsTerminal.output.encoding", System.getProperty("file.encoding")))));
+  }
+
+  public Shell(ConsoleReader reader, PrintWriter writer) {
+    super();
+    this.reader = reader;
+    this.writer = writer;
+  }
+
+  // Not for client use
+  public boolean config(String... args) {
+    ShellOptionsJC options = new ShellOptionsJC();
+    JCommander jc = new JCommander();
+
+    jc.setProgramName("accumulo shell");
+    jc.addObject(options);
+    try {
+      jc.parse(args);
+    } catch (ParameterException e) {
+      configError = true;
+    }
+
+    if (options.isHelpEnabled()) {
+      configError = true;
+    }
+
+    if (!configError && options.getUnrecognizedOptions() != null) {
+      configError = true;
+      logError("Unrecognized Options: " + options.getUnrecognizedOptions().toString());
+    }
+
+    if (configError) {
+      jc.usage();
+      return true;
+    }
+
+    setDebugging(options.isDebugEnabled());
+    authTimeout = options.getAuthTimeout() * 60 * 1000; // convert minutes to milliseconds
+    disableAuthTimeout = options.isAuthTimeoutDisabled();
+
+    // get the options that were parsed
+    String user = options.getUsername();
+    String password = options.getPassword();
+
+    tabCompletion = !options.isTabCompletionDisabled();
+
+    // Use a fake (Mock), ZK, or HdfsZK Accumulo instance
+    setInstance(options);
+
+    // AuthenticationToken options
+    token = options.getAuthenticationToken();
+    Map<String,String> loginOptions = options.getTokenProperties();
+
+    // process default parameters if unspecified
+    try {
+      boolean hasToken = (token != null);
+      boolean hasTokenOptions = !loginOptions.isEmpty();
+
+      if (hasToken && password != null) {
+        throw new ParameterException("Can not supply '--pass' option with '--tokenClass' option");
+      }
+
+      Runtime.getRuntime().addShutdownHook(new Thread() {
+        @Override
+        public void run() {
+          reader.getTerminal().setEchoEnabled(true);
+        }
+      });
+
+      // Need either both a token and options, or neither, but not just one.
+      if (hasToken != hasTokenOptions) {
+        throw new ParameterException("Must supply either both or neither of '--tokenClass' and '--tokenProperty'");
+      } else if (hasToken) { // implied hasTokenOptions
+        // Fully qualified name so we don't shadow java.util.Properties
+        org.apache.accumulo.core.client.security.tokens.AuthenticationToken.Properties props;
+        // and line wrap it because the package name is so long
+        props = new org.apache.accumulo.core.client.security.tokens.AuthenticationToken.Properties();
+
+        props.putAllStrings(loginOptions);
+        token.init(props);
+      } else {
+        // Read password if the user explicitly asked for it, or didn't specify anything at all
+        if ("stdin".equals(password) || password == null) {
+          password = reader.readLine("Password: ", '*');
+        }
+
+        if (password == null) {
+          // User cancel, e.g. Ctrl-D pressed
+          throw new ParameterException("No password or token option supplied");
+        } else {
+          this.token = new PasswordToken(password);
+        }
+      }
+
+      if (!options.isFake()) {
+        ZooReader zr = new ZooReader(instance.getZooKeepers(), instance.getZooKeepersSessionTimeOut());
+        DistributedTrace.enable(instance, zr, "shell", InetAddress.getLocalHost().getHostName());
+      }
+
+      this.setTableName("");
+      this.principal = user;
+      connector = instance.getConnector(this.principal, token);
+
+    } catch (Exception e) {
+      printException(e);
+      configError = true;
+    }
+
+    // decide whether to execute commands from a file and quit
+    if (options.getExecFile() != null) {
+      execFile = options.getExecFile();
+      verbose = false;
+    } else if (options.getExecFileVerbose() != null) {
+      execFile = options.getExecFileVerbose();
+      verbose = true;
+    }
+    execCommand = options.getExecCommand();
+    if (execCommand != null) {
+      verbose = false;
+    }
+
+    rootToken = new Token();
+
+    Command[] dataCommands = {new DeleteCommand(), new DeleteManyCommand(), new DeleteRowsCommand(), new EGrepCommand(), new FormatterCommand(),
+        new InterpreterCommand(), new GrepCommand(), new ImportDirectoryCommand(), new InsertCommand(), new MaxRowCommand(), new ScanCommand()};
+    Command[] debuggingCommands = {new ClasspathCommand(), new DebugCommand(), new ListScansCommand(), new ListCompactionsCommand(), new TraceCommand(),
+        new PingCommand()};
+    Command[] execCommands = {new ExecfileCommand(), new HistoryCommand(), new ExtensionCommand(), new ScriptCommand()};
+    Command[] exitCommands = {new ByeCommand(), new ExitCommand(), new QuitCommand()};
+    Command[] helpCommands = {new AboutCommand(), new HelpCommand(), new InfoCommand(), new QuestionCommand()};
+    Command[] iteratorCommands = {new DeleteIterCommand(), new DeleteScanIterCommand(), new ListIterCommand(), new SetIterCommand(), new SetScanIterCommand(),
+        new SetShellIterCommand(), new ListShellIterCommand(), new DeleteShellIterCommand()};
+    Command[] otherCommands = {new HiddenCommand()};
+    Command[] permissionsCommands = {new GrantCommand(), new RevokeCommand(), new SystemPermissionsCommand(), new TablePermissionsCommand(),
+        new UserPermissionsCommand(), new NamespacePermissionsCommand()};
+    Command[] stateCommands = {new AuthenticateCommand(), new ClsCommand(), new ClearCommand(), new FateCommand(), new NoTableCommand(), new SleepCommand(),
+        new TableCommand(), new UserCommand(), new WhoAmICommand()};
+    Command[] tableCommands = {new CloneTableCommand(), new ConfigCommand(), new CreateTableCommand(), new DeleteTableCommand(), new DropTableCommand(),
+        new DUCommand(), new ExportTableCommand(), new ImportTableCommand(), new OfflineCommand(), new OnlineCommand(), new RenameTableCommand(),
+        new TablesCommand(), new NamespacesCommand(), new CreateNamespaceCommand(), new DeleteNamespaceCommand(), new RenameNamespaceCommand()};
+    Command[] tableControlCommands = {new AddSplitsCommand(), new CompactCommand(), new ConstraintCommand(), new FlushCommand(), new GetGroupsCommand(),
+        new GetSplitsCommand(), new MergeCommand(), new SetGroupsCommand()};
+    Command[] userCommands = {new AddAuthsCommand(), new CreateUserCommand(), new DeleteUserCommand(), new DropUserCommand(), new GetAuthsCommand(),
+        new PasswdCommand(), new SetAuthsCommand(), new UsersCommand()};
+    commandGrouping.put("-- Writing, Reading, and Removing Data --", dataCommands);
+    commandGrouping.put("-- Debugging Commands -------------------", debuggingCommands);
+    commandGrouping.put("-- Shell Execution Commands -------------", execCommands);
+    commandGrouping.put("-- Exiting Commands ---------------------", exitCommands);
+    commandGrouping.put("-- Help Commands ------------------------", helpCommands);
+    commandGrouping.put("-- Iterator Configuration ---------------", iteratorCommands);
+    commandGrouping.put("-- Permissions Administration Commands --", permissionsCommands);
+    commandGrouping.put("-- Shell State Commands -----------------", stateCommands);
+    commandGrouping.put("-- Table Administration Commands --------", tableCommands);
+    commandGrouping.put("-- Table Control Commands ---------------", tableControlCommands);
+    commandGrouping.put("-- User Administration Commands ---------", userCommands);
+
+    for (Command[] cmds : commandGrouping.values()) {
+      for (Command cmd : cmds)
+        commandFactory.put(cmd.getName(), cmd);
+    }
+    for (Command cmd : otherCommands) {
+      commandFactory.put(cmd.getName(), cmd);
+    }
+    return configError;
+  }
+
+  /**
+   * Sets the instance used by the shell based on the given options.
+   * 
+   * @param options
+   *          shell options
+   */
+  protected void setInstance(ShellOptionsJC options) {
+    // should only be one set of instance options set
+    instance = null;
+    if (options.isFake()) {
+      instance = new MockInstance("fake");
+    } else {
+      String instanceName, hosts;
+      if (options.isHdfsZooInstance()) {
+        instanceName = hosts = null;
+      } else if (options.getZooKeeperInstance().size() > 0) {
+        List<String> zkOpts = options.getZooKeeperInstance();
+        instanceName = zkOpts.get(0);
+        hosts = zkOpts.get(1);
+      } else {
+        instanceName = options.getZooKeeperInstanceName();
+        hosts = options.getZooKeeperHosts();
+      }
+      try {
+        instance = getZooInstance(instanceName, hosts, options.getClientConfiguration());
+      } catch (Exception e) {
+        throw new IllegalArgumentException("Unable to load client config from " + options.getClientConfigFile(), e);
+      }
+    }
+  }
+
+  /*
+   * Takes instanceName and keepers as separate arguments, rather than just packaged into the clientConfig, so that we can fail over to accumulo-site.xml or
+   * HDFS config if they're unspecified.
+   */
+  private static Instance getZooInstance(String instanceName, String keepers, ClientConfiguration clientConfig) {
+    UUID instanceId = null;
+    if (instanceName == null) {
+      instanceName = clientConfig.get(ClientProperty.INSTANCE_NAME);
+    }
+    if (instanceName == null || keepers == null) {
+      AccumuloConfiguration conf = SiteConfiguration.getInstance(ServerConfigurationUtil.convertClientConfig(DefaultConfiguration.getInstance(), clientConfig));
+      if (instanceName == null) {
+        Path instanceDir = new Path(VolumeConfiguration.getVolumeUris(conf)[0], "instance_id");
+        instanceId = UUID.fromString(ZooUtil.getInstanceIDFromHdfs(instanceDir, conf));
+      }
+      if (keepers == null) {
+        keepers = conf.get(Property.INSTANCE_ZK_HOST);
+      }
+    }
+    if (instanceId != null) {
+      return new ZooKeeperInstance(clientConfig.withInstance(instanceId).withZkHosts(keepers));
+    } else {
+      return new ZooKeeperInstance(clientConfig.withInstance(instanceName).withZkHosts(keepers));
+    }
+  }
+
+  public Connector getConnector() {
+    return connector;
+  }
+
+  public Instance getInstance() {
+    return instance;
+  }
+
+  public static void main(String args[]) throws IOException {
+    Shell shell = new Shell();
+    try {
+      shell.config(args);
+
+      System.exit(shell.start());
+    } finally {
+      shell.shutdown();
+    }
+  }
+
+  public int start() throws IOException {
+    if (configError)
+      return 1;
+
+    String input;
+    if (isVerbose())
+      printInfo();
+
+    String home = System.getProperty("HOME");
+    if (home == null)
+      home = System.getenv("HOME");
+    String configDir = home + "/" + HISTORY_DIR_NAME;
+    String historyPath = configDir + "/" + HISTORY_FILE_NAME;
+    File accumuloDir = new File(configDir);
+    if (!accumuloDir.exists() && !accumuloDir.mkdirs())
+      log.warn("Unable to make directory for history at " + accumuloDir);
+    try {
+      final FileHistory history = new FileHistory(new File(historyPath));
+      reader.setHistory(history);
+      // Add shutdown hook to flush file history, per jline javadocs
+      Runtime.getRuntime().addShutdownHook(new Thread() {
+        @Override
+        public void run() {
+          try {
+            history.flush();
+          } catch (IOException e) {
+            log.warn("Could not flush history to file.");
+          }
+        }
+      });
+    } catch (IOException e) {
+      log.warn("Unable to load history file at " + historyPath);
+    }
+
+    // Turn Ctrl+C into Exception instead of JVM exit
+    reader.setHandleUserInterrupt(true);
+
+    ShellCompletor userCompletor = null;
+
+    if (execFile != null) {
+      java.util.Scanner scanner = new java.util.Scanner(execFile, StandardCharsets.UTF_8.name());
+      try {
+        while (scanner.hasNextLine() && !hasExited()) {
+          execCommand(scanner.nextLine(), true, isVerbose());
+        }
+      } finally {
+        scanner.close();
+      }
+    } else if (execCommand != null) {
+      for (String command : execCommand.split("\n")) {
+        execCommand(command, true, isVerbose());
+      }
+      return exitCode;
+    }
+
+    while (true) {
+      try {
+        if (hasExited())
+          return exitCode;
+
+        // If tab completion is true we need to reset
+        if (tabCompletion) {
+          if (userCompletor != null)
+            reader.removeCompleter(userCompletor);
+
+          userCompletor = setupCompletion();
+          reader.addCompleter(userCompletor);
+        }
+
+        reader.setPrompt(getDefaultPrompt());
+        input = reader.readLine();
+        if (input == null) {
+          reader.println();
+          return exitCode;
+        } // User Canceled (Ctrl+D)
+
+        execCommand(input, disableAuthTimeout, false);
+      } catch (UserInterruptException uie) {
+        // User Cancelled (Ctrl+C)
+        reader.println();
+
+        String partialLine = uie.getPartialLine();
+        if (partialLine == null || "".equals(uie.getPartialLine().trim())) {
+          // No content, actually exit
+          return exitCode;
+        }
+      } finally {
+        reader.flush();
+      }
+    }
+  }
+
+  public void shutdown() {
+    if (reader != null) {
+      reader.shutdown();
+    }
+  }
+
+  public void printInfo() throws IOException {
+    reader.print("\n" + SHELL_DESCRIPTION + "\n" + "- \n" + "- version: " + Constants.VERSION + "\n" + "- instance name: "
+        + connector.getInstance().getInstanceName() + "\n" + "- instance id: " + connector.getInstance().getInstanceID() + "\n" + "- \n"
+        + "- type 'help' for a list of available commands\n" + "- \n");
+    reader.flush();
+  }
+
+  public void printVerboseInfo() throws IOException {
+    StringBuilder sb = new StringBuilder("-\n");
+    sb.append("- Current user: ").append(connector.whoami()).append("\n");
+    if (execFile != null)
+      sb.append("- Executing commands from: ").append(execFile).append("\n");
+    if (disableAuthTimeout)
+      sb.append("- Authorization timeout: disabled\n");
+    else
+      sb.append("- Authorization timeout: ").append(String.format("%.2fs%n", authTimeout / 1000.0));
+    sb.append("- Debug: ").append(isDebuggingEnabled() ? "on" : "off").append("\n");
+    if (!scanIteratorOptions.isEmpty()) {
+      for (Entry<String,List<IteratorSetting>> entry : scanIteratorOptions.entrySet()) {
+        sb.append("- Session scan iterators for table ").append(entry.getKey()).append(":\n");
+        for (IteratorSetting setting : entry.getValue()) {
+          sb.append("-    Iterator ").append(setting.getName()).append(" options:\n");
+          sb.append("-        ").append("iteratorPriority").append(" = ").append(setting.getPriority()).append("\n");
+          sb.append("-        ").append("iteratorClassName").append(" = ").append(setting.getIteratorClass()).append("\n");
+          for (Entry<String,String> optEntry : setting.getOptions().entrySet()) {
+            sb.append("-        ").append(optEntry.getKey()).append(" = ").append(optEntry.getValue()).append("\n");
+          }
+        }
+      }
+    }
+    sb.append("-\n");
+    reader.print(sb.toString());
+  }
+
+  public String getDefaultPrompt() {
+    return connector.whoami() + "@" + connector.getInstance().getInstanceName() + (getTableName().isEmpty() ? "" : " ") + getTableName() + "> ";
+  }
+
+  public void execCommand(String input, boolean ignoreAuthTimeout, boolean echoPrompt) throws IOException {
+    audit.log(Level.INFO, getDefaultPrompt() + input);
+    if (echoPrompt) {
+      reader.print(getDefaultPrompt());
+      reader.println(input);
+    }
+
+    if (input.startsWith(COMMENT_PREFIX)) {
+      return;
+    }
+
+    String fields[];
+    try {
+      fields = new QuotedStringTokenizer(input).getTokens();
+    } catch (BadArgumentException e) {
+      printException(e);
+      ++exitCode;
+      return;
+    }
+    if (fields.length == 0)
+      return;
+
+    String command = fields[0];
+    fields = fields.length > 1 ? Arrays.copyOfRange(fields, 1, fields.length) : new String[] {};
+
+    Command sc = null;
+    if (command.length() > 0) {
+      try {
+        // Obtain the command from the command table
+        sc = commandFactory.get(command);
+        if (sc == null) {
+          reader.println(String.format("Unknown command \"%s\".  Enter \"help\" for a list possible commands.", command));
+          reader.flush();
+          return;
+        }
+
+        if (!(sc instanceof ExitCommand) && !ignoreAuthTimeout && System.currentTimeMillis() - lastUserActivity > authTimeout) {
+          reader.println("Shell has been idle for too long. Please re-authenticate.");
+          boolean authFailed = true;
+          do {
+            String pwd = readMaskedLine("Enter current password for '" + connector.whoami() + "': ", '*');
+            if (pwd == null) {
+              reader.println();
+              return;
+            } // user canceled
+
+            try {
+              authFailed = !connector.securityOperations().authenticateUser(connector.whoami(), new PasswordToken(pwd));
+            } catch (Exception e) {
+              ++exitCode;
+              printException(e);
+            }
+
+            if (authFailed)
+              reader.print("Invalid password. ");
+          } while (authFailed);
+          lastUserActivity = System.currentTimeMillis();
+        }
+
+        // Get the options from the command on how to parse the string
+        Options parseOpts = sc.getOptionsWithHelp();
+
+        // Parse the string using the given options
+        CommandLine cl = new BasicParser().parse(parseOpts, fields);
+
+        int actualArgLen = cl.getArgs().length;
+        int expectedArgLen = sc.numArgs();
+        if (cl.hasOption(helpOption)) {
+          // Display help if asked to; otherwise execute the command
+          sc.printHelp(this);
+        } else if (expectedArgLen != NO_FIXED_ARG_LENGTH_CHECK && actualArgLen != expectedArgLen) {
+          ++exitCode;
+          // Check for valid number of fixed arguments (if not
+          // negative; negative means it is not checked, for
+          // vararg-like commands)
+          printException(new IllegalArgumentException(String.format("Expected %d argument%s. There %s %d.", expectedArgLen, expectedArgLen == 1 ? "" : "s",
+              actualArgLen == 1 ? "was" : "were", actualArgLen)));
+          sc.printHelp(this);
+        } else {
+          int tmpCode = sc.execute(input, cl, this);
+          exitCode += tmpCode;
+          reader.flush();
+        }
+
+      } catch (ConstraintViolationException e) {
+        ++exitCode;
+        printConstraintViolationException(e);
+      } catch (TableNotFoundException e) {
+        ++exitCode;
+        if (getTableName().equals(e.getTableName()))
+          setTableName("");
+        printException(e);
+      } catch (ParseException e) {
+        // not really an error if the exception is a missing required
+        // option when the user is asking for help
+        if (!(e instanceof MissingOptionException && (Arrays.asList(fields).contains("-" + helpOption) || Arrays.asList(fields).contains("--" + helpLongOption)))) {
+          ++exitCode;
+          printException(e);
+        }
+        if (sc != null)
+          sc.printHelp(this);
+      } catch (UserInterruptException e) {
+        ++exitCode;
+      } catch (Exception e) {
+        ++exitCode;
+        printException(e);
+      }
+    } else {
+      ++exitCode;
+      printException(new BadArgumentException("Unrecognized empty command", command, -1));
+    }
+    reader.flush();
+  }
+
+  /**
+   * The command tree is built in reverse so that the references are more easily linked up. There is some code in token to allow forward building of the command
+   * tree.
+   */
+  private ShellCompletor setupCompletion() {
+    rootToken = new Token();
+
+    Set<String> tableNames = null;
+    try {
+      tableNames = connector.tableOperations().list();
+    } catch (Exception e) {
+      log.debug("Unable to obtain list of tables", e);
+      tableNames = Collections.emptySet();
+    }
+
+    Set<String> userlist = null;
+    try {
+      userlist = connector.securityOperations().listLocalUsers();
+    } catch (Exception e) {
+      log.debug("Unable to obtain list of users", e);
+      userlist = Collections.emptySet();
+    }
+
+    Set<String> namespaces = null;
+    try {
+      namespaces = connector.namespaceOperations().list();
+    } catch (Exception e) {
+      log.debug("Unable to obtain list of namespaces", e);
+      namespaces = Collections.emptySet();
+    }
+
+    Map<Command.CompletionSet,Set<String>> options = new HashMap<Command.CompletionSet,Set<String>>();
+
+    Set<String> commands = new HashSet<String>();
+    for (String a : commandFactory.keySet())
+      commands.add(a);
+
+    Set<String> modifiedUserlist = new HashSet<String>();
+    Set<String> modifiedTablenames = new HashSet<String>();
+    Set<String> modifiedNamespaces = new HashSet<String>();
+
+    for (String a : tableNames)
+      modifiedTablenames.add(a.replaceAll("([\\s'\"])", "\\\\$1"));
+    for (String a : userlist)
+      modifiedUserlist.add(a.replaceAll("([\\s'\"])", "\\\\$1"));
+    for (String a : namespaces) {
+      String b = a.replaceAll("([\\s'\"])", "\\\\$1");
+      modifiedNamespaces.add(b.isEmpty() ? "\"\"" : b);
+    }
+
+    options.put(Command.CompletionSet.USERNAMES, modifiedUserlist);
+    options.put(Command.CompletionSet.TABLENAMES, modifiedTablenames);
+    options.put(Command.CompletionSet.NAMESPACES, modifiedNamespaces);
+    options.put(Command.CompletionSet.COMMANDS, commands);
+
+    for (Command[] cmdGroup : commandGrouping.values()) {
+      for (Command c : cmdGroup) {
+        c.getOptionsWithHelp(); // prep the options for the command
+        // so that the completion can
+        // include them
+        c.registerCompletion(rootToken, options);
+      }
+    }
+    return new ShellCompletor(rootToken, options);
+  }
+
+  /**
+   * The Command class represents a command to be run in the shell. It contains the methods to execute along with some methods to help tab completion, and
+   * return the command name, help, and usage.
+   */
+  public static abstract class Command {
+    // Helper methods for completion
+    public enum CompletionSet {
+      TABLENAMES, USERNAMES, COMMANDS, NAMESPACES
+    }
+
+    static Set<String> getCommandNames(Map<CompletionSet,Set<String>> objects) {
+      return objects.get(CompletionSet.COMMANDS);
+    }
+
+    static Set<String> getTableNames(Map<CompletionSet,Set<String>> objects) {
+      return objects.get(CompletionSet.TABLENAMES);
+    }
+
+    static Set<String> getUserNames(Map<CompletionSet,Set<String>> objects) {
+      return objects.get(CompletionSet.USERNAMES);
+    }
+
+    static Set<String> getNamespaces(Map<CompletionSet,Set<String>> objects) {
+      return objects.get(CompletionSet.NAMESPACES);
+    }
+
+    public void registerCompletionGeneral(Token root, Set<String> args, boolean caseSens) {
+      Token t = new Token(args);
+      t.setCaseSensitive(caseSens);
+
+      Token command = new Token(getName());
+      command.addSubcommand(t);
+
+      root.addSubcommand(command);
+    }
+
+    public void registerCompletionForTables(Token root, Map<CompletionSet,Set<String>> completionSet) {
+      registerCompletionGeneral(root, completionSet.get(CompletionSet.TABLENAMES), true);
+    }
+
+    public void registerCompletionForUsers(Token root, Map<CompletionSet,Set<String>> completionSet) {
+      registerCompletionGeneral(root, completionSet.get(CompletionSet.USERNAMES), true);
+    }
+
+    public void registerCompletionForCommands(Token root, Map<CompletionSet,Set<String>> completionSet) {
+      registerCompletionGeneral(root, completionSet.get(CompletionSet.COMMANDS), false);
+    }
+
+    public void registerCompletionForNamespaces(Token root, Map<CompletionSet,Set<String>> completionSet) {
+      registerCompletionGeneral(root, completionSet.get(CompletionSet.NAMESPACES), true);
+    }
+
+    // abstract methods to override
+    public abstract int execute(String fullCommand, CommandLine cl, Shell shellState) throws Exception;
+
+    public abstract String description();
+
+    /**
+     * If the number of arguments is not always zero (not including those arguments handled through Options), make sure to override the {@link #usage()} method.
+     * Otherwise, {@link #usage()} does need to be overridden.
+     */
+    public abstract int numArgs();
+
+    // OPTIONAL methods to override:
+
+    // the general version of getname uses reflection to get the class name
+    // and then cuts off the suffix -Command to get the name of the command
+    public String getName() {
+      String s = this.getClass().getName();
+      int st = Math.max(s.lastIndexOf('$'), s.lastIndexOf('.'));
+      int i = s.indexOf("Command");
+      return i > 0 ? s.substring(st + 1, i).toLowerCase(Locale.ENGLISH) : null;
+    }
+
+    // The general version of this method adds the name
+    // of the command to the completion tree
+    public void registerCompletion(Token root, Map<CompletionSet,Set<String>> completion_set) {
+      root.addSubcommand(new Token(getName()));
+    }
+
+    // The general version of this method uses the HelpFormatter
+    // that comes with the apache Options package to print out the help
+    public final void printHelp(Shell shellState) {
+      shellState.printHelp(usage(), "description: " + this.description(), getOptionsWithHelp());
+    }
+
+    public final void printHelp(Shell shellState, int width) {
+      shellState.printHelp(usage(), "description: " + this.description(), getOptionsWithHelp(), width);
+    }
+
+    // Get options with help
+    public final Options getOptionsWithHelp() {
+      Options opts = getOptions();
+      opts.addOption(new Option(helpOption, helpLongOption, false, "display this help"));
+      return opts;
+    }
+
+    // General usage is just the command
+    public String usage() {
+      return getName();
+    }
+
+    // General Options are empty
+    public Options getOptions() {
+      return new Options();
+    }
+  }
+
+  public interface PrintLine {
+    void print(String s);
+
+    void close();
+  }
+
+  public static class PrintShell implements PrintLine {
+    ConsoleReader reader;
+
+    public PrintShell(ConsoleReader reader) {
+      this.reader = reader;
+    }
+
+    @Override
+    public void print(String s) {
+      try {
+        reader.println(s);
+      } catch (Exception ex) {
+        throw new RuntimeException(ex);
+      }
+    }
+
+    @Override
+    public void close() {}
+  };
+
+  public static class PrintFile implements PrintLine {
+    PrintWriter writer;
+
+    public PrintFile(String filename) throws FileNotFoundException {
+      writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(filename), StandardCharsets.UTF_8)));
+    }
+
+    @Override
+    public void print(String s) {
+      writer.println(s);
+    }
+
+    @Override
+    public void close() {
+      writer.close();
+    }
+  };
+
+  public final void printLines(Iterator<String> lines, boolean paginate) throws IOException {
+    printLines(lines, paginate, null);
+  }
+
+  public final void printLines(Iterator<String> lines, boolean paginate, PrintLine out) throws IOException {
+    int linesPrinted = 0;
+    String prompt = "-- hit any key to continue or 'q' to quit --";
+    int lastPromptLength = prompt.length();
+    int termWidth = reader.getTerminal().getWidth();
+    int maxLines = reader.getTerminal().getHeight();
+
+    String peek = null;
+    while (lines.hasNext()) {
+      String nextLine = lines.next();
+      if (nextLine == null)
+        continue;
+      for (String line : nextLine.split("\\n")) {
+        if (out == null) {
+          if (peek != null) {
+            reader.println(peek);
+            if (paginate) {
+              linesPrinted += peek.length() == 0 ? 0 : Math.ceil(peek.length() * 1.0 / termWidth);
+
+              // check if displaying the next line would result in
+              // scrolling off the screen
+              if (linesPrinted + Math.ceil(lastPromptLength * 1.0 / termWidth) + Math.ceil(prompt.length() * 1.0 / termWidth)
+                  + Math.ceil(line.length() * 1.0 / termWidth) > maxLines) {
+                linesPrinted = 0;
+                int numdashes = (termWidth - prompt.length()) / 2;
+                String nextPrompt = repeat("-", numdashes) + prompt + repeat("-", numdashes);
+                lastPromptLength = nextPrompt.length();
+                reader.print(nextPrompt);
+                reader.flush();
+
+                if (Character.toUpperCase((char) reader.readCharacter()) == 'Q') {
+                  reader.println();
+                  return;
+                }
+                reader.println();
+                termWidth = reader.getTerminal().getWidth();
+                maxLines = reader.getTerminal().getHeight();
+              }
+            }
+          }
+          peek = line;
+        } else {
+          out.print(line);
+        }
+      }
+    }
+    if (out == null && peek != null) {
+      reader.println(peek);
+    }
+  }
+
+  public final void printRecords(Iterable<Entry<Key,Value>> scanner, boolean printTimestamps, boolean paginate, Class<? extends Formatter> formatterClass,
+      PrintLine outFile) throws IOException {
+    printLines(FormatterFactory.getFormatter(formatterClass, scanner, printTimestamps), paginate, outFile);
+  }
+
+  public final void printRecords(Iterable<Entry<Key,Value>> scanner, boolean printTimestamps, boolean paginate, Class<? extends Formatter> formatterClass)
+      throws IOException {
+    printLines(FormatterFactory.getFormatter(formatterClass, scanner, printTimestamps), paginate);
+  }
+
+  public final void printBinaryRecords(Iterable<Entry<Key,Value>> scanner, boolean printTimestamps, boolean paginate, PrintLine outFile) throws IOException {
+    printLines(FormatterFactory.getFormatter(binaryFormatterClass, scanner, printTimestamps), paginate, outFile);
+  }
+
+  public final void printBinaryRecords(Iterable<Entry<Key,Value>> scanner, boolean printTimestamps, boolean paginate) throws IOException {
+    printLines(FormatterFactory.getFormatter(binaryFormatterClass, scanner, printTimestamps), paginate);
+  }
+
+  public static String repeat(String s, int c) {
+    StringBuilder sb = new StringBuilder();
+    for (int i = 0; i < c; i++)
+      sb.append(s);
+    return sb.toString();
+  }
+
+  public void checkTableState() {
+    if (getTableName().isEmpty())
+      throw new IllegalStateException(
+          "Not in a table context. Please use 'table <tableName>' to switch to a table, or use '-t' to specify a table if option is available.");
+  }
+
+  private final void printConstraintViolationException(ConstraintViolationException cve) {
+    printException(cve, "");
+    int COL1 = 50, COL2 = 14;
+    int col3 = Math.max(1, Math.min(Integer.MAX_VALUE, reader.getTerminal().getWidth() - COL1 - COL2 - 6));
+    logError(String.format("%" + COL1 + "s-+-%" + COL2 + "s-+-%" + col3 + "s%n", repeat("-", COL1), repeat("-", COL2), repeat("-", col3)));
+    logError(String.format("%-" + COL1 + "s | %" + COL2 + "s | %-" + col3 + "s%n", "Constraint class", "Violation code", "Violation Description"));
+    logError(String.format("%" + COL1 + "s-+-%" + COL2 + "s-+-%" + col3 + "s%n", repeat("-", COL1), repeat("-", COL2), repeat("-", col3)));
+    for (TConstraintViolationSummary cvs : cve.violationSummaries)
+      logError(String.format("%-" + COL1 + "s | %" + COL2 + "d | %-" + col3 + "s%n", cvs.constrainClass, cvs.violationCode, cvs.violationDescription));
+    logError(String.format("%" + COL1 + "s-+-%" + COL2 + "s-+-%" + col3 + "s%n", repeat("-", COL1), repeat("-", COL2), repeat("-", col3)));
+  }
+
+  public final void printException(Exception e) {
+    printException(e, e.getMessage());
+  }
+
+  private final void printException(Exception e, String msg) {
+    logError(e.getClass().getName() + (msg != null ? ": " + msg : ""));
+    log.debug(e.getClass().getName() + (msg != null ? ": " + msg : ""), e);
+  }
+
+  public static final void setDebugging(boolean debuggingEnabled) {
+    Logger.getLogger(Constants.CORE_PACKAGE_NAME).setLevel(debuggingEnabled ? Level.TRACE : Level.INFO);
+  }
+
+  public static final boolean isDebuggingEnabled() {
+    return Logger.getLogger(Constants.CORE_PACKAGE_NAME).isTraceEnabled();
+  }
+
+  private final void printHelp(String usage, String description, Options opts) {
+    printHelp(usage, description, opts, Integer.MAX_VALUE);
+  }
+
+  private final void printHelp(String usage, String description, Options opts, int width) {
+    // TODO Use the OutputStream from the JLine ConsoleReader if we can ever get access to it
+    new HelpFormatter().printHelp(writer, width, usage, description, opts, 2, 5, null, true);
+    writer.flush();
+  }
+
+  public int getExitCode() {
+    return exitCode;
+  }
+
+  public void resetExitCode() {
+    exitCode = 0;
+  }
+
+  public void setExit(boolean exit) {
+    this.exit = exit;
+  }
+
+  public boolean getExit() {
+    return this.exit;
+  }
+
+  public boolean isVerbose() {
+    return verbose;
+  }
+
+  public void setTableName(String tableName) {
+    this.tableName = (tableName == null || tableName.isEmpty()) ? "" : Tables.qualified(tableName);
+  }
+
+  public String getTableName() {
+    return tableName;
+  }
+
+  public ConsoleReader getReader() {
+    return reader;
+  }
+
+  public void updateUser(String principal, AuthenticationToken token) throws AccumuloException, AccumuloSecurityException {
+    connector = instance.getConnector(principal, token);
+    this.principal = principal;
+    this.token = token;
+  }
+
+  public String getPrincipal() {
+    return principal;
+  }
+
+  public AuthenticationToken getToken() {
+    return token;
+  }
+
+  /**
+   * Return the formatter for the current table.
+   * 
+   * @return the formatter class for the current table
+   */
+  public Class<? extends Formatter> getFormatter() {
+    return getFormatter(this.tableName);
+  }
+
+  /**
+   * Return the formatter for the given table.
+   * 
+   * @param tableName
+   *          the table name
+   * @return the formatter class for the given table
+   */
+  public Class<? extends Formatter> getFormatter(String tableName) {
+    Class<? extends Formatter> formatter = FormatterCommand.getCurrentFormatter(tableName, this);
+
+    if (null == formatter) {
+      logError("Could not load the specified formatter. Using the DefaultFormatter");
+      return this.defaultFormatterClass;
+    } else {
+      return formatter;
+    }
+  }
+
+  public void setLogErrorsToConsole() {
+    this.logErrorsToConsole = true;
+  }
+
+  private void logError(String s) {
+    log.error(s);
+    if (logErrorsToConsole) {
+      try {
+        reader.println("ERROR: " + s);
+        reader.flush();
+      } catch (IOException e) {}
+    }
+  }
+
+  public String readMaskedLine(String prompt, Character mask) throws IOException {
+    this.masking = true;
+    String s = reader.readLine(prompt, mask);
+    this.masking = false;
+    return s;
+  }
+
+  public boolean isMasking() {
+    return masking;
+  }
+
+  public boolean hasExited() {
+    return exit;
+  }
+
+  public boolean isTabCompletion() {
+    return tabCompletion;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/ShellCommandException.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/ShellCommandException.java b/shell/src/main/java/org/apache/accumulo/shell/ShellCommandException.java
new file mode 100644
index 0000000..b25e9da
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/ShellCommandException.java
@@ -0,0 +1,59 @@
+/*
+ * 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.accumulo.shell;
+
+public class ShellCommandException extends Exception {
+  private static final long serialVersionUID = 1L;
+  
+  public enum ErrorCode {
+    UNKNOWN_ERROR("Unknown error"),
+    UNSUPPORTED_LANGUAGE("Programming language used is not supported"),
+    UNRECOGNIZED_COMMAND("Command is not supported"),
+    INITIALIZATION_FAILURE("Command could not be initialized"),
+    XML_PARSING_ERROR("Failed to parse the XML file");
+    
+    private String description;
+    
+    private ErrorCode(String description) {
+      this.description = description;
+    }
+    
+    public String getDescription() {
+      return this.description;
+    }
+    
+    public String toString() {
+      return getDescription();
+    }
+  }
+  
+  private ErrorCode code;
+  private String command;
+  
+  public ShellCommandException(ErrorCode code) {
+    this(code, null);
+  }
+  
+  public ShellCommandException(ErrorCode code, String command) {
+    this.code = code;
+    this.command = command;
+  }
+  
+  public String getMessage() {
+    return code + (command != null ? " (" + command + ")" : "");
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/ShellCompletor.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/ShellCompletor.java b/shell/src/main/java/org/apache/accumulo/shell/ShellCompletor.java
new file mode 100644
index 0000000..3ed6a04
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/ShellCompletor.java
@@ -0,0 +1,162 @@
+/*
+ * 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.accumulo.shell;
+
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import jline.console.completer.Completer;
+
+import org.apache.accumulo.shell.Shell.Command.CompletionSet;
+import org.apache.accumulo.shell.commands.QuotedStringTokenizer;
+
+public class ShellCompletor implements Completer {
+
+  // private static final Logger log = Logger.getLogger(ShellCompletor.class);
+
+  Map<CompletionSet,Set<String>> options;
+  Token root = null;
+
+  public ShellCompletor() {}
+
+  public ShellCompletor(Token root) {
+    this.root = root;
+  }
+
+  public ShellCompletor(Token rootToken, Map<CompletionSet,Set<String>> options) {
+    this.root = rootToken;
+    this.options = options;
+  }
+
+  @Override
+  @SuppressWarnings({"unchecked", "rawtypes"})
+  public int complete(String buffer, int cursor, List candidates) {
+    try {
+      return _complete(buffer, cursor, candidates);
+    } catch (Exception e) {
+      candidates.add("");
+      candidates.add(e.getMessage());
+      return cursor;
+    }
+  }
+
+  private int _complete(String fullBuffer, int cursor, List<String> candidates) {
+    boolean inTableFlag = false, inUserFlag = false, inNamespaceFlag = false;
+    // Only want to grab the buffer up to the cursor because
+    // the user could be trying to tab complete in the middle
+    // of the line
+    String buffer = fullBuffer.substring(0, cursor);
+
+    Token current_command_token = root;
+    String current_string_token = null;
+    boolean end_space = buffer.endsWith(" ");
+
+    // tabbing with no text
+    if (buffer.length() == 0) {
+      candidates.addAll(root.getSubcommandNames());
+      return 0;
+    }
+
+    String prefix = "";
+
+    QuotedStringTokenizer qst = new QuotedStringTokenizer(buffer);
+
+    Iterator<String> iter = qst.iterator();
+    while (iter.hasNext()) {
+      current_string_token = iter.next();
+      current_string_token = current_string_token.replaceAll("([\\s'\"])", "\\\\$1");
+
+      if (!iter.hasNext()) {
+        // if we end in a space and that space isn't part of the last token
+        // (which would be the case at the start of a quote) OR the buffer
+        // ends with a " indicating that we need to start on the next command
+        // and not complete the current command.
+        if (end_space && !current_string_token.endsWith(" ") || buffer.endsWith("\"")) {
+          // match subcommands
+
+          // we're in a subcommand so try to match the universal
+          // option flags if we're there
+          if (current_string_token.trim().equals("-" + Shell.tableOption)) {
+            candidates.addAll(options.get(Shell.Command.CompletionSet.TABLENAMES));
+            prefix += "-" + Shell.tableOption + " ";
+          } else if (current_string_token.trim().equals("-" + Shell.userOption)) {
+            candidates.addAll(options.get(Shell.Command.CompletionSet.USERNAMES));
+            prefix += "-" + Shell.userOption + " ";
+          } else if (current_string_token.trim().equals("-" + Shell.namespaceOption)) {
+            candidates.addAll(options.get(Shell.Command.CompletionSet.NAMESPACES));
+            prefix += "-" + Shell.namespaceOption + " ";
+          } else if (current_command_token != null) {
+            Token next = current_command_token.getSubcommand(current_string_token);
+            if (next != null) {
+              current_command_token = next;
+
+              if (current_command_token.getCaseSensitive())
+                prefix += current_string_token + " ";
+              else
+                prefix += current_string_token.toUpperCase() + " ";
+
+              candidates.addAll(current_command_token.getSubcommandNames());
+            }
+          }
+          Collections.sort(candidates);
+          return (prefix.length());
+        }
+        // need to match current command
+        // if we're in -t <table>, -u <user>, or -tn <namespace> complete those
+        if (inTableFlag) {
+          for (String a : options.get(Shell.Command.CompletionSet.TABLENAMES))
+            if (a.startsWith(current_string_token))
+              candidates.add(a);
+        } else if (inUserFlag) {
+          for (String a : options.get(Shell.Command.CompletionSet.USERNAMES))
+            if (a.startsWith(current_string_token))
+              candidates.add(a);
+        } else if (inNamespaceFlag) {
+          for (String a : options.get(Shell.Command.CompletionSet.NAMESPACES))
+            if (a.startsWith(current_string_token))
+              candidates.add(a);
+        } else if (current_command_token != null)
+          candidates.addAll(current_command_token.getSubcommandNames(current_string_token));
+
+        Collections.sort(candidates);
+        return (prefix.length());
+      }
+
+      if (current_string_token.trim().equals("-" + Shell.tableOption))
+        inTableFlag = true;
+      else if (current_string_token.trim().equals("-" + Shell.userOption))
+        inUserFlag = true;
+      else if (current_string_token.trim().equals("-" + Shell.namespaceOption))
+        inNamespaceFlag = true;
+      else
+        inUserFlag = inTableFlag = inNamespaceFlag = false;
+
+      if (current_command_token != null && current_command_token.getCaseSensitive())
+        prefix += current_string_token + " ";
+      else
+        prefix += current_string_token.toUpperCase() + " ";
+
+      if (current_command_token != null && current_command_token.getSubcommandNames().contains(current_string_token))
+        current_command_token = current_command_token.getSubcommand(current_string_token);
+
+    }
+    return 0;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/ShellExtension.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/ShellExtension.java b/shell/src/main/java/org/apache/accumulo/shell/ShellExtension.java
new file mode 100644
index 0000000..d29d276
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/ShellExtension.java
@@ -0,0 +1,27 @@
+/*
+ * 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.accumulo.shell;
+
+import org.apache.accumulo.shell.Shell.Command;
+
+public abstract class ShellExtension {
+    
+    public abstract String getExtensionName();
+
+    public abstract Command[] getCommands();
+    
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/ShellOptions.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/ShellOptions.java b/shell/src/main/java/org/apache/accumulo/shell/ShellOptions.java
new file mode 100644
index 0000000..302a8a9
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/ShellOptions.java
@@ -0,0 +1,33 @@
+/*
+ * 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.accumulo.shell;
+
+import org.apache.commons.cli.Option;
+
+/**
+ * Abstract class to encompass the Options available on the Accumulo Shell
+ */
+public abstract class ShellOptions {
+  // Global options flags
+  public static final String userOption = "u";
+  public static final String tableOption = "t";
+  public static final String namespaceOption = "ns";
+  public static final String helpOption = "?";
+  public static final String helpLongOption = "help";
+
+  final Option helpOpt = new Option(helpOption, helpLongOption, false, "display this help");
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/ShellOptionsJC.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/ShellOptionsJC.java b/shell/src/main/java/org/apache/accumulo/shell/ShellOptionsJC.java
new file mode 100644
index 0000000..35cef9f
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/ShellOptionsJC.java
@@ -0,0 +1,280 @@
+/*
+ * 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.accumulo.shell;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Scanner;
+import java.util.TreeMap;
+
+import org.apache.accumulo.core.client.ClientConfiguration;
+import org.apache.accumulo.core.client.ClientConfiguration.ClientProperty;
+import org.apache.accumulo.core.client.security.tokens.AuthenticationToken;
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.commons.configuration.PropertiesConfiguration;
+import org.apache.log4j.Logger;
+
+import com.beust.jcommander.DynamicParameter;
+import com.beust.jcommander.IStringConverter;
+import com.beust.jcommander.Parameter;
+import com.beust.jcommander.ParameterException;
+import com.beust.jcommander.converters.FileConverter;
+
+public class ShellOptionsJC {
+  // Use the Shell logger because this is really just an extension.
+  public static final Logger log = Logger.getLogger(Shell.class);
+
+  @Parameter(names = {"-u", "--user"}, description = "username (defaults to your OS user)")
+  private String username = System.getProperty("user.name", "root");
+
+  public static class PasswordConverter implements IStringConverter<String> {
+    public static final String STDIN = "stdin";
+
+    private enum KeyType {
+      PASS("pass:"), ENV("env:") {
+        @Override
+        String process(String value) {
+          return System.getenv(value);
+        }
+      },
+      FILE("file:") {
+        @Override
+        String process(String value) {
+          Scanner scanner = null;
+          try {
+            scanner = new Scanner(new File(value));
+            return scanner.nextLine();
+          } catch (FileNotFoundException e) {
+            throw new ParameterException(e);
+          } finally {
+            if (scanner != null) {
+              scanner.close();
+            }
+          }
+        }
+      },
+      STDIN(PasswordConverter.STDIN) {
+        @Override
+        public boolean matches(String value) {
+          return prefix.equals(value);
+        }
+
+        @Override
+        public String convert(String value) {
+          // Will check for this later
+          return prefix;
+        }
+      };
+
+      String prefix;
+
+      private KeyType(String prefix) {
+        this.prefix = prefix;
+      }
+
+      public boolean matches(String value) {
+        return value.startsWith(prefix);
+      }
+
+      public String convert(String value) {
+        return process(value.substring(prefix.length()));
+      }
+
+      String process(String value) {
+        return value;
+      }
+    };
+
+    @Override
+    public String convert(String value) {
+      for (KeyType keyType : KeyType.values()) {
+        if (keyType.matches(value)) {
+          return keyType.convert(value);
+        }
+      }
+
+      return value;
+    }
+  }
+
+  // Note: Don't use "password = true" because then it will prompt even if we have a token
+  @Parameter(names = {"-p", "--password"}, description = "password (can be specified as 'pass:<password>', 'file:<local file containing the password>', "
+      + "'env:<variable containing the pass>', or stdin)", converter = PasswordConverter.class)
+  private String password;
+
+  public static class TokenConverter implements IStringConverter<AuthenticationToken> {
+    @Override
+    public AuthenticationToken convert(String value) {
+      try {
+        return Class.forName(value).asSubclass(AuthenticationToken.class).newInstance();
+      } catch (Exception e) {
+        // Catching ClassNotFoundException, ClassCastException, InstantiationException and IllegalAccessException
+        throw new ParameterException(e);
+      }
+    }
+  }
+
+  @Parameter(names = {"-tc", "--tokenClass"}, description = "token type to create, use the -l to pass options", converter = TokenConverter.class)
+  private AuthenticationToken authenticationToken;
+
+  @DynamicParameter(names = {"-l", "--tokenProperty"}, description = "login properties in the format key=value. Reuse -l for each property")
+  private Map<String,String> tokenProperties = new TreeMap<String,String>();
+
+  @Parameter(names = "--disable-tab-completion", description = "disables tab completion (for less overhead when scripting)")
+  private boolean tabCompletionDisabled;
+
+  @Parameter(names = "--debug", description = "enables client debugging")
+  private boolean debugEnabled;
+
+  @Parameter(names = "--fake", description = "fake a connection to accumulo")
+  private boolean fake;
+
+  @Parameter(names = {"-?", "--help"}, help = true, description = "display this help")
+  private boolean helpEnabled;
+
+  @Parameter(names = {"-e", "--execute-command"}, description = "executes a command, and then exits")
+  private String execCommand;
+
+  @Parameter(names = {"-f", "--execute-file"}, description = "executes commands from a file at startup", converter = FileConverter.class)
+  private File execFile;
+
+  @Parameter(names = {"-fv", "--execute-file-verbose"}, description = "executes commands from a file at startup, with commands shown",
+      converter = FileConverter.class)
+  private File execFileVerbose;
+
+  @Parameter(names = {"-h", "--hdfsZooInstance"}, description = "use hdfs zoo instance")
+  private boolean hdfsZooInstance;
+
+  @Parameter(names = {"-z", "--zooKeeperInstance"}, description = "use a zookeeper instance with the given instance name and list of zoo hosts", arity = 2)
+  private List<String> zooKeeperInstance = new ArrayList<String>();
+
+  @Parameter(names = {"--ssl"}, description = "use ssl to connect to accumulo")
+  private boolean useSsl = false;
+
+  @Parameter(
+      names = "--config-file",
+      description = "read the given client config file.  If omitted, the path searched can be specified with $ACCUMULO_CLIENT_CONF_PATH, which defaults to ~/.accumulo/config:$ACCUMULO_CONF_DIR/client.conf:/etc/accumulo/client.conf")
+  private String clientConfigFile = null;
+
+  @Parameter(names = {"-zi", "--zooKeeperInstanceName"}, description = "use a zookeeper instance with the given instance name")
+  private String zooKeeperInstanceName;
+
+  @Parameter(names = {"-zh", "--zooKeeperHosts"}, description = "use a zookeeper instance with the given list of zoo hosts")
+  private String zooKeeperHosts;
+
+  @Parameter(names = "--auth-timeout", description = "minutes the shell can be idle without re-entering a password")
+  private int authTimeout = 60; // TODO Add validator for positive number
+
+  @Parameter(names = "--disable-auth-timeout", description = "disables requiring the user to re-type a password after being idle")
+  private boolean authTimeoutDisabled;
+
+  @Parameter(hidden = true)
+  private List<String> unrecognizedOptions;
+
+  public String getUsername() {
+    return username;
+  }
+
+  public String getPassword() {
+    return password;
+  }
+
+  public AuthenticationToken getAuthenticationToken() {
+    return authenticationToken;
+  }
+
+  public Map<String,String> getTokenProperties() {
+    return tokenProperties;
+  }
+
+  public boolean isTabCompletionDisabled() {
+    return tabCompletionDisabled;
+  }
+
+  public boolean isDebugEnabled() {
+    return debugEnabled;
+  }
+
+  public boolean isFake() {
+    return fake;
+  }
+
+  public boolean isHelpEnabled() {
+    return helpEnabled;
+  }
+
+  public String getExecCommand() {
+    return execCommand;
+  }
+
+  public File getExecFile() {
+    return execFile;
+  }
+
+  public File getExecFileVerbose() {
+    return execFileVerbose;
+  }
+
+  public boolean isHdfsZooInstance() {
+    return hdfsZooInstance;
+  }
+
+  public List<String> getZooKeeperInstance() {
+    return zooKeeperInstance;
+  }
+
+  public String getZooKeeperInstanceName() {
+    return zooKeeperInstanceName;
+  }
+
+  public String getZooKeeperHosts() {
+    return zooKeeperHosts;
+  }
+
+  public int getAuthTimeout() {
+    return authTimeout;
+  }
+
+  public boolean isAuthTimeoutDisabled() {
+    return authTimeoutDisabled;
+  }
+
+  public List<String> getUnrecognizedOptions() {
+    return unrecognizedOptions;
+  }
+
+  public boolean useSsl() {
+    return useSsl;
+  }
+
+  public String getClientConfigFile() {
+    return clientConfigFile;
+  }
+
+  public ClientConfiguration getClientConfiguration() throws ConfigurationException, FileNotFoundException {
+    ClientConfiguration clientConfig = clientConfigFile == null ? ClientConfiguration.loadDefault() : new ClientConfiguration(new PropertiesConfiguration(
+        getClientConfigFile()));
+    if (useSsl()) {
+      clientConfig.setProperty(ClientProperty.INSTANCE_RPC_SSL_ENABLED, "true");
+    }
+    return clientConfig;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/ShellUtil.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/ShellUtil.java b/shell/src/main/java/org/apache/accumulo/shell/ShellUtil.java
new file mode 100644
index 0000000..c0f7a9a
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/ShellUtil.java
@@ -0,0 +1,60 @@
+/*
+ * 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.accumulo.shell;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.nio.charset.StandardCharsets;
+import java.util.List;
+import java.util.Scanner;
+
+import org.apache.commons.codec.binary.Base64;
+import org.apache.hadoop.io.Text;
+
+import com.google.common.collect.Lists;
+
+public class ShellUtil {
+
+  /**
+   * Scans the given file line-by-line (ignoring empty lines) and returns a list containing those lines. If decode is set to true, every line is decoded using
+   * {@link Base64#decodeBase64(byte[])} from the UTF-8 bytes of that line before inserting in the list.
+   * 
+   * @param filename
+   *          Path to the file that needs to be scanned
+   * @param decode
+   *          Whether to decode lines in the file
+   * @return List of {@link Text} objects containing data in the given file
+   * @throws FileNotFoundException
+   *           if the given file doesn't exist
+   */
+  public static List<Text> scanFile(String filename, boolean decode) throws FileNotFoundException {
+    String line;
+    Scanner file = new Scanner(new File(filename), StandardCharsets.UTF_8.name());
+    List<Text> result = Lists.newArrayList();
+    try {
+      while (file.hasNextLine()) {
+        line = file.nextLine();
+        if (!line.isEmpty()) {
+          result.add(decode ? new Text(Base64.decodeBase64(line.getBytes(StandardCharsets.UTF_8))) : new Text(line));
+        }
+      }
+    } finally {
+      file.close();
+    }
+    return result;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/Token.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/Token.java b/shell/src/main/java/org/apache/accumulo/shell/Token.java
new file mode 100644
index 0000000..5083457
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/Token.java
@@ -0,0 +1,137 @@
+/*
+ * 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.accumulo.shell;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+/*
+ * A token is a word in a command in the shell.  The tree that this builds is used for
+ * tab-completion of tables, users, commands and certain other parts of the shell that
+ * can be realistically and quickly gathered. Tokens can have multiple commands grouped 
+ * together and many possible subcommands, although they are stored in a set so duplicates
+ * aren't allowed.
+ */
+
+public class Token {
+  private Set<String> command = new HashSet<String>();
+  private Set<Token> subcommands = new HashSet<Token>();
+  private boolean caseSensitive = false;
+  
+  public Token() {}
+  
+  public Token(String commandName) {
+    this();
+    command.add(commandName);
+  }
+  
+  public Token(Collection<String> commandNames) {
+    this();
+    command.addAll(commandNames);
+  }
+  
+  public Token(Set<String> commandNames, Set<Token> subCommandNames) {
+    this();
+    command.addAll(commandNames);
+    subcommands.addAll(subCommandNames);
+  }
+  
+  public void setCaseSensitive(boolean cs) {
+    caseSensitive = cs;
+  }
+  
+  public boolean getCaseSensitive() {
+    return caseSensitive;
+  }
+  
+  public Set<String> getCommandNames() {
+    return command;
+  }
+  
+  public Set<Token> getSubcommandList() {
+    return subcommands;
+  }
+  
+  public Token getSubcommand(String name) {
+    Iterator<Token> iter = subcommands.iterator();
+    while (iter.hasNext()) {
+      Token t = iter.next();
+      if (t.containsCommand(name))
+        return t;
+    }
+    return null;
+  }
+  
+  public Set<String> getSubcommandNames() {
+    HashSet<String> set = new HashSet<String>();
+    for (Token t : subcommands)
+      set.addAll(t.getCommandNames());
+    return set;
+  }
+  
+  public Set<String> getSubcommandNames(String startsWith) {
+    Iterator<Token> iter = subcommands.iterator();
+    HashSet<String> set = new HashSet<String>();
+    while (iter.hasNext()) {
+      Token t = iter.next();
+      Set<String> subset = t.getCommandNames();
+      for (String s : subset) {
+        if (!t.getCaseSensitive()) {
+          if (s.toLowerCase().startsWith(startsWith.toLowerCase())) {
+            set.add(s);
+          }
+        } else {
+          if (s.startsWith(startsWith)) {
+            set.add(s);
+          }
+        }
+      }
+    }
+    return set;
+  }
+  
+  public boolean containsCommand(String match) {
+    Iterator<String> iter = command.iterator();
+    while (iter.hasNext()) {
+      String t = iter.next();
+      if (caseSensitive) {
+        if (t.equals(match))
+          return true;
+      } else {
+        if (t.equalsIgnoreCase(match))
+          return true;
+      }
+    }
+    return false;
+  }
+  
+  public void addSubcommand(Token t) {
+    subcommands.add(t);
+  }
+  
+  public void addSubcommand(Collection<String> t) {
+    for (String a : t) {
+      addSubcommand(new Token(a));
+    }
+  }
+  
+  public String toString() {
+    return this.command.toString();
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/AboutCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/AboutCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/AboutCommand.java
new file mode 100644
index 0000000..9ba8460
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/AboutCommand.java
@@ -0,0 +1,56 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.io.IOException;
+
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+
+public class AboutCommand extends Command {
+  private Option verboseOption;
+  
+  @Override
+  public String description() {
+    return "displays information about this program";
+  }
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws IOException {
+    shellState.printInfo();
+    if (cl.hasOption(verboseOption.getOpt())) {
+      shellState.printVerboseInfo();
+    }
+    return 0;
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options opts = new Options();
+    verboseOption = new Option("v", "verbose", false, "display detailed session information");
+    opts.addOption(verboseOption);
+    return opts;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/ActiveCompactionIterator.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/ActiveCompactionIterator.java b/shell/src/main/java/org/apache/accumulo/shell/commands/ActiveCompactionIterator.java
new file mode 100644
index 0000000..159a2a6
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/ActiveCompactionIterator.java
@@ -0,0 +1,136 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.accumulo.core.client.IteratorSetting;
+import org.apache.accumulo.core.client.admin.ActiveCompaction;
+import org.apache.accumulo.core.client.admin.InstanceOperations;
+import org.apache.accumulo.core.util.Duration;
+
+class ActiveCompactionIterator implements Iterator<String> {
+  
+  private InstanceOperations instanceOps;
+  private Iterator<String> tsIter;
+  private Iterator<String> compactionIter;
+  
+  private static String maxDecimal(double count) {
+    if (count < 9.995)
+      return String.format("%.2f", count);
+    if (count < 99.95)
+      return String.format("%.1f", count);
+    return String.format("%.0f", count);
+  }
+
+  private static String shortenCount(long count) {
+    if (count < 1000)
+      return count + "";
+    if (count < 1000000)
+      return maxDecimal(count / 1000.0) + "K";
+    if (count < 1000000000)
+      return maxDecimal(count / 1000000.0) + "M";
+    return maxDecimal(count / 1000000000.0) + "B";
+  }
+
+  private void readNext() {
+    final List<String> compactions = new ArrayList<String>();
+    
+    while (tsIter.hasNext()) {
+      
+      final String tserver = tsIter.next();
+      try {
+        List<ActiveCompaction> acl = instanceOps.getActiveCompactions(tserver);
+        
+        acl = new ArrayList<ActiveCompaction>(acl);
+        
+        Collections.sort(acl, new Comparator<ActiveCompaction>() {
+          @Override
+          public int compare(ActiveCompaction o1, ActiveCompaction o2) {
+            return (int) (o2.getAge() - o1.getAge());
+          }
+        });
+
+        for (ActiveCompaction ac : acl) {
+          String output = ac.getOutputFile();
+          int index = output.indexOf("tables");
+          if (index > 0) {
+            output = output.substring(index + 6);
+          }
+          
+          ac.getIterators();
+          
+          List<String> iterList = new ArrayList<String>();
+          Map<String,Map<String,String>> iterOpts = new HashMap<String,Map<String,String>>();
+          for (IteratorSetting is : ac.getIterators()) {
+            iterList.add(is.getName() + "=" + is.getPriority() + "," + is.getIteratorClass());
+            iterOpts.put(is.getName(), is.getOptions());
+          }
+
+          compactions.add(String.format("%21s | %9s | %5s | %6s | %5s | %5s | %15s | %-40s | %5s | %35s | %9s | %s", tserver,
+              Duration.format(ac.getAge(), "", "-"), ac.getType(), ac.getReason(), shortenCount(ac.getEntriesRead()), shortenCount(ac.getEntriesWritten()),
+              ac.getTable(), ac.getExtent(), ac.getInputFiles().size(), output, iterList, iterOpts));
+        }
+      } catch (Exception e) {
+        compactions.add(tserver + " ERROR " + e.getMessage());
+      }
+      
+      if (compactions.size() > 0) {
+        break;
+      }
+    }
+    
+    compactionIter = compactions.iterator();
+  }
+  
+  ActiveCompactionIterator(List<String> tservers, InstanceOperations instanceOps) {
+    this.instanceOps = instanceOps;
+    this.tsIter = tservers.iterator();
+    
+    final String header = String.format(" %-21s| %-9s | %-5s | %-6s | %-5s | %-5s | %-15s | %-40s | %-5s | %-35s | %-9s | %s", "TABLET SERVER", "AGE", "TYPE",
+        "REASON", "READ", "WROTE", "TABLE", "TABLET", "INPUT", "OUTPUT", "ITERATORS", "ITERATOR OPTIONS");
+    
+    compactionIter = Collections.singletonList(header).iterator();
+  }
+  
+  @Override
+  public boolean hasNext() {
+    return compactionIter.hasNext();
+  }
+  
+  @Override
+  public String next() {
+    final String next = compactionIter.next();
+    
+    if (!compactionIter.hasNext())
+      readNext();
+    
+    return next;
+  }
+  
+  @Override
+  public void remove() {
+    throw new UnsupportedOperationException();
+  }
+  
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/ActiveScanIterator.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/ActiveScanIterator.java b/shell/src/main/java/org/apache/accumulo/shell/commands/ActiveScanIterator.java
new file mode 100644
index 0000000..0412317
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/ActiveScanIterator.java
@@ -0,0 +1,91 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.accumulo.core.client.admin.ActiveScan;
+import org.apache.accumulo.core.client.admin.InstanceOperations;
+import org.apache.accumulo.core.client.admin.ScanType;
+import org.apache.accumulo.core.util.Duration;
+
+class ActiveScanIterator implements Iterator<String> {
+  
+  private InstanceOperations instanceOps;
+  private Iterator<String> tsIter;
+  private Iterator<String> scansIter;
+  
+  private void readNext() {
+    final List<String> scans = new ArrayList<String>();
+    
+    while (tsIter.hasNext()) {
+      
+      final String tserver = tsIter.next();
+      try {
+        final List<ActiveScan> asl = instanceOps.getActiveScans(tserver);
+        
+        for (ActiveScan as : asl) {
+          scans.add(String.format("%21s |%21s |%9s |%9s |%7s |%6s |%8s |%8s |%10s |%20s |%10s |%10s | %s", tserver, as.getClient(),
+              Duration.format(as.getAge(), "", "-"), Duration.format(as.getLastContactTime(), "", "-"), as.getState(), as.getType(), as.getUser(),
+              as.getTable(), as.getColumns(), as.getAuthorizations(), (as.getType() == ScanType.SINGLE ? as.getExtent() : "N/A"), as.getSsiList(), as.getSsio()));
+        }
+      } catch (Exception e) {
+        scans.add(tserver + " ERROR " + e.getMessage());
+      }
+      
+      if (scans.size() > 0) {
+        break;
+      }
+    }
+    
+    scansIter = scans.iterator();
+  }
+  
+  ActiveScanIterator(List<String> tservers, InstanceOperations instanceOps) {
+    this.instanceOps = instanceOps;
+    this.tsIter = tservers.iterator();
+    
+    final String header = String.format(" %-21s| %-21s| %-9s| %-9s| %-7s| %-6s| %-8s| %-8s| %-10s| %-20s| %-10s| %-10s | %s", "TABLET SERVER", "CLIENT", "AGE",
+        "LAST", "STATE", "TYPE", "USER", "TABLE", "COLUMNS", "AUTHORIZATIONS", "TABLET", "ITERATORS", "ITERATOR OPTIONS");
+    
+    scansIter = Collections.singletonList(header).iterator();
+  }
+  
+  @Override
+  public boolean hasNext() {
+    return scansIter.hasNext();
+  }
+  
+  @Override
+  public String next() {
+    final String next = scansIter.next();
+    
+    if (!scansIter.hasNext())
+      readNext();
+    
+    return next;
+  }
+  
+  @Override
+  public void remove() {
+    throw new UnsupportedOperationException();
+  }
+  
+}


[08/53] [abbrv] ACCUMULO-1897 Move shell into new package and module

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/test/java/org/apache/accumulo/core/util/shell/ShellConfigTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/accumulo/core/util/shell/ShellConfigTest.java b/core/src/test/java/org/apache/accumulo/core/util/shell/ShellConfigTest.java
deleted file mode 100644
index 43d2e12..0000000
--- a/core/src/test/java/org/apache/accumulo/core/util/shell/ShellConfigTest.java
+++ /dev/null
@@ -1,90 +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.accumulo.core.util.shell;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import java.io.FileDescriptor;
-import java.io.FileInputStream;
-import java.io.PrintStream;
-import java.io.PrintWriter;
-
-import jline.console.ConsoleReader;
-
-import org.apache.accumulo.core.client.security.tokens.PasswordToken;
-import org.apache.accumulo.core.util.shell.ShellTest.TestOutputStream;
-import org.apache.log4j.Level;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-import com.beust.jcommander.ParameterException;
-
-public class ShellConfigTest {
-  TestOutputStream output;
-  Shell shell;
-  PrintStream out;
-  
-  @Before
-  public void setUp() throws Exception {
-    Shell.log.setLevel(Level.ERROR);
-    
-    out = System.out;
-    output = new TestOutputStream();
-    System.setOut(new PrintStream(output));
-
-    shell = new Shell(new ConsoleReader(new FileInputStream(FileDescriptor.in), output), new PrintWriter(output));
-    shell.setLogErrorsToConsole();
-  }
-  
-  @After
-  public void teardown() throws Exception {
-    shell.shutdown();
-    output.clear();
-    System.setOut(out);
-  }
-  
-  @Test
-  public void testHelp() {
-    assertTrue(shell.config("--help"));
-    assertTrue("Did not print usage", output.get().startsWith("Usage"));
-  }
-  
-  @Test
-  public void testBadArg() {
-    assertTrue(shell.config("--bogus"));
-    assertTrue("Did not print usage", output.get().startsWith("Usage"));
-  }
-  
-  @Test
-  public void testToken() {
-    assertTrue(shell.config("--fake", "-tc", PasswordToken.class.getCanonicalName()));
-    assertTrue(output.get().contains(ParameterException.class.getCanonicalName()));
-  }
-  
-  @Test
-  public void testTokenAndOption() {
-    assertFalse(shell.config("--fake", "-tc", PasswordToken.class.getCanonicalName(), "-u", "foo", "-l", "password=foo"));
-  }
-  
-  @Test
-  public void testTokenAndOptionAndPassword() {
-    assertTrue(shell.config("--fake", "-tc", PasswordToken.class.getCanonicalName(), "-l", "password=foo", "-p", "bar"));
-    assertTrue(output.get().contains(ParameterException.class.getCanonicalName()));
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/test/java/org/apache/accumulo/core/util/shell/ShellSetInstanceTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/accumulo/core/util/shell/ShellSetInstanceTest.java b/core/src/test/java/org/apache/accumulo/core/util/shell/ShellSetInstanceTest.java
deleted file mode 100644
index d4c0aea..0000000
--- a/core/src/test/java/org/apache/accumulo/core/util/shell/ShellSetInstanceTest.java
+++ /dev/null
@@ -1,242 +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.accumulo.core.util.shell;
-
-import static org.easymock.EasyMock.anyObject;
-import static org.easymock.EasyMock.expect;
-import static org.powermock.api.easymock.PowerMock.createMock;
-import static org.powermock.api.easymock.PowerMock.expectLastCall;
-import static org.powermock.api.easymock.PowerMock.expectNew;
-import static org.powermock.api.easymock.PowerMock.mockStatic;
-import static org.powermock.api.easymock.PowerMock.replay;
-import static org.powermock.api.easymock.PowerMock.verify;
-
-import java.io.FileDescriptor;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.PrintWriter;
-import java.util.Collections;
-import java.util.List;
-import java.util.UUID;
-
-import jline.console.ConsoleReader;
-
-import org.apache.accumulo.core.client.ClientConfiguration;
-import org.apache.accumulo.core.client.ClientConfiguration.ClientProperty;
-import org.apache.accumulo.core.client.ZooKeeperInstance;
-import org.apache.accumulo.core.client.mock.MockInstance;
-import org.apache.accumulo.core.conf.AccumuloConfiguration;
-import org.apache.accumulo.core.conf.ConfigSanityCheck;
-import org.apache.accumulo.core.conf.Property;
-import org.apache.accumulo.core.conf.SiteConfiguration;
-import org.apache.accumulo.core.zookeeper.ZooUtil;
-import org.apache.hadoop.fs.Path;
-import org.apache.log4j.Level;
-import org.easymock.EasyMock;
-import org.junit.After;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
-
-@RunWith(PowerMockRunner.class)
-@PrepareForTest({Shell.class, ZooUtil.class, ConfigSanityCheck.class})
-public class ShellSetInstanceTest {
-  public static class TestOutputStream extends OutputStream {
-    StringBuilder sb = new StringBuilder();
-
-    @Override
-    public void write(int b) throws IOException {
-      sb.append((char) (0xff & b));
-    }
-
-    public String get() {
-      return sb.toString();
-    }
-
-    public void clear() {
-      sb.setLength(0);
-    }
-  }
-
-  @BeforeClass
-  public static void setupClass() {
-    // This is necessary because PowerMock messes with Hadoop's ability to
-    // determine the current user (see security.UserGroupInformation).
-    System.setProperty("HADOOP_USER_NAME", "test");
-  }
-  @AfterClass
-  public static void teardownClass() {
-    System.clearProperty("HADOOP_USER_NAME");
-  }
-
-  private TestOutputStream output;
-  private Shell shell;
-
-  @Before
-  public void setup() throws IOException {
-    Shell.log.setLevel(Level.OFF);
-    output = new TestOutputStream();
-    shell = new Shell(new ConsoleReader(new FileInputStream(FileDescriptor.in), output), new PrintWriter(output));
-    shell.setLogErrorsToConsole();
-  }
-  @After
-  public void tearDown() {
-    shell.shutdown();
-    SiteConfiguration.clearInstance();
-  }
-
-  @Test
-  public void testSetInstance_Fake() throws Exception {
-    ShellOptionsJC opts = createMock(ShellOptionsJC.class);
-    expect(opts.isFake()).andReturn(true);
-    replay(opts);
-    MockInstance theInstance = createMock(MockInstance.class);
-    expectNew(MockInstance.class, "fake").andReturn(theInstance);
-    replay(theInstance, MockInstance.class);
-
-    shell.setInstance(opts);
-    verify(theInstance, MockInstance.class);
-  }
-  @Test
-  public void testSetInstance_HdfsZooInstance_Explicit() throws Exception {
-    testSetInstance_HdfsZooInstance(true, false, false);
-  }
-  @Test
-  public void testSetInstance_HdfsZooInstance_InstanceGiven() throws Exception {
-    testSetInstance_HdfsZooInstance(false, true, false);
-  }
-  @Test
-  public void testSetInstance_HdfsZooInstance_HostsGiven() throws Exception {
-    testSetInstance_HdfsZooInstance(false, false, true);
-  }
-  @Test
-  public void testSetInstance_HdfsZooInstance_Implicit() throws Exception {
-    testSetInstance_HdfsZooInstance(false, false, false);
-  }
-  
-  @SuppressWarnings("deprecation")
-  private void testSetInstance_HdfsZooInstance(boolean explicitHdfs, boolean onlyInstance, boolean onlyHosts)
-    throws Exception {
-    ClientConfiguration clientConf = createMock(ClientConfiguration.class);
-    ShellOptionsJC opts = createMock(ShellOptionsJC.class);
-    expect(opts.isFake()).andReturn(false);
-    expect(opts.getClientConfiguration()).andReturn(clientConf);
-    expect(opts.isHdfsZooInstance()).andReturn(explicitHdfs);
-    if (!explicitHdfs) {
-      expect(opts.getZooKeeperInstance())
-        .andReturn(Collections.<String>emptyList());
-      if (onlyInstance) {
-        expect(opts.getZooKeeperInstanceName()).andReturn("instance");
-        expect(clientConf.withInstance("instance")).andReturn(clientConf);
-      } else {
-        expect(opts.getZooKeeperInstanceName()).andReturn(null);
-      }
-      if (onlyHosts) {
-        expect(opts.getZooKeeperHosts()).andReturn("host3,host4");
-        expect(clientConf.withZkHosts("host3,host4")).andReturn(clientConf);
-      } else {
-        expect(opts.getZooKeeperHosts()).andReturn(null);
-      }
-    }
-    replay(opts);
-
-    if (!onlyInstance) {
-      expect(clientConf.get(ClientProperty.INSTANCE_NAME)).andReturn(null);
-    }
-
-    mockStatic(ConfigSanityCheck.class);
-    ConfigSanityCheck.validate(EasyMock.<AccumuloConfiguration>anyObject());
-    expectLastCall().atLeastOnce();
-    replay(ConfigSanityCheck.class);
-
-    if (!onlyHosts) {
-      expect(clientConf.containsKey(Property.INSTANCE_ZK_HOST.getKey())).andReturn(true).atLeastOnce();
-      expect(clientConf.getString(Property.INSTANCE_ZK_HOST.getKey())).andReturn("host1,host2").atLeastOnce();
-      expect(clientConf.withZkHosts("host1,host2")).andReturn(clientConf);
-    }
-    if (!onlyInstance) {
-      expect(clientConf.containsKey(Property.INSTANCE_VOLUMES.getKey())).andReturn(false).atLeastOnce();
-      expect(clientConf.containsKey(Property.INSTANCE_DFS_DIR.getKey())).andReturn(true).atLeastOnce();
-      expect(clientConf.containsKey(Property.INSTANCE_DFS_URI.getKey())).andReturn(true).atLeastOnce();
-      expect(clientConf.getString(Property.INSTANCE_DFS_URI.getKey())).andReturn("hdfs://nn1").atLeastOnce();
-      expect(clientConf.getString(Property.INSTANCE_DFS_DIR.getKey())).andReturn("/dfs").atLeastOnce();
-    }
-
-    UUID randomUUID = null;
-    if (!onlyInstance) {
-      mockStatic(ZooUtil.class);
-      randomUUID = UUID.randomUUID();
-      expect(ZooUtil.getInstanceIDFromHdfs(anyObject(Path.class), anyObject(AccumuloConfiguration.class)))
-        .andReturn(randomUUID.toString());
-      replay(ZooUtil.class);
-      expect(clientConf.withInstance(randomUUID)).andReturn(clientConf);
-    }
-    replay(clientConf);
-
-    ZooKeeperInstance theInstance = createMock(ZooKeeperInstance.class);
-    
-    expectNew(ZooKeeperInstance.class, clientConf).andReturn(theInstance);
-    replay(theInstance, ZooKeeperInstance.class);
-
-    shell.setInstance(opts);
-    verify(theInstance, ZooKeeperInstance.class);
-  }
-  @Test
-  public void testSetInstance_ZKInstance_DashZ() throws Exception {
-    testSetInstance_ZKInstance(true);
-  }
-  @Test
-  public void testSetInstance_ZKInstance_DashZIandZH() throws Exception {
-    testSetInstance_ZKInstance(false);
-  }
-  private void testSetInstance_ZKInstance(boolean dashZ) throws Exception {
-    ClientConfiguration clientConf = createMock(ClientConfiguration.class);
-    ShellOptionsJC opts = createMock(ShellOptionsJC.class);
-    expect(opts.isFake()).andReturn(false);
-    expect(opts.getClientConfiguration()).andReturn(clientConf);
-    expect(opts.isHdfsZooInstance()).andReturn(false);
-    if (dashZ) {
-      expect(clientConf.withInstance("foo")).andReturn(clientConf);
-      expect(clientConf.withZkHosts("host1,host2")).andReturn(clientConf);
-      List<String> zl = new java.util.ArrayList<String>();
-      zl.add("foo");
-      zl.add("host1,host2");
-      expect(opts.getZooKeeperInstance()).andReturn(zl);
-      expectLastCall().anyTimes();
-    } else {
-      expect(clientConf.withInstance("bar")).andReturn(clientConf);
-      expect(clientConf.withZkHosts("host3,host4")).andReturn(clientConf);
-      expect(opts.getZooKeeperInstance()).andReturn(Collections.<String>emptyList());
-      expect(opts.getZooKeeperInstanceName()).andReturn("bar");
-      expect(opts.getZooKeeperHosts()).andReturn("host3,host4");
-    }
-    replay(clientConf);
-    replay(opts);
-
-    ZooKeeperInstance theInstance = createMock(ZooKeeperInstance.class);
-    expectNew(ZooKeeperInstance.class, clientConf).andReturn(theInstance);
-    replay(theInstance, ZooKeeperInstance.class);
-
-    shell.setInstance(opts);
-    verify(theInstance, ZooKeeperInstance.class);
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/test/java/org/apache/accumulo/core/util/shell/ShellTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/accumulo/core/util/shell/ShellTest.java b/core/src/test/java/org/apache/accumulo/core/util/shell/ShellTest.java
deleted file mode 100644
index 3d9b89e..0000000
--- a/core/src/test/java/org/apache/accumulo/core/util/shell/ShellTest.java
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.accumulo.core.util.shell;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.io.PrintWriter;
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.TimeZone;
-
-import jline.console.ConsoleReader;
-
-import org.apache.accumulo.core.util.format.DateStringFormatter;
-import org.apache.log4j.Level;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-public class ShellTest {
-  public static class TestOutputStream extends OutputStream {
-    StringBuilder sb = new StringBuilder();
-
-    @Override
-    public void write(int b) throws IOException {
-      sb.append((char) (0xff & b));
-    }
-
-    public String get() {
-      return sb.toString();
-    }
-
-    public void clear() {
-      sb.setLength(0);
-    }
-  }
-
-  public static class StringInputStream extends InputStream {
-    private String source = "";
-    private int offset = 0;
-
-    @Override
-    public int read() throws IOException {
-      if (offset == source.length())
-        return '\n';
-      else
-        return source.charAt(offset++);
-    }
-
-    public void set(String other) {
-      source = other;
-      offset = 0;
-    }
-  }
-
-  private StringInputStream input;
-  private TestOutputStream output;
-  private Shell shell;
-
-  void exec(String cmd) throws IOException {
-    output.clear();
-    shell.execCommand(cmd, true, true);
-  }
-
-  void exec(String cmd, boolean expectGoodExit) throws IOException {
-    exec(cmd);
-    if (expectGoodExit)
-      assertGoodExit("", true);
-    else
-      assertBadExit("", true);
-  }
-
-  void exec(String cmd, boolean expectGoodExit, String expectString) throws IOException {
-    exec(cmd, expectGoodExit, expectString, true);
-  }
-
-  void exec(String cmd, boolean expectGoodExit, String expectString, boolean stringPresent) throws IOException {
-    exec(cmd);
-    if (expectGoodExit)
-      assertGoodExit(expectString, stringPresent);
-    else
-      assertBadExit(expectString, stringPresent);
-  }
-
-  @Before
-  public void setup() throws IOException {
-    TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
-    Shell.log.setLevel(Level.OFF);
-    output = new TestOutputStream();
-    input = new StringInputStream();
-    PrintWriter pw = new PrintWriter(new OutputStreamWriter(output));
-    shell = new Shell(new ConsoleReader(input, output), pw);
-    shell.setLogErrorsToConsole();
-    shell.config("--fake", "-u", "test", "-p", "secret");
-  }
-
-  @After
-  public void teardown() {
-    shell.shutdown();
-  }
-
-  void assertGoodExit(String s, boolean stringPresent) {
-    Shell.log.debug(output.get());
-    assertEquals(shell.getExitCode(), 0);
-    if (s.length() > 0)
-      assertEquals(s + " present in " + output.get() + " was not " + stringPresent, stringPresent, output.get().contains(s));
-  }
-
-  void assertBadExit(String s, boolean stringPresent) {
-    Shell.log.debug(output.get());
-    assertTrue(shell.getExitCode() > 0);
-    if (s.length() > 0)
-      assertEquals(s + " present in " + output.get() + " was not " + stringPresent, stringPresent, output.get().contains(s));
-    shell.resetExitCode();
-  }
-
-  @Test
-  public void aboutTest() throws IOException {
-    Shell.log.debug("Starting about test -----------------------------------");
-    exec("about", true, "Shell - Apache Accumulo Interactive Shell");
-    exec("about -v", true, "Current user:");
-    exec("about arg", false, "java.lang.IllegalArgumentException: Expected 0 arguments");
-  }
-
-  @Test
-  public void addGetSplitsTest() throws IOException {
-    Shell.log.debug("Starting addGetSplits test ----------------------------");
-    exec("addsplits arg", false, "java.lang.IllegalStateException: Not in a table context");
-    exec("createtable test", true);
-    exec("addsplits 1 \\x80", true);
-    exec("getsplits", true, "1\n\\x80");
-    exec("deletetable test -f", true, "Table: [test] has been deleted");
-  }
-
-  @Test
-  public void insertDeleteScanTest() throws IOException {
-    Shell.log.debug("Starting insertDeleteScan test ------------------------");
-    exec("insert r f q v", false, "java.lang.IllegalStateException: Not in a table context");
-    exec("delete r f q", false, "java.lang.IllegalStateException: Not in a table context");
-    exec("createtable test", true);
-    exec("insert r f q v", true);
-    exec("scan", true, "r f:q []    v");
-    exec("delete r f q", true);
-    exec("scan", true, "r f:q []    v", false);
-    exec("insert \\x90 \\xa0 \\xb0 \\xc0\\xd0\\xe0\\xf0", true);
-    exec("scan", true, "\\x90 \\xA0:\\xB0 []    \\xC0\\xD0");
-    exec("scan -f 2", true, "\\x90 \\xA0:\\xB0 []    \\xC0\\xD0");
-    exec("scan -f 2", true, "\\x90 \\xA0:\\xB0 []    \\xC0\\xD0\\xE0", false);
-    exec("scan -b \\x90 -e \\x90 -c \\xA0", true, "\\x90 \\xA0:\\xB0 []    \\xC0");
-    exec("scan -b \\x90 -e \\x90 -c \\xA0:\\xB0", true, "\\x90 \\xA0:\\xB0 []    \\xC0");
-    exec("scan -b \\x90 -be", true, "\\x90 \\xA0:\\xB0 []    \\xC0", false);
-    exec("scan -e \\x90 -ee", true, "\\x90 \\xA0:\\xB0 []    \\xC0", false);
-    exec("scan -b \\x90\\x00", true, "\\x90 \\xA0:\\xB0 []    \\xC0", false);
-    exec("scan -e \\x8f", true, "\\x90 \\xA0:\\xB0 []    \\xC0", false);
-    exec("delete \\x90 \\xa0 \\xb0", true);
-    exec("scan", true, "\\x90 \\xA0:\\xB0 []    \\xC0", false);
-    exec("deletetable test -f", true, "Table: [test] has been deleted");
-  }
-
-  @Test
-  public void authsTest() throws Exception {
-    Shell.log.debug("Starting auths test --------------------------");
-    exec("setauths x,y,z", false, "Missing required option");
-    exec("setauths -s x,y,z -u notauser", false, "user does not exist");
-    exec("setauths -s y,z,x", true);
-    exec("getauths -u notauser", false, "user does not exist");
-    exec("getauths", true, "x,y,z");
-    exec("addauths -u notauser", false, "Missing required option");
-    exec("addauths -u notauser -s foo", false, "user does not exist");
-    exec("addauths -s a", true);
-    exec("getauths", true, "a,x,y,z");
-    exec("setauths -c", true);
-  }
-
-  @Test
-  public void userTest() throws Exception {
-    Shell.log.debug("Starting user test --------------------------");
-    // Test cannot be done via junit because createuser only prompts for password
-    // exec("createuser root", false, "user exists");
-  }
-
-  @Test
-  public void duContextTest() throws Exception {
-    Shell.log.debug("Starting du context test --------------------------");
-    exec("createtable t", true);
-    exec("du", true, "0 [t]");
-    exec("deletetable t -f", true, "Table: [t] has been deleted");
-  }
-
-  @Test
-  public void duTest() throws IOException {
-    Shell.log.debug("Starting DU test --------------------------");
-    exec("createtable t", true);
-    exec("du t", true, "0 [t]");
-    exec("deletetable t -f", true, "Table: [t] has been deleted");
-  }
-
-  @Test
-  public void duPatternTest() throws IOException {
-    Shell.log.debug("Starting DU with pattern test --------------------------");
-    exec("createtable t", true);
-    exec("createtable tt", true);
-    exec("du -p t.*", true, "0 [t, tt]");
-    exec("deletetable t -f", true, "Table: [t] has been deleted");
-    exec("deletetable tt -f", true, "Table: [tt] has been deleted");
-  }
-
-  @Test
-  public void scanDateStringFormatterTest() throws IOException {
-    Shell.log.debug("Starting scan dateStringFormatter test --------------------------");
-    exec("createtable t", true);
-    exec("insert r f q v -ts 0", true);
-    DateFormat dateFormat = new SimpleDateFormat(DateStringFormatter.DATE_FORMAT);
-    String expected = String.format("r f:q [] %s    v", dateFormat.format(new Date(0)));
-    exec("scan -fm org.apache.accumulo.core.util.format.DateStringFormatter -st", true, expected);
-    exec("deletetable t -f", true, "Table: [t] has been deleted");
-  }
-
-  @Test
-  public void commentTest() throws IOException {
-    Shell.log.debug("Starting comment test --------------------------");
-    exec("#", true, "Unknown command", false);
-    exec("# foo", true, "Unknown command", false);
-    exec("- foo", true, "Unknown command", true);
-  }
-
-  @Test
-  public void execFileTest() throws IOException {
-    Shell.log.debug("Starting exec file test --------------------------");
-    shell.config("--fake", "-u", "test", "-p", "secret", "-f", "src/test/resources/shelltest.txt");
-    assertEquals(0, shell.start());
-    assertGoodExit("Unknown command", false);
-  }
-
-  @Test
-  public void setIterTest() throws IOException {
-    Shell.log.debug("Starting setiter test --------------------------");
-    exec("createtable t", true);
-
-    String cmdJustClass = "setiter -class VersioningIterator -p 1";
-    exec(cmdJustClass, false, "java.lang.IllegalArgumentException", false);
-    exec(cmdJustClass, false, "fully qualified package name", true);
-
-    String cmdFullPackage = "setiter -class o.a.a.foo -p 1";
-    exec(cmdFullPackage, false, "java.lang.IllegalArgumentException", false);
-    exec(cmdFullPackage, false, "class not found", true);
-
-    String cmdNoOption = "setiter -class java.lang.String -p 1";
-    exec(cmdNoOption, false, "loaded successfully but does not implement SortedKeyValueIterator", true);
-
-    input.set("\n\n");
-    exec("setiter -scan -class org.apache.accumulo.core.iterators.ColumnFamilyCounter -p 30 -name foo", true);
-    
-    input.set("bar\nname value\n");
-    exec("setiter -scan -class org.apache.accumulo.core.iterators.ColumnFamilyCounter -p 31", true);
-    
-    //TODO can't verify this as config -t fails, functionality verified in ShellServerIT
-    
-    exec("deletetable t -f", true, "Table: [t] has been deleted");
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/test/java/org/apache/accumulo/core/util/shell/ShellUtilTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/accumulo/core/util/shell/ShellUtilTest.java b/core/src/test/java/org/apache/accumulo/core/util/shell/ShellUtilTest.java
deleted file mode 100644
index a5fd179..0000000
--- a/core/src/test/java/org/apache/accumulo/core/util/shell/ShellUtilTest.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.accumulo.core.util.shell;
-
-import static org.junit.Assert.*;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-import java.util.List;
-
-import org.apache.commons.codec.binary.Base64;
-import org.apache.commons.io.FileUtils;
-import org.apache.hadoop.io.Text;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-
-import com.google.common.collect.ImmutableList;
-
-public class ShellUtilTest {
-
-  @Rule
-  public TemporaryFolder folder = new TemporaryFolder(new File(System.getProperty("user.dir") + "/target"));
-
-  // String with 3 lines, with one empty line
-  private static final String FILEDATA = "line1\n\nline2";
-
-  @Test
-  public void testWithoutDecode() throws IOException {
-    File testFile = new File(folder.getRoot(), "testFileNoDecode.txt");
-    FileUtils.writeStringToFile(testFile, FILEDATA);
-    List<Text> output = ShellUtil.scanFile(testFile.getAbsolutePath(), false);
-    assertEquals(ImmutableList.of(new Text("line1"), new Text("line2")), output);
-  }
-
-  @Test
-  public void testWithDecode() throws IOException {
-    File testFile = new File(folder.getRoot(), "testFileWithDecode.txt");
-    FileUtils.writeStringToFile(testFile, FILEDATA);
-    List<Text> output = ShellUtil.scanFile(testFile.getAbsolutePath(), true);
-    assertEquals(
-        ImmutableList.of(new Text(Base64.decodeBase64("line1".getBytes(StandardCharsets.UTF_8))), new Text(Base64.decodeBase64("line2".getBytes(StandardCharsets.UTF_8)))),
-        output);
-  }
-
-  @Test(expected = FileNotFoundException.class)
-  public void testWithMissingFile() throws FileNotFoundException {
-    ShellUtil.scanFile("missingFile.txt", false);
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/test/java/org/apache/accumulo/core/util/shell/command/FormatterCommandTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/accumulo/core/util/shell/command/FormatterCommandTest.java b/core/src/test/java/org/apache/accumulo/core/util/shell/command/FormatterCommandTest.java
deleted file mode 100644
index 091ef75..0000000
--- a/core/src/test/java/org/apache/accumulo/core/util/shell/command/FormatterCommandTest.java
+++ /dev/null
@@ -1,184 +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.accumulo.core.util.shell.command;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Iterator;
-import java.util.Map.Entry;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.TableExistsException;
-import org.apache.accumulo.core.client.mock.MockShell;
-import org.apache.accumulo.core.data.Key;
-import org.apache.accumulo.core.data.Value;
-import org.apache.accumulo.core.util.format.Formatter;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.log4j.Level;
-import org.apache.log4j.Logger;
-import org.junit.Assert;
-import org.junit.Test;
-
-/**
- * Uses the MockShell to test the shell output with Formatters
- */
-public class FormatterCommandTest {
-  ByteArrayOutputStream out = null;
-  InputStream in = null;
-  
-  @Test
-  public void test() throws IOException, AccumuloException, AccumuloSecurityException, TableExistsException, ClassNotFoundException {
-    // Keep the Shell AUDIT log off the test output
-    Logger.getLogger(Shell.class).setLevel(Level.WARN);
-    
-    final String[] args = new String[] {"--fake", "-u", "root", "-p", ""};
-    
-    final String[] commands = createCommands();
-    
-    in = MockShell.makeCommands(commands);
-    out = new ByteArrayOutputStream();
-    
-    final MockShell shell = new MockShell(in, out);
-    shell.config(args);
-    
-    // Can't call createtable in the shell with MockAccumulo
-    shell.getConnector().tableOperations().create("test");
-    
-    try {
-      shell.start();
-    } catch (Exception e) {
-      Assert.fail("Exception while running commands: " + e.getMessage());
-    }
-    
-    shell.getReader().flush();
-    
-    final String[] output = new String(out.toByteArray()).split("\n\r");
-    
-    boolean formatterOn = false;
-    
-    final String[] expectedDefault = new String[] {"row cf:cq []    1234abcd", "row cf1:cq1 []    9876fedc", "row2 cf:cq []    13579bdf",
-        "row2 cf1:cq []    2468ace"};
-    
-    final String[] expectedFormatted = new String[] {"row cf:cq []    0x31 0x32 0x33 0x34 0x61 0x62 0x63 0x64",
-        "row cf1:cq1 []    0x39 0x38 0x37 0x36 0x66 0x65 0x64 0x63", "row2 cf:cq []    0x31 0x33 0x35 0x37 0x39 0x62 0x64 0x66",
-        "row2 cf1:cq []    0x32 0x34 0x36 0x38 0x61 0x63 0x65"};
-    
-    int outputIndex = 0;
-    while (outputIndex < output.length) {
-      final String line = output[outputIndex];
-      
-      if (line.startsWith("root@mock-instance")) {
-        if (line.contains("formatter")) {
-          formatterOn = true;
-        }
-        
-        outputIndex++;
-      } else if (line.startsWith("row")) {
-        int expectedIndex = 0;
-        String[] comparisonData;
-        
-        // Pick the type of data we expect (formatted or default)
-        if (formatterOn) {
-          comparisonData = expectedFormatted;
-        } else {
-          comparisonData = expectedDefault;
-        }
-        
-        // Ensure each output is what we expected
-        while (expectedIndex + outputIndex < output.length && expectedIndex < expectedFormatted.length) {
-          Assert.assertEquals(comparisonData[expectedIndex].trim(), output[expectedIndex + outputIndex].trim());
-          expectedIndex++;
-        }
-        
-        outputIndex += expectedIndex;
-      }
-    }
-  }
-  
-  private String[] createCommands() {
-    return new String[] {"table test", "insert row cf cq 1234abcd", "insert row cf1 cq1 9876fedc", "insert row2 cf cq 13579bdf", "insert row2 cf1 cq 2468ace",
-        "scan", "formatter -t test -f org.apache.accumulo.core.util.shell.command.FormatterCommandTest$HexFormatter", "scan"};
-  }
-  
-  /**
-   * <p>
-   * Simple <code>Formatter</code> that will convert each character in the Value from decimal to hexadecimal. Will automatically skip over characters in the
-   * value which do not fall within the [0-9,a-f] range.
-   * </p>
-   * 
-   * <p>
-   * Example: <code>'0'</code> will be displayed as <code>'0x30'</code>
-   * </p>
-   */
-  public static class HexFormatter implements Formatter {
-    private Iterator<Entry<Key,Value>> iter = null;
-    private boolean printTs = false;
-    
-    private final static String tab = "\t";
-    private final static String newline = "\n";
-    
-    public HexFormatter() {}
-    
-    @Override
-    public boolean hasNext() {
-      return this.iter.hasNext();
-    }
-    
-    @Override
-    public String next() {
-      final Entry<Key,Value> entry = iter.next();
-      
-      String key;
-      
-      // Observe the timestamps
-      if (printTs) {
-        key = entry.getKey().toString();
-      } else {
-        key = entry.getKey().toStringNoTime();
-      }
-      
-      final Value v = entry.getValue();
-      
-      // Approximate how much space we'll need
-      final StringBuilder sb = new StringBuilder(key.length() + v.getSize() * 5);
-      
-      sb.append(key).append(tab);
-      
-      for (byte b : v.get()) {
-        if ((b >= 48 && b <= 57) || (b >= 97 || b <= 102)) {
-          sb.append(String.format("0x%x ", Integer.valueOf(b)));
-        }
-      }
-      
-      sb.append(newline);
-      
-      return sb.toString();
-    }
-    
-    @Override
-    public void remove() {}
-    
-    @Override
-    public void initialize(final Iterable<Entry<Key,Value>> scanner, final boolean printTimestamps) {
-      this.iter = scanner.iterator();
-      this.printTs = printTimestamps;
-    }
-  }
-  
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/test/resources/shelltest.txt
----------------------------------------------------------------------
diff --git a/core/src/test/resources/shelltest.txt b/core/src/test/resources/shelltest.txt
deleted file mode 100644
index 19b6f61..0000000
--- a/core/src/test/resources/shelltest.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-# 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.
-exit
-foo

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/examples/simple/pom.xml
----------------------------------------------------------------------
diff --git a/examples/simple/pom.xml b/examples/simple/pom.xml
index 752d952..8390d01 100644
--- a/examples/simple/pom.xml
+++ b/examples/simple/pom.xml
@@ -61,6 +61,10 @@
     </dependency>
     <dependency>
       <groupId>org.apache.accumulo</groupId>
+      <artifactId>accumulo-shell</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.accumulo</groupId>
       <artifactId>accumulo-trace</artifactId>
     </dependency>
     <dependency>

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/examples/simple/src/main/java/org/apache/accumulo/examples/simple/shell/DebugCommand.java
----------------------------------------------------------------------
diff --git a/examples/simple/src/main/java/org/apache/accumulo/examples/simple/shell/DebugCommand.java b/examples/simple/src/main/java/org/apache/accumulo/examples/simple/shell/DebugCommand.java
index cab78bd..6960898 100644
--- a/examples/simple/src/main/java/org/apache/accumulo/examples/simple/shell/DebugCommand.java
+++ b/examples/simple/src/main/java/org/apache/accumulo/examples/simple/shell/DebugCommand.java
@@ -19,8 +19,8 @@ package org.apache.accumulo.examples.simple.shell;
 import java.util.Set;
 import java.util.TreeSet;
 
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
 import org.apache.commons.cli.CommandLine;
 
 public class DebugCommand extends Command {

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/examples/simple/src/main/java/org/apache/accumulo/examples/simple/shell/MyAppShellExtension.java
----------------------------------------------------------------------
diff --git a/examples/simple/src/main/java/org/apache/accumulo/examples/simple/shell/MyAppShellExtension.java b/examples/simple/src/main/java/org/apache/accumulo/examples/simple/shell/MyAppShellExtension.java
index 3a22f7b..1ba5ad3 100644
--- a/examples/simple/src/main/java/org/apache/accumulo/examples/simple/shell/MyAppShellExtension.java
+++ b/examples/simple/src/main/java/org/apache/accumulo/examples/simple/shell/MyAppShellExtension.java
@@ -16,8 +16,8 @@
  */
 package org.apache.accumulo.examples.simple.shell;
 
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.accumulo.core.util.shell.ShellExtension;
+import org.apache.accumulo.shell.ShellExtension;
+import org.apache.accumulo.shell.Shell.Command;
 
 public class MyAppShellExtension extends ShellExtension {
   

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index a829ba3..d6a552d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -74,6 +74,7 @@
   <modules>
     <module>trace</module>
     <module>core</module>
+    <module>shell</module>
     <module>fate</module>
     <module>start</module>
     <module>examples/simple</module>
@@ -283,6 +284,11 @@
       </dependency>
       <dependency>
         <groupId>org.apache.accumulo</groupId>
+        <artifactId>accumulo-shell</artifactId>
+        <version>${project.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.accumulo</groupId>
         <artifactId>accumulo-start</artifactId>
         <version>${project.version}</version>
       </dependency>

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/server/monitor/pom.xml
----------------------------------------------------------------------
diff --git a/server/monitor/pom.xml b/server/monitor/pom.xml
index 10586f1..411812c 100644
--- a/server/monitor/pom.xml
+++ b/server/monitor/pom.xml
@@ -65,6 +65,10 @@
     </dependency>
     <dependency>
       <groupId>org.apache.accumulo</groupId>
+      <artifactId>accumulo-shell</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.accumulo</groupId>
       <artifactId>accumulo-trace</artifactId>
     </dependency>
     <dependency>

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/server/monitor/src/main/java/org/apache/accumulo/monitor/servlets/ShellServlet.java
----------------------------------------------------------------------
diff --git a/server/monitor/src/main/java/org/apache/accumulo/monitor/servlets/ShellServlet.java b/server/monitor/src/main/java/org/apache/accumulo/monitor/servlets/ShellServlet.java
index 1824840..25e9e33 100644
--- a/server/monitor/src/main/java/org/apache/accumulo/monitor/servlets/ShellServlet.java
+++ b/server/monitor/src/main/java/org/apache/accumulo/monitor/servlets/ShellServlet.java
@@ -34,7 +34,7 @@ import javax.servlet.http.HttpSession;
 
 import jline.console.ConsoleReader;
 
-import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.shell.Shell;
 
 public class ShellServlet extends BasicServlet {
   private static final long serialVersionUID = 1L;

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/pom.xml
----------------------------------------------------------------------
diff --git a/shell/pom.xml b/shell/pom.xml
new file mode 100644
index 0000000..a5af4b8
--- /dev/null
+++ b/shell/pom.xml
@@ -0,0 +1,123 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.apache.accumulo</groupId>
+    <artifactId>accumulo-project</artifactId>
+    <version>1.7.0-SNAPSHOT</version>
+  </parent>
+  <artifactId>accumulo-shell</artifactId>
+  <name>Shell</name>
+  <description>An interactive shell for accessing Apache Accumulo via a command line interface.</description>
+  <dependencies>
+    <dependency>
+      <groupId>com.beust</groupId>
+      <artifactId>jcommander</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>com.google.guava</groupId>
+      <artifactId>guava</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>commons-cli</groupId>
+      <artifactId>commons-cli</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>commons-codec</groupId>
+      <artifactId>commons-codec</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>commons-collections</groupId>
+      <artifactId>commons-collections</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>commons-configuration</groupId>
+      <artifactId>commons-configuration</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>commons-io</groupId>
+      <artifactId>commons-io</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>commons-lang</groupId>
+      <artifactId>commons-lang</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>jline</groupId>
+      <artifactId>jline</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>log4j</groupId>
+      <artifactId>log4j</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.accumulo</groupId>
+      <artifactId>accumulo-core</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.accumulo</groupId>
+      <artifactId>accumulo-fate</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.accumulo</groupId>
+      <artifactId>accumulo-start</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.accumulo</groupId>
+      <artifactId>accumulo-trace</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.commons</groupId>
+      <artifactId>commons-vfs2</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.hadoop</groupId>
+      <artifactId>hadoop-client</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.thrift</groupId>
+      <artifactId>libthrift</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.easymock</groupId>
+      <artifactId>easymock</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.powermock</groupId>
+      <artifactId>powermock-api-easymock</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.powermock</groupId>
+      <artifactId>powermock-core</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.powermock</groupId>
+      <artifactId>powermock-module-junit4</artifactId>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+</project>


[03/53] [abbrv] ACCUMULO-1897 Move shell into new package and module

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/RevokeCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/RevokeCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/RevokeCommand.java
new file mode 100644
index 0000000..373c0b0
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/RevokeCommand.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.accumulo.shell.commands;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.accumulo.core.security.NamespacePermission;
+import org.apache.accumulo.core.security.SystemPermission;
+import org.apache.accumulo.core.security.TablePermission;
+import org.apache.accumulo.core.util.BadArgumentException;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Token;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.OptionGroup;
+import org.apache.commons.cli.Options;
+
+public class RevokeCommand extends TableOperation {
+  {
+    disableUnflaggedTableOptions();
+  }
+
+  private Option systemOpt, userOpt;
+  private String user;
+  private String[] permission;
+
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    user = cl.hasOption(userOpt.getOpt()) ? cl.getOptionValue(userOpt.getOpt()) : shellState.getConnector().whoami();
+
+    permission = cl.getArgs()[0].split("\\.", 2);
+    if (cl.hasOption(systemOpt.getOpt()) && permission[0].equalsIgnoreCase("System")) {
+      try {
+        shellState.getConnector().securityOperations().revokeSystemPermission(user, SystemPermission.valueOf(permission[1]));
+        Shell.log.debug("Revoked from " + user + " the " + permission[1] + " permission");
+      } catch (IllegalArgumentException e) {
+        throw new BadArgumentException("No such system permission", fullCommand, fullCommand.indexOf(cl.getArgs()[0]));
+      }
+    } else if (permission[0].equalsIgnoreCase("Table")) {
+      super.execute(fullCommand, cl, shellState);
+    } else if (permission[0].equalsIgnoreCase("Namespace")) {
+      if (cl.hasOption(optNamespace.getOpt())) {
+        try {
+          shellState.getConnector().securityOperations()
+              .revokeNamespacePermission(user, cl.getOptionValue(optNamespace.getOpt()), NamespacePermission.valueOf(permission[1]));
+        } catch (IllegalArgumentException e) {
+          throw new BadArgumentException("No such namespace permission", fullCommand, fullCommand.indexOf(cl.getArgs()[0]));
+        }
+      } else {
+        throw new BadArgumentException("No namespace specified to apply permission to", fullCommand, fullCommand.indexOf(cl.getArgs()[0]));
+      }
+    } else {
+      throw new BadArgumentException("Unrecognized permission", fullCommand, fullCommand.indexOf(cl.getArgs()[0]));
+    }
+    return 0;
+  }
+
+  @Override
+  protected void doTableOp(final Shell shellState, final String tableName) throws Exception {
+    try {
+      shellState.getConnector().securityOperations().revokeTablePermission(user, tableName, TablePermission.valueOf(permission[1]));
+      Shell.log.debug("Revoked from " + user + " the " + permission[1] + " permission on table " + tableName);
+    } catch (IllegalArgumentException e) {
+      throw new IllegalArgumentException("No such table permission", e);
+    }
+  }
+
+  @Override
+  public String description() {
+    return "revokes system or table permissions from a user";
+  }
+
+  @Override
+  public String usage() {
+    return getName() + " <permission>";
+  }
+
+  @Override
+  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> completionSet) {
+    final Token cmd = new Token(getName());
+    cmd.addSubcommand(new Token(TablePermission.printableValues()));
+    cmd.addSubcommand(new Token(SystemPermission.printableValues()));
+    cmd.addSubcommand(new Token(NamespacePermission.printableValues()));
+    root.addSubcommand(cmd);
+  }
+
+  @Override
+  public Options getOptions() {
+    super.getOptions();
+    final Options o = new Options();
+
+    final OptionGroup group = new OptionGroup();
+
+    systemOpt = new Option("s", "system", false, "revoke a system permission");
+
+    optNamespace = new Option(Shell.namespaceOption, "namespace", true, "name of a namespace to operate on");
+    optNamespace.setArgName("namespace");
+
+    group.addOption(systemOpt);
+    group.addOption(optTableName);
+    group.addOption(optTablePattern);
+    group.addOption(optNamespace);
+
+    o.addOptionGroup(group);
+    userOpt = new Option(Shell.userOption, "user", true, "user to operate on");
+    userOpt.setArgName("username");
+    userOpt.setRequired(true);
+    o.addOption(userOpt);
+
+    return o;
+  }
+
+  @Override
+  public int numArgs() {
+    return 1;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/ScanCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/ScanCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/ScanCommand.java
new file mode 100644
index 0000000..37a33a4
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/ScanCommand.java
@@ -0,0 +1,334 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.util.List;
+import java.util.Map.Entry;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.IteratorSetting;
+import org.apache.accumulo.core.client.Scanner;
+import org.apache.accumulo.core.client.ScannerBase;
+import org.apache.accumulo.core.conf.AccumuloConfiguration;
+import org.apache.accumulo.core.data.Key;
+import org.apache.accumulo.core.data.Range;
+import org.apache.accumulo.core.data.Value;
+import org.apache.accumulo.core.security.Authorizations;
+import org.apache.accumulo.core.util.format.BinaryFormatter;
+import org.apache.accumulo.core.util.format.Formatter;
+import org.apache.accumulo.core.util.interpret.DefaultScanInterpreter;
+import org.apache.accumulo.core.util.interpret.ScanInterpreter;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.accumulo.shell.Shell.PrintFile;
+import org.apache.accumulo.start.classloader.vfs.AccumuloVFSClassLoader;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+import org.apache.hadoop.io.Text;
+
+public class ScanCommand extends Command {
+  
+  private Option scanOptAuths, scanOptRow, scanOptColumns, disablePaginationOpt, showFewOpt, formatterOpt, interpreterOpt, formatterInterpeterOpt,
+      outputFileOpt;
+  
+  protected Option timestampOpt;
+  private Option optStartRowExclusive;
+  private Option optEndRowExclusive;
+  private Option timeoutOption;
+  private Option profileOpt;
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    final PrintFile printFile = getOutputFile(cl);
+    final String tableName = OptUtil.getTableOpt(cl, shellState);
+    
+    final Class<? extends Formatter> formatter = getFormatter(cl, tableName, shellState);
+    final ScanInterpreter interpeter = getInterpreter(cl, tableName, shellState);
+    
+    // handle first argument, if present, the authorizations list to
+    // scan with
+    final Authorizations auths = getAuths(cl, shellState);
+    final Scanner scanner = shellState.getConnector().createScanner(tableName, auths);
+    
+    // handle session-specific scan iterators
+    addScanIterators(shellState, cl, scanner, tableName);
+    
+    // handle remaining optional arguments
+    scanner.setRange(getRange(cl, interpeter));
+    
+    // handle columns
+    fetchColumns(cl, scanner, interpeter);
+    
+    // set timeout
+    scanner.setTimeout(getTimeout(cl), TimeUnit.MILLISECONDS);
+    
+    // output the records
+    if (cl.hasOption(showFewOpt.getOpt())) {
+      final String showLength = cl.getOptionValue(showFewOpt.getOpt());
+      try {
+        final int length = Integer.parseInt(showLength);
+        if (length < 1) {
+          throw new IllegalArgumentException();
+        }
+        BinaryFormatter.getlength(length);
+        printBinaryRecords(cl, shellState, scanner, printFile);
+      } catch (NumberFormatException nfe) {
+        shellState.getReader().println("Arg must be an integer.");
+      } catch (IllegalArgumentException iae) {
+        shellState.getReader().println("Arg must be greater than one.");
+      }
+      
+    } else {
+      printRecords(cl, shellState, scanner, formatter, printFile);
+    }
+    if (printFile != null) {
+      printFile.close();
+    }
+    
+    return 0;
+  }
+  
+  protected long getTimeout(final CommandLine cl) {
+    if (cl.hasOption(timeoutOption.getLongOpt())) {
+      return AccumuloConfiguration.getTimeInMillis(cl.getOptionValue(timeoutOption.getLongOpt()));
+    }
+    
+    return Long.MAX_VALUE;
+  }
+  
+  protected void addScanIterators(final Shell shellState, CommandLine cl, final Scanner scanner, final String tableName) {
+    
+    List<IteratorSetting> tableScanIterators;
+    if (cl.hasOption(profileOpt.getOpt())) {
+      String profile = cl.getOptionValue(profileOpt.getOpt());
+      tableScanIterators = shellState.iteratorProfiles.get(profile);
+      
+      if (tableScanIterators == null) {
+        throw new IllegalArgumentException("Profile " + profile + " does not exist");
+      }
+    } else {
+      tableScanIterators = shellState.scanIteratorOptions.get(tableName);
+      if (tableScanIterators == null) {
+        Shell.log.debug("Found no scan iterators to set");
+        return;
+      }
+    }
+    
+    Shell.log.debug("Found " + tableScanIterators.size() + " scan iterators to set");
+    
+    for (IteratorSetting setting : tableScanIterators) {
+      Shell.log.debug("Setting scan iterator " + setting.getName() + " at priority " + setting.getPriority() + " using class name "
+          + setting.getIteratorClass());
+      for (Entry<String,String> option : setting.getOptions().entrySet()) {
+        Shell.log.debug("Setting option for " + setting.getName() + ": " + option.getKey() + "=" + option.getValue());
+      }
+      scanner.addScanIterator(setting);
+    }
+  }
+  
+  protected void printRecords(final CommandLine cl, final Shell shellState, final Iterable<Entry<Key,Value>> scanner, final Class<? extends Formatter> formatter)
+      throws IOException {
+    printRecords(cl, shellState, scanner, formatter, null);
+  }
+  
+  protected void printRecords(final CommandLine cl, final Shell shellState, final Iterable<Entry<Key,Value>> scanner,
+      final Class<? extends Formatter> formatter, PrintFile outFile) throws IOException {
+    if (outFile == null) {
+      shellState.printRecords(scanner, cl.hasOption(timestampOpt.getOpt()), !cl.hasOption(disablePaginationOpt.getOpt()), formatter);
+    } else {
+      shellState.printRecords(scanner, cl.hasOption(timestampOpt.getOpt()), !cl.hasOption(disablePaginationOpt.getOpt()), formatter, outFile);
+    }
+  }
+  
+  protected void printBinaryRecords(final CommandLine cl, final Shell shellState, final Iterable<Entry<Key,Value>> scanner) throws IOException {
+    printBinaryRecords(cl, shellState, scanner, null);
+  }
+  
+  protected void printBinaryRecords(final CommandLine cl, final Shell shellState, final Iterable<Entry<Key,Value>> scanner, PrintFile outFile)
+      throws IOException {
+    if (outFile == null) {
+      shellState.printBinaryRecords(scanner, cl.hasOption(timestampOpt.getOpt()), !cl.hasOption(disablePaginationOpt.getOpt()));
+    } else {
+      shellState.printBinaryRecords(scanner, cl.hasOption(timestampOpt.getOpt()), !cl.hasOption(disablePaginationOpt.getOpt()), outFile);
+    }
+  }
+  
+  protected ScanInterpreter getInterpreter(final CommandLine cl, final String tableName, final Shell shellState) throws Exception {
+    
+    Class<? extends ScanInterpreter> clazz = null;
+    try {
+      if (cl.hasOption(interpreterOpt.getOpt())) {
+        clazz = AccumuloVFSClassLoader.loadClass(cl.getOptionValue(interpreterOpt.getOpt()), ScanInterpreter.class);
+      } else if (cl.hasOption(formatterInterpeterOpt.getOpt())) {
+        clazz = AccumuloVFSClassLoader.loadClass(cl.getOptionValue(formatterInterpeterOpt.getOpt()), ScanInterpreter.class);
+      }
+    } catch (ClassNotFoundException e) {
+      shellState.getReader().println("Interpreter class could not be loaded.\n" + e.getMessage());
+    }
+    
+    if (clazz == null)
+      clazz = InterpreterCommand.getCurrentInterpreter(tableName, shellState);
+    
+    if (clazz == null)
+      clazz = DefaultScanInterpreter.class;
+    
+    return clazz.newInstance();
+  }
+  
+  protected Class<? extends Formatter> getFormatter(final CommandLine cl, final String tableName, final Shell shellState) throws IOException {
+    
+    try {
+      if (cl.hasOption(formatterOpt.getOpt())) {
+        return AccumuloVFSClassLoader.loadClass(cl.getOptionValue(formatterOpt.getOpt()), Formatter.class);
+        
+      } else if (cl.hasOption(formatterInterpeterOpt.getOpt())) {
+        return AccumuloVFSClassLoader.loadClass(cl.getOptionValue(formatterInterpeterOpt.getOpt()), Formatter.class);
+      }
+    } catch (ClassNotFoundException e) {
+      shellState.getReader().println("Formatter class could not be loaded.\n" + e.getMessage());
+    }
+    
+    return shellState.getFormatter(tableName);
+  }
+  
+  protected void fetchColumns(final CommandLine cl, final ScannerBase scanner, final ScanInterpreter formatter) throws UnsupportedEncodingException {
+    if (cl.hasOption(scanOptColumns.getOpt())) {
+      for (String a : cl.getOptionValue(scanOptColumns.getOpt()).split(",")) {
+        final String sa[] = a.split(":", 2);
+        if (sa.length == 1) {
+          scanner.fetchColumnFamily(formatter.interpretColumnFamily(new Text(a.getBytes(Shell.CHARSET))));
+        } else {
+          scanner.fetchColumn(formatter.interpretColumnFamily(new Text(sa[0].getBytes(Shell.CHARSET))),
+              formatter.interpretColumnQualifier(new Text(sa[1].getBytes(Shell.CHARSET))));
+        }
+      }
+    }
+  }
+  
+  protected Range getRange(final CommandLine cl, final ScanInterpreter formatter) throws UnsupportedEncodingException {
+    if ((cl.hasOption(OptUtil.START_ROW_OPT) || cl.hasOption(OptUtil.END_ROW_OPT)) && cl.hasOption(scanOptRow.getOpt())) {
+      // did not see a way to make commons cli do this check... it has mutually exclusive options but does not support the or
+      throw new IllegalArgumentException("Options -" + scanOptRow.getOpt() + " AND (-" + OptUtil.START_ROW_OPT + " OR -" + OptUtil.END_ROW_OPT
+          + ") are mutally exclusive ");
+    }
+    
+    if (cl.hasOption(scanOptRow.getOpt())) {
+      return new Range(formatter.interpretRow(new Text(cl.getOptionValue(scanOptRow.getOpt()).getBytes(Shell.CHARSET))));
+    } else {
+      Text startRow = OptUtil.getStartRow(cl);
+      if (startRow != null)
+        startRow = formatter.interpretBeginRow(startRow);
+      Text endRow = OptUtil.getEndRow(cl);
+      if (endRow != null)
+        endRow = formatter.interpretEndRow(endRow);
+      final boolean startInclusive = !cl.hasOption(optStartRowExclusive.getOpt());
+      final boolean endInclusive = !cl.hasOption(optEndRowExclusive.getOpt());
+      return new Range(startRow, startInclusive, endRow, endInclusive);
+    }
+  }
+  
+  protected Authorizations getAuths(final CommandLine cl, final Shell shellState) throws AccumuloSecurityException, AccumuloException {
+    final String user = shellState.getConnector().whoami();
+    Authorizations auths = shellState.getConnector().securityOperations().getUserAuthorizations(user);
+    if (cl.hasOption(scanOptAuths.getOpt())) {
+      auths = ScanCommand.parseAuthorizations(cl.getOptionValue(scanOptAuths.getOpt()));
+    }
+    return auths;
+  }
+  
+  static Authorizations parseAuthorizations(final String field) {
+    if (field == null || field.isEmpty()) {
+      return Authorizations.EMPTY;
+    }
+    return new Authorizations(field.split(","));
+  }
+  
+  @Override
+  public String description() {
+    return "scans the table, and displays the resulting records";
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+    
+    scanOptAuths = new Option("s", "scan-authorizations", true, "scan authorizations (all user auths are used if this argument is not specified)");
+    optStartRowExclusive = new Option("be", "begin-exclusive", false, "make start row exclusive (by default it's inclusive)");
+    optStartRowExclusive.setArgName("begin-exclusive");
+    optEndRowExclusive = new Option("ee", "end-exclusive", false, "make end row exclusive (by default it's inclusive)");
+    optEndRowExclusive.setArgName("end-exclusive");
+    scanOptRow = new Option("r", "row", true, "row to scan");
+    scanOptColumns = new Option("c", "columns", true, "comma-separated columns");
+    timestampOpt = new Option("st", "show-timestamps", false, "display timestamps");
+    disablePaginationOpt = new Option("np", "no-pagination", false, "disable pagination of output");
+    showFewOpt = new Option("f", "show few", true, "show only a specified number of characters");
+    formatterOpt = new Option("fm", "formatter", true, "fully qualified name of the formatter class to use");
+    interpreterOpt = new Option("i", "interpreter", true, "fully qualified name of the interpreter class to use");
+    formatterInterpeterOpt = new Option("fi", "fmt-interpreter", true, "fully qualified name of a class that is a formatter and interpreter");
+    timeoutOption = new Option(null, "timeout", true,
+        "time before scan should fail if no data is returned. If no unit is given assumes seconds.  Units d,h,m,s,and ms are supported.  e.g. 30s or 100ms");
+    outputFileOpt = new Option("o", "output", true, "local file to write the scan output to");
+    
+    scanOptAuths.setArgName("comma-separated-authorizations");
+    scanOptRow.setArgName("row");
+    scanOptColumns.setArgName("<columnfamily>[:<columnqualifier>]{,<columnfamily>[:<columnqualifier>]}");
+    showFewOpt.setRequired(false);
+    showFewOpt.setArgName("int");
+    formatterOpt.setArgName("className");
+    timeoutOption.setArgName("timeout");
+    outputFileOpt.setArgName("file");
+    
+    profileOpt = new Option("pn", "profile", true, "iterator profile name");
+    profileOpt.setArgName("profile");
+    
+    o.addOption(scanOptAuths);
+    o.addOption(scanOptRow);
+    o.addOption(OptUtil.startRowOpt());
+    o.addOption(OptUtil.endRowOpt());
+    o.addOption(optStartRowExclusive);
+    o.addOption(optEndRowExclusive);
+    o.addOption(scanOptColumns);
+    o.addOption(timestampOpt);
+    o.addOption(disablePaginationOpt);
+    o.addOption(OptUtil.tableOpt("table to be scanned"));
+    o.addOption(showFewOpt);
+    o.addOption(formatterOpt);
+    o.addOption(interpreterOpt);
+    o.addOption(formatterInterpeterOpt);
+    o.addOption(timeoutOption);
+    o.addOption(outputFileOpt);
+    o.addOption(profileOpt);
+    
+    return o;
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+  
+  protected PrintFile getOutputFile(final CommandLine cl) throws FileNotFoundException {
+    final String outputFile = cl.getOptionValue(outputFileOpt.getOpt());
+    return (outputFile == null ? null : new PrintFile(outputFile));
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/ScriptCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/ScriptCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/ScriptCommand.java
new file mode 100644
index 0000000..9bd91cc
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/ScriptCommand.java
@@ -0,0 +1,290 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.io.File;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.Reader;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+
+import javax.script.Bindings;
+import javax.script.Compilable;
+import javax.script.CompiledScript;
+import javax.script.Invocable;
+import javax.script.ScriptContext;
+import javax.script.ScriptEngine;
+import javax.script.ScriptEngineFactory;
+import javax.script.ScriptEngineManager;
+import javax.script.ScriptException;
+import javax.script.SimpleScriptContext;
+
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.OptionGroup;
+import org.apache.commons.cli.Options;
+
+public class ScriptCommand extends Command {
+  
+  // Command to allow user to run scripts, see JSR-223
+  // http://www.oracle.com/technetwork/articles/javase/scripting-140262.html
+  
+  protected Option list, engine, script, file, args, out, function, object;
+  private static final String DEFAULT_ENGINE = "rhino";
+  
+  public int execute(String fullCommand, CommandLine cl, Shell shellState) throws Exception {
+
+    boolean invoke = false;
+    ScriptEngineManager mgr = new ScriptEngineManager();
+    
+    if (cl.hasOption(list.getOpt())) {
+      listJSREngineInfo(mgr, shellState);
+    } else if (cl.hasOption(file.getOpt()) || cl.hasOption(script.getOpt())) {
+      String engineName = DEFAULT_ENGINE;
+      if (cl.hasOption(engine.getOpt())) {
+        engineName = cl.getOptionValue(engine.getOpt());
+      }
+      ScriptEngine engine = mgr.getEngineByName(engineName);
+      if (null == engine) {
+        shellState.printException(new Exception(engineName + " not found"));
+        return 1;
+      }
+      
+      if (cl.hasOption(object.getOpt()) || cl.hasOption(function.getOpt())) {
+        if (!(engine instanceof Invocable)) {
+          shellState.printException(new Exception(engineName + " does not support invoking functions or methods"));
+          return 1;
+        }
+        invoke = true;
+      }
+      
+      ScriptContext ctx = new SimpleScriptContext();
+      
+      // Put the following objects into the context so that they
+      // are available to the scripts
+      // TODO: What else should go in here?
+      Bindings b = engine.getBindings(ScriptContext.ENGINE_SCOPE);
+      b.put("connection", shellState.getConnector());
+      
+      List<Object> argValues = new ArrayList<Object>();
+      if (cl.hasOption(args.getOpt())) {
+        String[] argList = cl.getOptionValue(args.getOpt()).split(",");
+        for (String arg : argList) {
+          String[] parts = arg.split("=");
+          if (parts.length == 0) {
+            continue;
+          } else if (parts.length == 1) {
+            b.put(parts[0], null);
+            argValues.add(null);
+          } else if (parts.length == 2) {
+            b.put(parts[0], parts[1]);
+            argValues.add(parts[1]);
+          }
+        }
+      }
+      ctx.setBindings(b, ScriptContext.ENGINE_SCOPE);
+      Object[] argArray = argValues.toArray(new Object[argValues.size()]);
+      
+      Writer writer = null;
+      if (cl.hasOption(out.getOpt())) {
+        File f = new File(cl.getOptionValue(out.getOpt()));
+        writer = new FileWriter(f);
+        ctx.setWriter(writer);
+      }
+      
+      if (cl.hasOption(file.getOpt())) {
+        File f = new File(cl.getOptionValue(file.getOpt()));
+        if (!f.exists()) {
+          if (null != writer) {
+            writer.close();
+          }
+          shellState.printException(new Exception(f.getAbsolutePath() + " not found"));
+          return 1;
+        }
+        Reader reader = new FileReader(f);
+        try {
+          engine.eval(reader, ctx);
+          if (invoke) {
+            this.invokeFunctionOrMethod(shellState, engine, cl, argArray);
+          }
+        } catch (ScriptException ex) {
+          shellState.printException(ex);
+          return 1;
+        } finally {
+          reader.close();
+          if (null != writer) {
+            writer.close();
+          }
+        }
+      } else if (cl.hasOption(script.getOpt())) {
+        String inlineScript = cl.getOptionValue(script.getOpt());
+        try {
+          if (engine instanceof Compilable) {
+            Compilable compiledEng = (Compilable) engine;
+            CompiledScript script = compiledEng.compile(inlineScript);
+            script.eval(ctx);
+            if (invoke) {
+              this.invokeFunctionOrMethod(shellState, engine, cl, argArray);
+            }
+          } else {
+            engine.eval(inlineScript, ctx);
+            if (invoke) {
+              this.invokeFunctionOrMethod(shellState, engine, cl, argArray);
+            }
+          }
+        } catch (ScriptException ex) {
+          shellState.printException(ex);
+          return 1;
+        } finally {
+          if (null != writer) {
+            writer.close();
+          }
+        }
+      }
+      if (null != writer) {
+        writer.close();
+      }
+      
+    } else {
+      printHelp(shellState);
+    }
+    return 0;
+  }
+  
+  public String description() {
+    return "execute JSR-223 scripts";
+  }
+  
+  public int numArgs() {
+    return 0;
+  }
+  
+  @Override
+  public String getName() {
+    return "script";
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+    
+    engine = new Option("e", "engine", false, "engine name, defaults to JDK default (Rhino)");
+    engine.setArgName("engineName");
+    engine.setArgs(1);
+    engine.setRequired(false);
+    o.addOption(engine);
+    
+    OptionGroup inputGroup = new OptionGroup();
+    list = new Option("l", "list", false, "list available script engines");
+    inputGroup.addOption(list);
+
+    script = new Option("s", "script", true, "use inline script");
+    script.setArgName("script text");
+    script.setArgs(1);
+    script.setRequired(false);
+    inputGroup.addOption(script);
+    
+    file = new Option("f", "file", true, "use script file");
+    file.setArgName("fileName");
+    file.setArgs(1);
+    file.setRequired(false);
+    
+    inputGroup.addOption(file);
+    inputGroup.setRequired(true);
+    o.addOptionGroup(inputGroup);
+    
+    OptionGroup invokeGroup = new OptionGroup();
+    object = new Option("obj", "object", true, "name of object");
+    object.setArgs(1);
+    object.setArgName("objectName:methodName");
+    object.setRequired(false);
+    invokeGroup.addOption(object);
+    
+    function = new Option("fx", "function", true, "invoke a script function");
+    function.setArgName("functionName");
+    function.setArgs(1);
+    function.setRequired(false);
+    invokeGroup.addOption(function);
+    invokeGroup.setRequired(false);
+    o.addOptionGroup(invokeGroup);
+    
+    args = new Option("a", "args", true, "comma separated list of key=value arguments");
+    args.setArgName("property1=value1,propert2=value2,...");
+    args.setArgs(Option.UNLIMITED_VALUES);
+    args.setRequired(false);
+    o.addOption(args);
+    
+    out = new Option("o", "output", true, "output file");
+    out.setArgName("fileName");
+    out.setArgs(1);
+    out.setRequired(false);
+    o.addOption(out);
+    
+    return o;
+  }
+  
+  private void listJSREngineInfo(ScriptEngineManager mgr, Shell shellState) throws IOException {
+    List<ScriptEngineFactory> factories = mgr.getEngineFactories();
+    Set<String> lines = new TreeSet<String>();
+    for (ScriptEngineFactory factory : factories) {
+      lines.add("ScriptEngineFactory Info");
+      String engName = factory.getEngineName();
+      String engVersion = factory.getEngineVersion();
+      String langName = factory.getLanguageName();
+      String langVersion = factory.getLanguageVersion();
+      lines.add("\tScript Engine: " + engName + " (" + engVersion + ")");
+      List<String> engNames = factory.getNames();
+      for (String name : engNames) {
+        lines.add("\tEngine Alias: " + name);
+      }
+      lines.add("\tLanguage: " + langName + " (" + langVersion + ")");
+    }
+    shellState.printLines(lines.iterator(), true);
+    
+  }
+  
+  private void invokeFunctionOrMethod(Shell shellState, ScriptEngine engine, CommandLine cl, Object[] args) {
+    try {
+      Invocable inv = (Invocable) engine;
+      if (cl.hasOption(function.getOpt())) {
+        inv.invokeFunction(cl.getOptionValue(function.getOpt()), args);
+      } else if (cl.hasOption(object.getOpt())) {
+        String objectMethod = cl.getOptionValue(object.getOpt());
+        String[] parts = objectMethod.split(":");
+        if (!(parts.length == 2)) {
+          shellState.printException(new Exception("Object and Method must be supplied"));
+          return;
+        }
+        String objectName = parts[0];
+        String methodName = parts[1];
+        Object obj = engine.get(objectName);
+        inv.invokeMethod(obj, methodName, args);
+        
+      }
+    } catch (Exception e) {
+      shellState.printException(e);
+    }
+  }
+  
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/SetAuthsCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/SetAuthsCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/SetAuthsCommand.java
new file mode 100644
index 0000000..cc99cbb
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/SetAuthsCommand.java
@@ -0,0 +1,77 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Token;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.OptionGroup;
+import org.apache.commons.cli.Options;
+
+public class SetAuthsCommand extends Command {
+  private Option userOpt;
+  private Option scanOptAuths;
+  private Option clearOptAuths;
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException {
+    final String user = cl.getOptionValue(userOpt.getOpt(), shellState.getConnector().whoami());
+    final String scanOpts = cl.hasOption(clearOptAuths.getOpt()) ? null : cl.getOptionValue(scanOptAuths.getOpt());
+    shellState.getConnector().securityOperations().changeUserAuthorizations(user, ScanCommand.parseAuthorizations(scanOpts));
+    Shell.log.debug("Changed record-level authorizations for user " + user);
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "sets the maximum scan authorizations for a user";
+  }
+  
+  @Override
+  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> completionSet) {
+    registerCompletionForUsers(root, completionSet);
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+    final OptionGroup setOrClear = new OptionGroup();
+    scanOptAuths = new Option("s", "scan-authorizations", true, "scan authorizations to set");
+    scanOptAuths.setArgName("comma-separated-authorizations");
+    setOrClear.addOption(scanOptAuths);
+    clearOptAuths = new Option("c", "clear-authorizations", false, "clear the scan authorizations");
+    setOrClear.addOption(clearOptAuths);
+    setOrClear.setRequired(true);
+    o.addOptionGroup(setOrClear);
+    userOpt = new Option(Shell.userOption, "user", true, "user to operate on");
+    userOpt.setArgName("user");
+    o.addOption(userOpt);
+    return o;
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/SetGroupsCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/SetGroupsCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/SetGroupsCommand.java
new file mode 100644
index 0000000..fc8b06e
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/SetGroupsCommand.java
@@ -0,0 +1,78 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Options;
+import org.apache.hadoop.io.Text;
+
+public class SetGroupsCommand extends Command {
+  @Override
+  public String description() {
+    return "sets the locality groups for a given table (for binary or commas, use Java API)";
+  }
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    final String tableName = OptUtil.getTableOpt(cl, shellState);
+    
+    final HashMap<String,Set<Text>> groups = new HashMap<String,Set<Text>>();
+    
+    for (String arg : cl.getArgs()) {
+      final String sa[] = arg.split("=", 2);
+      if (sa.length < 2) {
+        throw new IllegalArgumentException("Missing '='");
+      }
+      final String group = sa[0];
+      final HashSet<Text> colFams = new HashSet<Text>();
+      
+      for (String family : sa[1].split(",")) {
+        colFams.add(new Text(family.getBytes(Shell.CHARSET)));
+      }
+      
+      groups.put(group, colFams);
+    }
+    
+    shellState.getConnector().tableOperations().setLocalityGroups(tableName, groups);
+    
+    return 0;
+  }
+  
+  @Override
+  public int numArgs() {
+    return Shell.NO_FIXED_ARG_LENGTH_CHECK;
+  }
+  
+  @Override
+  public String usage() {
+    return getName() + " <group>=<col fam>{,<col fam>}{ <group>=<col fam>{,<col fam>}}";
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options opts = new Options();
+    opts.addOption(OptUtil.tableOpt("table to fetch locality groups for"));
+    return opts;
+  }
+  
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/SetIterCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/SetIterCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/SetIterCommand.java
new file mode 100644
index 0000000..a398b3a
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/SetIterCommand.java
@@ -0,0 +1,453 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.io.IOException;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import jline.console.ConsoleReader;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.IteratorSetting;
+import org.apache.accumulo.core.client.NamespaceNotFoundException;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.core.conf.Property;
+import org.apache.accumulo.core.data.Key;
+import org.apache.accumulo.core.data.Value;
+import org.apache.accumulo.core.iterators.IteratorUtil.IteratorScope;
+import org.apache.accumulo.core.iterators.OptionDescriber;
+import org.apache.accumulo.core.iterators.OptionDescriber.IteratorOptions;
+import org.apache.accumulo.core.iterators.SortedKeyValueIterator;
+import org.apache.accumulo.core.iterators.user.AgeOffFilter;
+import org.apache.accumulo.core.iterators.user.RegExFilter;
+import org.apache.accumulo.core.iterators.user.ReqVisFilter;
+import org.apache.accumulo.core.iterators.user.VersioningIterator;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.ShellCommandException;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.accumulo.shell.ShellCommandException.ErrorCode;
+import org.apache.accumulo.start.classloader.vfs.AccumuloVFSClassLoader;
+import org.apache.accumulo.start.classloader.vfs.ContextManager;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.OptionGroup;
+import org.apache.commons.cli.Options;
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.vfs2.FileSystemException;
+
+public class SetIterCommand extends Command {
+
+  private Option allScopeOpt, mincScopeOpt, majcScopeOpt, scanScopeOpt, nameOpt, priorityOpt;
+  private Option aggTypeOpt, ageoffTypeOpt, regexTypeOpt, versionTypeOpt, reqvisTypeOpt, classnameTypeOpt;
+
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException,
+      TableNotFoundException, IOException, ShellCommandException {
+
+    boolean tables = cl.hasOption(OptUtil.tableOpt().getOpt()) || !shellState.getTableName().isEmpty();
+    boolean namespaces = cl.hasOption(OptUtil.namespaceOpt().getOpt());
+
+    final int priority = Integer.parseInt(cl.getOptionValue(priorityOpt.getOpt()));
+
+    final Map<String,String> options = new HashMap<String,String>();
+    String classname = cl.getOptionValue(classnameTypeOpt.getOpt());
+    if (cl.hasOption(aggTypeOpt.getOpt())) {
+      Shell.log.warn("aggregators are deprecated");
+      @SuppressWarnings("deprecation")
+      String deprecatedClassName = org.apache.accumulo.core.iterators.AggregatingIterator.class.getName();
+      classname = deprecatedClassName;
+    } else if (cl.hasOption(regexTypeOpt.getOpt())) {
+      classname = RegExFilter.class.getName();
+    } else if (cl.hasOption(ageoffTypeOpt.getOpt())) {
+      classname = AgeOffFilter.class.getName();
+    } else if (cl.hasOption(versionTypeOpt.getOpt())) {
+      classname = VersioningIterator.class.getName();
+    } else if (cl.hasOption(reqvisTypeOpt.getOpt())) {
+      classname = ReqVisFilter.class.getName();
+    }
+
+    ClassLoader classloader = getClassLoader(cl, shellState);
+
+    // Get the iterator options, with potentially a name provided by the OptionDescriber impl or through user input
+    String configuredName = setUpOptions(classloader, shellState.getReader(), classname, options);
+
+    // Try to get the name provided by the setiter command
+    String name = cl.getOptionValue(nameOpt.getOpt(), null);
+    
+    // Cannot continue if no name is provided
+    if (null == name && null == configuredName) {
+      throw new IllegalArgumentException("No provided or default name for iterator");
+    } else if (null == name) {
+      // Fall back to the name from OptionDescriber or user input if none is provided on setiter option
+      name = configuredName;
+    }
+
+    if (namespaces) {
+      try {
+        setNamespaceProperties(cl, shellState, priority, options, classname, name);
+      } catch (NamespaceNotFoundException e) {
+        throw new IllegalArgumentException(e);
+      }
+    } else if (tables) {
+      setTableProperties(cl, shellState, priority, options, classname, name);
+    } else {
+      throw new IllegalArgumentException("No table or namespace specified");
+    }
+    return 0;
+  }
+
+  private ClassLoader getClassLoader(final CommandLine cl, final Shell shellState) throws AccumuloException, TableNotFoundException, AccumuloSecurityException,
+      IOException, FileSystemException {
+
+    boolean tables = cl.hasOption(OptUtil.tableOpt().getOpt()) || !shellState.getTableName().isEmpty();
+    boolean namespaces = cl.hasOption(OptUtil.namespaceOpt().getOpt());
+
+    String classpath = null;
+    Iterable<Entry<String,String>> tableProps;
+
+    if (namespaces) {
+      try {
+        tableProps = shellState.getConnector().namespaceOperations().getProperties(OptUtil.getNamespaceOpt(cl, shellState));
+      } catch (NamespaceNotFoundException e) {
+        throw new IllegalArgumentException(e);
+      }
+    } else if (tables) {
+      tableProps = shellState.getConnector().tableOperations().getProperties(OptUtil.getTableOpt(cl, shellState));
+    } else {
+      throw new IllegalArgumentException("No table or namespace specified");
+    }
+    for (Entry<String,String> entry : tableProps) {
+      if (entry.getKey().equals(Property.TABLE_CLASSPATH.getKey())) {
+        classpath = entry.getValue();
+      }
+    }
+
+    ClassLoader classloader;
+
+    if (classpath != null && !classpath.equals("")) {
+      shellState.getConnector().instanceOperations().getSystemConfiguration().get(Property.VFS_CONTEXT_CLASSPATH_PROPERTY.getKey() + classpath);
+
+      try {
+        AccumuloVFSClassLoader.getContextManager().setContextConfig(new ContextManager.DefaultContextsConfig(new Iterable<Map.Entry<String,String>>() {
+          @Override
+          public Iterator<Entry<String,String>> iterator() {
+            try {
+              return shellState.getConnector().instanceOperations().getSystemConfiguration().entrySet().iterator();
+            } catch (AccumuloException e) {
+              throw new RuntimeException(e);
+            } catch (AccumuloSecurityException e) {
+              throw new RuntimeException(e);
+            }
+          }
+        }));
+      } catch (IllegalStateException ise) {}
+
+      classloader = AccumuloVFSClassLoader.getContextManager().getClassLoader(classpath);
+    } else {
+      classloader = AccumuloVFSClassLoader.getClassLoader();
+    }
+    return classloader;
+  }
+
+  protected void setTableProperties(final CommandLine cl, final Shell shellState, final int priority, final Map<String,String> options, final String classname,
+      final String name) throws AccumuloException, AccumuloSecurityException, ShellCommandException, TableNotFoundException {
+    // remove empty values
+
+    final String tableName = OptUtil.getTableOpt(cl, shellState);
+
+    if (!shellState.getConnector().tableOperations().testClassLoad(tableName, classname, SortedKeyValueIterator.class.getName())) {
+      throw new ShellCommandException(ErrorCode.INITIALIZATION_FAILURE, "Servers are unable to load " + classname + " as type "
+          + SortedKeyValueIterator.class.getName());
+    }
+
+    final String aggregatorClass = options.get("aggregatorClass");
+    @SuppressWarnings("deprecation")
+    String deprecatedAggregatorClassName = org.apache.accumulo.core.iterators.aggregation.Aggregator.class.getName();
+    if (aggregatorClass != null && !shellState.getConnector().tableOperations().testClassLoad(tableName, aggregatorClass, deprecatedAggregatorClassName)) {
+      throw new ShellCommandException(ErrorCode.INITIALIZATION_FAILURE, "Servers are unable to load " + aggregatorClass + " as type "
+          + deprecatedAggregatorClassName);
+    }
+
+    for (Iterator<Entry<String,String>> i = options.entrySet().iterator(); i.hasNext();) {
+      final Entry<String,String> entry = i.next();
+      if (entry.getValue() == null || entry.getValue().isEmpty()) {
+        i.remove();
+      }
+    }
+    final EnumSet<IteratorScope> scopes = EnumSet.noneOf(IteratorScope.class);
+    if (cl.hasOption(allScopeOpt.getOpt()) || cl.hasOption(mincScopeOpt.getOpt())) {
+      scopes.add(IteratorScope.minc);
+    }
+    if (cl.hasOption(allScopeOpt.getOpt()) || cl.hasOption(majcScopeOpt.getOpt())) {
+      scopes.add(IteratorScope.majc);
+    }
+    if (cl.hasOption(allScopeOpt.getOpt()) || cl.hasOption(scanScopeOpt.getOpt())) {
+      scopes.add(IteratorScope.scan);
+    }
+    if (scopes.isEmpty()) {
+      throw new IllegalArgumentException("You must select at least one scope to configure");
+    }
+    final IteratorSetting setting = new IteratorSetting(priority, name, classname, options);
+    shellState.getConnector().tableOperations().attachIterator(tableName, setting, scopes);
+  }
+
+  protected void setNamespaceProperties(final CommandLine cl, final Shell shellState, final int priority, final Map<String,String> options,
+      final String classname, final String name) throws AccumuloException, AccumuloSecurityException, ShellCommandException, NamespaceNotFoundException {
+    // remove empty values
+
+    final String namespace = OptUtil.getNamespaceOpt(cl, shellState);
+
+    if (!shellState.getConnector().namespaceOperations().testClassLoad(namespace, classname, SortedKeyValueIterator.class.getName())) {
+      throw new ShellCommandException(ErrorCode.INITIALIZATION_FAILURE, "Servers are unable to load " + classname + " as type "
+          + SortedKeyValueIterator.class.getName());
+    }
+
+    final String aggregatorClass = options.get("aggregatorClass");
+    @SuppressWarnings("deprecation")
+    String deprecatedAggregatorClassName = org.apache.accumulo.core.iterators.aggregation.Aggregator.class.getName();
+    if (aggregatorClass != null && !shellState.getConnector().namespaceOperations().testClassLoad(namespace, aggregatorClass, deprecatedAggregatorClassName)) {
+      throw new ShellCommandException(ErrorCode.INITIALIZATION_FAILURE, "Servers are unable to load " + aggregatorClass + " as type "
+          + deprecatedAggregatorClassName);
+    }
+
+    for (Iterator<Entry<String,String>> i = options.entrySet().iterator(); i.hasNext();) {
+      final Entry<String,String> entry = i.next();
+      if (entry.getValue() == null || entry.getValue().isEmpty()) {
+        i.remove();
+      }
+    }
+    final EnumSet<IteratorScope> scopes = EnumSet.noneOf(IteratorScope.class);
+    if (cl.hasOption(allScopeOpt.getOpt()) || cl.hasOption(mincScopeOpt.getOpt())) {
+      scopes.add(IteratorScope.minc);
+    }
+    if (cl.hasOption(allScopeOpt.getOpt()) || cl.hasOption(majcScopeOpt.getOpt())) {
+      scopes.add(IteratorScope.majc);
+    }
+    if (cl.hasOption(allScopeOpt.getOpt()) || cl.hasOption(scanScopeOpt.getOpt())) {
+      scopes.add(IteratorScope.scan);
+    }
+    if (scopes.isEmpty()) {
+      throw new IllegalArgumentException("You must select at least one scope to configure");
+    }
+    final IteratorSetting setting = new IteratorSetting(priority, name, classname, options);
+    shellState.getConnector().namespaceOperations().attachIterator(namespace, setting, scopes);
+  }
+
+  private static String setUpOptions(ClassLoader classloader, final ConsoleReader reader, final String className, final Map<String,String> options)
+      throws IOException, ShellCommandException {
+    String input;
+    @SuppressWarnings("rawtypes")
+    SortedKeyValueIterator untypedInstance;
+    @SuppressWarnings("rawtypes")
+    Class<? extends SortedKeyValueIterator> clazz;
+    try {
+      clazz = classloader.loadClass(className).asSubclass(SortedKeyValueIterator.class);
+      untypedInstance = clazz.newInstance();
+    } catch (ClassNotFoundException e) {
+      StringBuilder msg = new StringBuilder("Unable to load ").append(className);
+      if (className.indexOf('.') < 0) {
+        msg.append("; did you use a fully qualified package name?");
+      } else {
+        msg.append("; class not found.");
+      }
+      throw new ShellCommandException(ErrorCode.INITIALIZATION_FAILURE, msg.toString());
+    } catch (InstantiationException e) {
+      throw new IllegalArgumentException(e.getMessage());
+    } catch (IllegalAccessException e) {
+      throw new IllegalArgumentException(e.getMessage());
+    } catch (ClassCastException e) {
+      StringBuilder msg = new StringBuilder(50);
+      msg.append(className).append(" loaded successfully but does not implement SortedKeyValueIterator.");
+      msg.append(" This class cannot be used with this command.");
+      throw new ShellCommandException(ErrorCode.INITIALIZATION_FAILURE, msg.toString());
+    }
+
+    @SuppressWarnings("unchecked")
+    SortedKeyValueIterator<Key,Value> skvi = (SortedKeyValueIterator<Key,Value>) untypedInstance;
+    OptionDescriber iterOptions = null;
+    if (OptionDescriber.class.isAssignableFrom(skvi.getClass())) {
+      iterOptions = (OptionDescriber) skvi;
+    }
+
+    String iteratorName;
+    if (null != iterOptions) {
+      final IteratorOptions itopts = iterOptions.describeOptions();
+      iteratorName = itopts.getName();
+      
+      if (iteratorName == null) {
+        throw new IllegalArgumentException(className + " described its default distinguishing name as null");
+      }
+      String shortClassName = className;
+      if (className.contains(".")) {
+        shortClassName = className.substring(className.lastIndexOf('.') + 1);
+      }
+      final Map<String,String> localOptions = new HashMap<String,String>();
+      do {
+        // clean up the overall options that caused things to fail
+        for (String key : localOptions.keySet()) {
+          options.remove(key);
+        }
+        localOptions.clear();
+  
+        reader.println(itopts.getDescription());
+  
+        String prompt;
+        if (itopts.getNamedOptions() != null) {
+          for (Entry<String,String> e : itopts.getNamedOptions().entrySet()) {
+            prompt = Shell.repeat("-", 10) + "> set " + shortClassName + " parameter " + e.getKey() + ", " + e.getValue() + ": ";
+            reader.flush();
+            input = reader.readLine(prompt);
+            if (input == null) {
+              reader.println();
+              throw new IOException("Input stream closed");
+            }
+            // Places all Parameters and Values into the LocalOptions, even if the value is "".
+            // This allows us to check for "" values when setting the iterators and allows us to remove
+            // the parameter and value from the table property.
+            localOptions.put(e.getKey(), input);
+          }
+        }
+  
+        if (itopts.getUnnamedOptionDescriptions() != null) {
+          for (String desc : itopts.getUnnamedOptionDescriptions()) {
+            reader.println(Shell.repeat("-", 10) + "> entering options: " + desc);
+            input = "start";
+            prompt = Shell.repeat("-", 10) + "> set " + shortClassName + " option (<name> <value>, hit enter to skip): ";
+            while (true) {
+              reader.flush();
+              input = reader.readLine(prompt);
+              if (input == null) {
+                reader.println();
+                throw new IOException("Input stream closed");
+              } else {
+                input = new String(input);
+              }
+  
+              if (input.length() == 0)
+                break;
+  
+              String[] sa = input.split(" ", 2);
+              localOptions.put(sa[0], sa[1]);
+            }
+          }
+        }
+  
+        options.putAll(localOptions);
+        if (!iterOptions.validateOptions(options))
+          reader.println("invalid options for " + clazz.getName());
+  
+      } while (!iterOptions.validateOptions(options));
+    } else {
+      reader.flush();
+      reader.println("The iterator class does not implement OptionDescriber. Consider this for better iterator configuration using this setiter command.");
+      iteratorName = reader.readLine("Name for iterator (enter to skip): ");
+      if (null == iteratorName) {
+        reader.println();
+        throw new IOException("Input stream closed");
+      } else if (StringUtils.isWhitespace(iteratorName)) {
+        // Treat whitespace or empty string as no name provided
+        iteratorName = null;
+      }
+      
+      reader.flush();
+      reader.println("Optional, configure name-value options for iterator:");
+      String prompt = Shell.repeat("-", 10) + "> set option (<name> <value>, hit enter to skip): ";
+      final HashMap<String,String> localOptions = new HashMap<String,String>();
+      
+      while (true) {
+        reader.flush();
+        input = reader.readLine(prompt);
+        if (input == null) {
+          reader.println();
+          throw new IOException("Input stream closed");
+        } else if (StringUtils.isWhitespace(input)) {
+          break;
+        } 
+
+        String[] sa = input.split(" ", 2);
+        localOptions.put(sa[0], sa[1]);
+      }
+      
+      options.putAll(localOptions);
+    }
+    
+    return iteratorName;
+  }
+
+  @Override
+  public String description() {
+    return "sets a table-specific or namespace-specific iterator";
+  }
+
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+
+    priorityOpt = new Option("p", "priority", true, "the order in which the iterator is applied");
+    priorityOpt.setArgName("pri");
+    priorityOpt.setRequired(true);
+
+    nameOpt = new Option("n", "name", true, "iterator to set");
+    nameOpt.setArgName("itername");
+
+    allScopeOpt = new Option("all", "all-scopes", false, "applied at scan time, minor and major compactions");
+    mincScopeOpt = new Option(IteratorScope.minc.name(), "minor-compaction", false, "applied at minor compaction");
+    majcScopeOpt = new Option(IteratorScope.majc.name(), "major-compaction", false, "applied at major compaction");
+    scanScopeOpt = new Option(IteratorScope.scan.name(), "scan-time", false, "applied at scan time");
+
+    final OptionGroup typeGroup = new OptionGroup();
+    classnameTypeOpt = new Option("class", "class-name", true, "a java class that implements SortedKeyValueIterator");
+    classnameTypeOpt.setArgName("name");
+    aggTypeOpt = new Option("agg", "aggregator", false, "an aggregating type");
+    regexTypeOpt = new Option("regex", "regular-expression", false, "a regex matching iterator");
+    versionTypeOpt = new Option("vers", "version", false, "a versioning iterator");
+    reqvisTypeOpt = new Option("reqvis", "require-visibility", false, "an iterator that omits entries with empty visibilities");
+    ageoffTypeOpt = new Option("ageoff", "ageoff", false, "an aging off iterator");
+
+    typeGroup.addOption(classnameTypeOpt);
+    typeGroup.addOption(aggTypeOpt);
+    typeGroup.addOption(regexTypeOpt);
+    typeGroup.addOption(versionTypeOpt);
+    typeGroup.addOption(reqvisTypeOpt);
+    typeGroup.addOption(ageoffTypeOpt);
+    typeGroup.setRequired(true);
+
+    final OptionGroup tableGroup = new OptionGroup();
+    tableGroup.addOption(OptUtil.tableOpt("table to configure iterators on"));
+    tableGroup.addOption(OptUtil.namespaceOpt("namespace to configure iterators on"));
+
+    o.addOption(priorityOpt);
+    o.addOption(nameOpt);
+    o.addOption(allScopeOpt);
+    o.addOption(mincScopeOpt);
+    o.addOption(majcScopeOpt);
+    o.addOption(scanScopeOpt);
+    o.addOptionGroup(typeGroup);
+    o.addOptionGroup(tableGroup);
+    return o;
+  }
+
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/SetScanIterCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/SetScanIterCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/SetScanIterCommand.java
new file mode 100644
index 0000000..3ae42dd
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/SetScanIterCommand.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.accumulo.shell.commands;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.IteratorSetting;
+import org.apache.accumulo.core.client.Scanner;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.core.iterators.IteratorUtil.IteratorScope;
+import org.apache.accumulo.core.iterators.SortedKeyValueIterator;
+import org.apache.accumulo.core.security.Authorizations;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.ShellCommandException;
+import org.apache.accumulo.shell.ShellCommandException.ErrorCode;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.OptionGroup;
+import org.apache.commons.cli.Options;
+
+public class SetScanIterCommand extends SetIterCommand {
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException, TableNotFoundException,
+      IOException, ShellCommandException {
+    Shell.log.warn("Deprecated, use " + new SetShellIterCommand().getName());
+    return super.execute(fullCommand, cl, shellState);
+  }
+  
+  @Override
+  protected void setTableProperties(final CommandLine cl, final Shell shellState, final int priority, final Map<String,String> options, final String classname,
+      final String name) throws AccumuloException, AccumuloSecurityException, ShellCommandException, TableNotFoundException {
+    
+    final String tableName = OptUtil.getTableOpt(cl, shellState);
+
+    // instead of setting table properties, just put the options in a list to use at scan time
+    Class<?> loadClass;
+    try {
+      loadClass = getClass().getClassLoader().loadClass(classname);
+    } catch (ClassNotFoundException e) {
+      throw new ShellCommandException(ErrorCode.INITIALIZATION_FAILURE, "Unable to load " + classname);
+    }
+    try {
+      loadClass.asSubclass(SortedKeyValueIterator.class);
+    } catch (ClassCastException ex) {
+      throw new ShellCommandException(ErrorCode.INITIALIZATION_FAILURE, "Unable to load " + classname  + " as type "
+          + SortedKeyValueIterator.class.getName());
+    }
+    
+    for (Iterator<Entry<String,String>> i = options.entrySet().iterator(); i.hasNext();) {
+      final Entry<String,String> entry = i.next();
+      if (entry.getValue() == null || entry.getValue().isEmpty()) {
+        i.remove();
+      }
+    }
+
+    List<IteratorSetting> tableScanIterators = shellState.scanIteratorOptions.get(tableName);
+    if (tableScanIterators == null) {
+      tableScanIterators = new ArrayList<IteratorSetting>();
+      shellState.scanIteratorOptions.put(tableName, tableScanIterators);
+    }
+    final IteratorSetting setting = new IteratorSetting(priority, name, classname);
+    setting.addOptions(options);
+    
+    // initialize a scanner to ensure the new setting does not conflict with existing settings
+    final String user = shellState.getConnector().whoami();
+    final Authorizations auths = shellState.getConnector().securityOperations().getUserAuthorizations(user);
+    final Scanner scanner = shellState.getConnector().createScanner(tableName, auths);
+    for (IteratorSetting s : tableScanIterators) {
+      scanner.addScanIterator(s);
+    }
+    scanner.addScanIterator(setting);
+    
+    // if no exception has been thrown, it's safe to add it to the list
+    tableScanIterators.add(setting);
+    Shell.log.debug("Scan iterators :" + shellState.scanIteratorOptions.get(tableName));
+  }
+  
+  @Override
+  public String description() {
+    return "sets a table-specific scan iterator for this shell session";
+  }
+  
+  @Override
+  public Options getOptions() {
+    // Remove the options that specify which type of iterator this is, since
+    // they are all scan iterators with this command.
+    final HashSet<OptionGroup> groups = new HashSet<OptionGroup>();
+    final Options parentOptions = super.getOptions();
+    final Options modifiedOptions = new Options();
+    for (Iterator<?> it = parentOptions.getOptions().iterator(); it.hasNext();) {
+      Option o = (Option) it.next();
+      if (!IteratorScope.majc.name().equals(o.getOpt()) && !IteratorScope.minc.name().equals(o.getOpt()) && !IteratorScope.scan.name().equals(o.getOpt())) {
+        modifiedOptions.addOption(o);
+        OptionGroup group = parentOptions.getOptionGroup(o);
+        if (group != null)
+          groups.add(group);
+      }
+    }
+    for (OptionGroup group : groups) {
+      modifiedOptions.addOptionGroup(group);
+    }
+    return modifiedOptions;
+  }
+  
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/SetShellIterCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/SetShellIterCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/SetShellIterCommand.java
new file mode 100644
index 0000000..c7fea56
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/SetShellIterCommand.java
@@ -0,0 +1,131 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.IteratorSetting;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.core.iterators.IteratorUtil.IteratorScope;
+import org.apache.accumulo.core.iterators.SortedKeyValueIterator;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.ShellCommandException;
+import org.apache.accumulo.shell.ShellCommandException.ErrorCode;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.OptionGroup;
+import org.apache.commons.cli.Options;
+
+public class SetShellIterCommand extends SetIterCommand {
+  private Option profileOpt;
+
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException,
+      TableNotFoundException, IOException, ShellCommandException {
+    return super.execute(fullCommand, cl, shellState);
+  }
+  
+  @Override
+  protected void setTableProperties(final CommandLine cl, final Shell shellState, final int priority, final Map<String,String> options, final String classname,
+      final String name) throws AccumuloException, AccumuloSecurityException, ShellCommandException, TableNotFoundException {
+    // instead of setting table properties, just put the options in a list to use at scan time
+    
+    String profile = cl.getOptionValue(profileOpt.getOpt());
+
+    // instead of setting table properties, just put the options in a list to use at scan time
+    Class<?> loadClass;
+    try {
+      loadClass = getClass().getClassLoader().loadClass(classname);
+    } catch (ClassNotFoundException e) {
+      throw new ShellCommandException(ErrorCode.INITIALIZATION_FAILURE, "Unable to load " + classname);
+    }
+    try {
+      loadClass.asSubclass(SortedKeyValueIterator.class);
+    } catch (ClassCastException ex) {
+      throw new ShellCommandException(ErrorCode.INITIALIZATION_FAILURE, "xUnable to load " + classname  + " as type "
+          + SortedKeyValueIterator.class.getName());
+    }
+    
+    for (Iterator<Entry<String,String>> i = options.entrySet().iterator(); i.hasNext();) {
+      final Entry<String,String> entry = i.next();
+      if (entry.getValue() == null || entry.getValue().isEmpty()) {
+        i.remove();
+      }
+    }
+
+    List<IteratorSetting> tableScanIterators = shellState.iteratorProfiles.get(profile);
+    if (tableScanIterators == null) {
+      tableScanIterators = new ArrayList<IteratorSetting>();
+      shellState.iteratorProfiles.put(profile, tableScanIterators);
+    }
+    final IteratorSetting setting = new IteratorSetting(priority, name, classname);
+    setting.addOptions(options);
+
+    Iterator<IteratorSetting> iter = tableScanIterators.iterator();
+    while (iter.hasNext()) {
+      if (iter.next().getName().equals(name)) {
+        iter.remove();
+      }
+    }
+
+    tableScanIterators.add(setting);
+  }
+  
+  @Override
+  public String description() {
+    return "adds an iterator to a profile for this shell session";
+  }
+  
+  @Override
+  public Options getOptions() {
+    // Remove the options that specify which type of iterator this is, since
+    // they are all scan iterators with this command.
+    final HashSet<OptionGroup> groups = new HashSet<OptionGroup>();
+    final Options parentOptions = super.getOptions();
+    final Options modifiedOptions = new Options();
+    for (Iterator<?> it = parentOptions.getOptions().iterator(); it.hasNext();) {
+      Option o = (Option) it.next();
+      if (!IteratorScope.majc.name().equals(o.getOpt()) && !IteratorScope.minc.name().equals(o.getOpt()) && !IteratorScope.scan.name().equals(o.getOpt())
+          && !"table".equals(o.getLongOpt())) {
+        modifiedOptions.addOption(o);
+        OptionGroup group = parentOptions.getOptionGroup(o);
+        if (group != null)
+          groups.add(group);
+      }
+    }
+    for (OptionGroup group : groups) {
+      modifiedOptions.addOptionGroup(group);
+    }
+    
+    profileOpt = new Option("pn", "profile", true, "iterator profile name");
+    profileOpt.setRequired(true);
+    profileOpt.setArgName("profile");
+    
+    modifiedOptions.addOption(profileOpt);
+
+    return modifiedOptions;
+  }
+  
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/ShellPluginConfigurationCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/ShellPluginConfigurationCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/ShellPluginConfigurationCommand.java
new file mode 100644
index 0000000..45d48e7
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/ShellPluginConfigurationCommand.java
@@ -0,0 +1,146 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.util.Iterator;
+import java.util.Map.Entry;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.core.conf.Property;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.accumulo.start.classloader.vfs.AccumuloVFSClassLoader;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.OptionGroup;
+import org.apache.commons.cli.Options;
+import org.apache.log4j.Logger;
+
+public abstract class ShellPluginConfigurationCommand extends Command {
+  private Option removePluginOption, pluginClassOption, listPluginOption;
+  
+  private String pluginType;
+  
+  private Property tableProp;
+  
+  private String classOpt;
+  
+  ShellPluginConfigurationCommand(final String typeName, final Property tableProp, final String classOpt) {
+    this.pluginType = typeName;
+    this.tableProp = tableProp;
+    this.classOpt = classOpt;
+  }
+
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    final String tableName = OptUtil.getTableOpt(cl, shellState);
+    
+    if (cl.hasOption(removePluginOption.getOpt())) {
+      // Remove the property
+      removePlugin(cl, shellState, tableName);
+      
+      shellState.getReader().println("Removed "+pluginType+" on " + tableName);
+    } else if (cl.hasOption(listPluginOption.getOpt())) {
+      // Get the options for this table
+      final Iterator<Entry<String,String>> iter = shellState.getConnector().tableOperations().getProperties(tableName).iterator();
+      
+      while (iter.hasNext()) {
+        Entry<String,String> ent = iter.next();
+        
+        // List all parameters with the property name
+        if (ent.getKey().startsWith(tableProp.toString())) {
+          shellState.getReader().println(ent.getKey() + ": " + ent.getValue());
+        }
+      }
+    } else {
+      // Set the plugin with the provided options
+      String className = cl.getOptionValue(pluginClassOption.getOpt());
+      
+      // Set the plugin property on the table
+      setPlugin(cl, shellState, tableName, className);
+    }
+    
+    return 0;
+  }
+
+  protected void setPlugin(final CommandLine cl, final Shell shellState, final String tableName, final String className) throws AccumuloException, AccumuloSecurityException {
+    shellState.getConnector().tableOperations().setProperty(tableName, tableProp.toString(), className);
+  }
+  
+  protected void removePlugin(final CommandLine cl, final Shell shellState, final String tableName) throws AccumuloException, AccumuloSecurityException {
+    shellState.getConnector().tableOperations().removeProperty(tableName, tableProp.toString());
+  }
+  
+  public static <T> Class<? extends T> getPluginClass(final String tableName, final Shell shellState, final Class<T> clazz, final Property pluginProp) {
+    Iterator<Entry<String,String>> props;
+    try {
+      props = shellState.getConnector().tableOperations().getProperties(tableName).iterator();
+    } catch (AccumuloException e) {
+      return null;
+    } catch (TableNotFoundException e) {
+      return null;
+    }
+    
+    while (props.hasNext()) {
+      final Entry<String,String> ent = props.next();
+      if (ent.getKey().equals(pluginProp.toString())) {
+        Class<? extends T> pluginClazz;
+        try {
+          pluginClazz = AccumuloVFSClassLoader.loadClass(ent.getValue(), clazz);
+        } catch (ClassNotFoundException e) {
+          Logger.getLogger(ShellPluginConfigurationCommand.class).warn("Class not found" + e.getMessage());
+          return null;
+        }
+        
+        return pluginClazz;
+      }
+    }
+    
+    return null;
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+    final OptionGroup actionGroup = new OptionGroup();
+    
+    pluginClassOption = new Option(classOpt, pluginType, true, "fully qualified name of the " + pluginType + " class to use");
+    pluginClassOption.setArgName("className");
+    
+    // Action to take: apply (default), remove, list
+    removePluginOption = new Option("r", "remove", false, "remove the current "+pluginType+"");
+    listPluginOption = new Option("l", "list", false, "display the current "+pluginType+"");
+    
+    actionGroup.addOption(pluginClassOption);
+    actionGroup.addOption(removePluginOption);
+    actionGroup.addOption(listPluginOption);
+    actionGroup.setRequired(true);
+    
+    o.addOptionGroup(actionGroup);
+    o.addOption(OptUtil.tableOpt("table to set the "+pluginType+" on"));
+    
+    return o;
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+  
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/SleepCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/SleepCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/SleepCommand.java
new file mode 100644
index 0000000..1f7ed5d
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/SleepCommand.java
@@ -0,0 +1,46 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+
+public class SleepCommand extends Command {
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    final double secs = Double.parseDouble(cl.getArgs()[0]);
+    Thread.sleep((long) (secs * 1000));
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "sleeps for the given number of seconds";
+  }
+  
+  @Override
+  public int numArgs() {
+    return 1;
+  }
+  
+  @Override
+  public String usage() {
+    return getName() + " <seconds>";
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/SystemPermissionsCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/SystemPermissionsCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/SystemPermissionsCommand.java
new file mode 100644
index 0000000..7cf4584
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/SystemPermissionsCommand.java
@@ -0,0 +1,44 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.io.IOException;
+
+import org.apache.accumulo.core.security.SystemPermission;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+
+public class SystemPermissionsCommand extends Command {
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws IOException {
+    for (String p : SystemPermission.printableValues()) {
+      shellState.getReader().println(p);
+    }
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "displays a list of valid system permissions";
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/TableCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/TableCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/TableCommand.java
new file mode 100644
index 0000000..6a563ab
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/TableCommand.java
@@ -0,0 +1,60 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Token;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+
+public class TableCommand extends Command {
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException, TableNotFoundException {
+    final String tableName = cl.getArgs()[0];
+    if (!shellState.getConnector().tableOperations().exists(tableName)) {
+      throw new TableNotFoundException(null, tableName, null);
+    }
+    shellState.setTableName(tableName);
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "switches to the specified table";
+  }
+  
+  @Override
+  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> special) {
+    registerCompletionForTables(root, special);
+  }
+  
+  @Override
+  public String usage() {
+    return getName() + " <tableName>";
+  }
+  
+  @Override
+  public int numArgs() {
+    return 1;
+  }
+}


[47/53] [abbrv] git commit: ACCUMULO-1487 Fix build command in build.sh convenience script

Posted by el...@apache.org.
ACCUMULO-1487 Fix build command in build.sh convenience script


Project: http://git-wip-us.apache.org/repos/asf/accumulo/repo
Commit: http://git-wip-us.apache.org/repos/asf/accumulo/commit/479a36bd
Tree: http://git-wip-us.apache.org/repos/asf/accumulo/tree/479a36bd
Diff: http://git-wip-us.apache.org/repos/asf/accumulo/diff/479a36bd

Branch: refs/heads/ACCUMULO-378
Commit: 479a36bd991e831fba04118c51a605a601a86dec
Parents: 14e2b64
Author: Christopher Tubbs <ct...@apache.org>
Authored: Mon Apr 7 20:41:59 2014 -0400
Committer: Christopher Tubbs <ct...@apache.org>
Committed: Mon Apr 7 20:41:59 2014 -0400

----------------------------------------------------------------------
 assemble/build.sh | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/accumulo/blob/479a36bd/assemble/build.sh
----------------------------------------------------------------------
diff --git a/assemble/build.sh b/assemble/build.sh
index 31b2d2c..5f65419 100755
--- a/assemble/build.sh
+++ b/assemble/build.sh
@@ -52,13 +52,13 @@ if [[ $1 = '--create-release-candidate' ]]; then
 elif [[ $1 = '--seal-jars' ]]; then
   cacheGPG
   # build a tag, but with sealed jars
-  run mvn clean compile javadoc:aggregate install \
-   -P apache-release,seal-jars,thrift,native,assemble,docs
+  run mvn clean install \
+   -P apache-release,seal-jars,thrift,assemble,docs
 elif [[ $1 = '--test' ]]; then
   cacheGPG
   # build a tag, but with tests
-  run mvn clean compile javadoc:aggregate install \
-   -P apache-release,thrift,native,assemble,docs
+  run mvn clean install \
+   -P apache-release,thrift,assemble,docs
 else
   fail "Missing one of: --create-release-candidate, --test, --seal-jars"
 fi


[10/53] [abbrv] ACCUMULO-1897 Move shell into new package and module

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/OfflineCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/OfflineCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/OfflineCommand.java
deleted file mode 100644
index fde4514..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/OfflineCommand.java
+++ /dev/null
@@ -1,61 +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.accumulo.core.util.shell.commands;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.TableNotFoundException;
-import org.apache.accumulo.core.metadata.MetadataTable;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-
-public class OfflineCommand extends TableOperation {
-  
-  private boolean wait;
-  private Option waitOpt;
-  
-  @Override
-  public String description() {
-    return "starts the process of taking table offline";
-  }
-  
-  protected void doTableOp(final Shell shellState, final String tableName) throws AccumuloException, AccumuloSecurityException, TableNotFoundException {
-    if (tableName.equals(MetadataTable.NAME)) {
-      Shell.log.info("  You cannot take the " + MetadataTable.NAME + " offline.");
-    } else {
-      shellState.getConnector().tableOperations().offline(tableName, wait);
-      Shell.log.info("Offline of table " + tableName + (wait ? " completed." : " initiated..."));
-    }
-  }
-  
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    wait = cl.hasOption(waitOpt.getLongOpt());
-    return super.execute(fullCommand, cl, shellState);
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options opts = super.getOptions();
-    waitOpt = new Option("w", "wait", false, "wait for offline to finish");
-    opts.addOption(waitOpt); 
-    return opts;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/OnlineCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/OnlineCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/OnlineCommand.java
deleted file mode 100644
index 7b6ebe2..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/OnlineCommand.java
+++ /dev/null
@@ -1,61 +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.accumulo.core.util.shell.commands;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.TableNotFoundException;
-import org.apache.accumulo.core.metadata.RootTable;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-
-public class OnlineCommand extends TableOperation {
-  
-  private boolean wait;
-  private Option waitOpt;
-  
-  @Override
-  public String description() {
-    return "starts the process of putting a table online";
-  }
-  
-  @Override
-  protected void doTableOp(final Shell shellState, final String tableName) throws AccumuloException, AccumuloSecurityException, TableNotFoundException {
-    if (tableName.equals(RootTable.NAME)) {
-      Shell.log.info("  The " + RootTable.NAME + " is always online.");
-    } else {
-      shellState.getConnector().tableOperations().online(tableName, wait);
-      Shell.log.info("Online of table " + tableName + (wait ? " completed." : " initiated..."));
-    }
-  }
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    wait = cl.hasOption(waitOpt.getLongOpt());
-    return super.execute(fullCommand, cl, shellState);
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options opts = super.getOptions();
-    waitOpt = new Option("w", "wait", false, "wait for online to finish");
-    opts.addOption(waitOpt); 
-    return opts;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/OptUtil.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/OptUtil.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/OptUtil.java
deleted file mode 100644
index 9915bdf..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/OptUtil.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.accumulo.core.util.shell.commands;
-
-import java.io.UnsupportedEncodingException;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.NamespaceNotFoundException;
-import org.apache.accumulo.core.client.TableNotFoundException;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.OptionGroup;
-import org.apache.hadoop.io.Text;
-
-public abstract class OptUtil {
-  public static final String START_ROW_OPT = "b";
-  public static final String END_ROW_OPT = "e";
-
-  public static String getTableOpt(final CommandLine cl, final Shell shellState) throws TableNotFoundException {
-    String tableName;
-
-    if (cl.hasOption(Shell.tableOption)) {
-      tableName = cl.getOptionValue(Shell.tableOption);
-      if (!shellState.getConnector().tableOperations().exists(tableName)) {
-        throw new TableNotFoundException(tableName, tableName, "specified table that doesn't exist");
-      }
-    } else {
-      shellState.checkTableState();
-      tableName = shellState.getTableName();
-    }
-
-    return tableName;
-  }
-
-  public static String getNamespaceOpt(final CommandLine cl, final Shell shellState) throws NamespaceNotFoundException, AccumuloException,
-      AccumuloSecurityException {
-    String namespace = null;
-    if (cl.hasOption(Shell.namespaceOption)) {
-      namespace = cl.getOptionValue(Shell.namespaceOption);
-      if (!shellState.getConnector().namespaceOperations().exists(namespace)) {
-        throw new NamespaceNotFoundException(namespace, namespace, "specified namespace that doesn't exist");
-      }
-    } else {
-      throw new NamespaceNotFoundException(null, null, "no namespace specified");
-    }
-    return namespace;
-  }
-
-  public static Option tableOpt() {
-    return tableOpt("tableName");
-  }
-
-  public static Option tableOpt(final String description) {
-    final Option tableOpt = new Option(Shell.tableOption, "table", true, description);
-    tableOpt.setArgName("table");
-    tableOpt.setRequired(false);
-    return tableOpt;
-  }
-
-  public static Option namespaceOpt() {
-    return namespaceOpt("namespace");
-  }
-
-  public static Option namespaceOpt(final String description) {
-    final Option namespaceOpt = new Option(Shell.namespaceOption, "namespace", true, description);
-    namespaceOpt.setArgName("namespace");
-    namespaceOpt.setRequired(false);
-    return namespaceOpt;
-  }
-
-  public static enum AdlOpt {
-    ADD("a"), DELETE("d"), LIST("l");
-
-    public final String opt;
-
-    private AdlOpt(String opt) {
-      this.opt = opt;
-    }
-  }
-
-  public static AdlOpt getAldOpt(final CommandLine cl) {
-    if (cl.hasOption(AdlOpt.ADD.opt)) {
-      return AdlOpt.ADD;
-    } else if (cl.hasOption(AdlOpt.DELETE.opt)) {
-      return AdlOpt.DELETE;
-    } else {
-      return AdlOpt.LIST;
-    }
-  }
-
-  public static OptionGroup addListDeleteGroup(final String name) {
-    final Option addOpt = new Option(AdlOpt.ADD.opt, "add", false, "add " + name);
-    final Option deleteOpt = new Option(AdlOpt.DELETE.opt, "delete", false, "delete " + name);
-    final Option listOpt = new Option(AdlOpt.LIST.opt, "list", false, "list " + name + "(s)");
-    final OptionGroup og = new OptionGroup();
-    og.addOption(addOpt);
-    og.addOption(deleteOpt);
-    og.addOption(listOpt);
-    og.setRequired(true);
-    return og;
-  }
-
-  public static Option startRowOpt() {
-    final Option o = new Option(START_ROW_OPT, "begin-row", true, "begin row (inclusive)");
-    o.setArgName("begin-row");
-    return o;
-  }
-
-  public static Option endRowOpt() {
-    final Option o = new Option(END_ROW_OPT, "end-row", true, "end row (inclusive)");
-    o.setArgName("end-row");
-    return o;
-  }
-
-  public static Text getStartRow(final CommandLine cl) throws UnsupportedEncodingException {
-    if (cl.hasOption(START_ROW_OPT)) {
-      return new Text(cl.getOptionValue(START_ROW_OPT).getBytes(Shell.CHARSET));
-    } else {
-      return null;
-    }
-  }
-
-  public static Text getEndRow(final CommandLine cl) throws UnsupportedEncodingException {
-    if (cl.hasOption(END_ROW_OPT)) {
-      return new Text(cl.getOptionValue(END_ROW_OPT).getBytes(Shell.CHARSET));
-    } else {
-      return null;
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/PasswdCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/PasswdCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/PasswdCommand.java
deleted file mode 100644
index 86446a2..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/PasswdCommand.java
+++ /dev/null
@@ -1,96 +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.accumulo.core.util.shell.commands;
-
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.impl.thrift.SecurityErrorCode;
-import org.apache.accumulo.core.client.security.tokens.PasswordToken;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-
-public class PasswdCommand extends Command {
-  private Option userOpt;
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException, IOException {
-    final String currentUser = shellState.getConnector().whoami();
-    final String user = cl.getOptionValue(userOpt.getOpt(), currentUser);
-    
-    String password = null;
-    String passwordConfirm = null;
-    String oldPassword = null;
-    
-    oldPassword = shellState.readMaskedLine("Enter current password for '" + currentUser + "': ", '*');
-    if (oldPassword == null) {
-      shellState.getReader().println();
-      return 0;
-    } // user canceled
-    
-    if (!shellState.getConnector().securityOperations().authenticateUser(currentUser, new PasswordToken(oldPassword)))
-      throw new AccumuloSecurityException(user, SecurityErrorCode.BAD_CREDENTIALS);
-    
-    password = shellState.readMaskedLine("Enter new password for '" + user + "': ", '*');
-    if (password == null) {
-      shellState.getReader().println();
-      return 0;
-    } // user canceled
-    passwordConfirm = shellState.readMaskedLine("Please confirm new password for '" + user + "': ", '*');
-    if (passwordConfirm == null) {
-      shellState.getReader().println();
-      return 0;
-    } // user canceled
-    
-    if (!password.equals(passwordConfirm)) {
-      throw new IllegalArgumentException("Passwords do not match");
-    }
-    byte[] pass = password.getBytes(StandardCharsets.UTF_8);
-    shellState.getConnector().securityOperations().changeLocalUserPassword(user, new PasswordToken(pass));
-    // update the current credentials if the password changed was for
-    // the current user
-    if (shellState.getConnector().whoami().equals(user)) {
-      shellState.updateUser(user, new PasswordToken(pass));
-    }
-    Shell.log.debug("Changed password for user " + user);
-    return 0;
-  }
-  
-  @Override
-  public String description() {
-    return "changes a user's password";
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-    userOpt = new Option(Shell.userOption, "user", true, "user to operate on");
-    userOpt.setArgName("user");
-    o.addOption(userOpt);
-    return o;
-  }
-  
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/PingCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/PingCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/PingCommand.java
deleted file mode 100644
index d0eb615..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/PingCommand.java
+++ /dev/null
@@ -1,82 +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.accumulo.core.util.shell.commands;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.accumulo.core.client.admin.InstanceOperations;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-
-/**
- * 
- */
-public class PingCommand extends Command {
-  
-  private Option tserverOption, disablePaginationOpt;
-  
-  @Override
-  public String description() {
-    return "ping tablet servers";
-  }
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    
-    List<String> tservers;
-    
-    final InstanceOperations instanceOps = shellState.getConnector().instanceOperations();
-    
-    final boolean paginate = !cl.hasOption(disablePaginationOpt.getOpt());
-    
-    if (cl.hasOption(tserverOption.getOpt())) {
-      tservers = new ArrayList<String>();
-      tservers.add(cl.getOptionValue(tserverOption.getOpt()));
-    } else {
-      tservers = instanceOps.getTabletServers();
-    }
-    
-    shellState.printLines(new PingIterator(tservers, instanceOps), paginate);
-    
-    return 0;
-  }
-  
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options opts = new Options();
-    
-    tserverOption = new Option("ts", "tabletServer", true, "tablet server to ping");
-    tserverOption.setArgName("tablet server");
-    opts.addOption(tserverOption);
-    
-    disablePaginationOpt = new Option("np", "no-pagination", false, "disable pagination of output");
-    opts.addOption(disablePaginationOpt);
-    
-    return opts;
-  }
-  
-}
-

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/PingIterator.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/PingIterator.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/PingIterator.java
deleted file mode 100644
index 2a1020e..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/PingIterator.java
+++ /dev/null
@@ -1,58 +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.accumulo.core.util.shell.commands;
-
-import java.util.Iterator;
-import java.util.List;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.admin.InstanceOperations;
-
-class PingIterator implements Iterator<String> {
-  
-  private Iterator<String> iter;
-  private InstanceOperations instanceOps;
-
-  PingIterator(List<String> tservers, InstanceOperations instanceOps) {
-    iter = tservers.iterator();
-    this.instanceOps = instanceOps;
-  }
-  
-  @Override
-  public boolean hasNext() {
-    return iter.hasNext();
-  }
-  
-  @Override
-  public String next() {
-    String tserver = iter.next();
-    
-    try {
-      instanceOps.ping(tserver);
-    } catch (AccumuloException e) {
-      return tserver + " ERROR " + e.getMessage();
-    }
-    
-    return tserver + " OK";
-  }
-  
-  @Override
-  public void remove() {
-    throw new UnsupportedOperationException();
-  }
-  
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/QuestionCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/QuestionCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/QuestionCommand.java
deleted file mode 100644
index b12c2cb..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/QuestionCommand.java
+++ /dev/null
@@ -1,24 +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.accumulo.core.util.shell.commands;
-
-public class QuestionCommand extends HelpCommand {
-  @Override
-  public String getName() {
-    return "?";
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/QuitCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/QuitCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/QuitCommand.java
deleted file mode 100644
index 8aa95f5..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/QuitCommand.java
+++ /dev/null
@@ -1,19 +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.accumulo.core.util.shell.commands;
-
-public class QuitCommand extends ExitCommand {}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/QuotedStringTokenizer.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/QuotedStringTokenizer.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/QuotedStringTokenizer.java
deleted file mode 100644
index 76ebb8f..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/QuotedStringTokenizer.java
+++ /dev/null
@@ -1,141 +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.accumulo.core.util.shell.commands;
-
-import java.io.UnsupportedEncodingException;
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.Iterator;
-
-import org.apache.accumulo.core.util.BadArgumentException;
-import org.apache.accumulo.core.util.shell.Shell;
-
-/**
- * A basic tokenizer for generating tokens from a string. It understands quoted strings and escaped quote characters.
- * 
- * You can use the escape sequence '\' to escape single quotes, double quotes, and spaces only, in addition to the escape character itself.
- * 
- * The behavior is the same for single and double quoted strings. (i.e. '\'' is the same as "\'")
- */
-
-public class QuotedStringTokenizer implements Iterable<String> {
-  private ArrayList<String> tokens;
-  private String input;
-  
-  public QuotedStringTokenizer(final String t) throws BadArgumentException {
-    tokens = new ArrayList<String>();
-    this.input = t;
-    try {
-      createTokens();
-    } catch (UnsupportedEncodingException e) {
-      throw new IllegalArgumentException(e.getMessage());
-    }
-  }
-  
-  public String[] getTokens() {
-    return tokens.toArray(new String[tokens.size()]);
-  }
-  
-  private void createTokens() throws BadArgumentException, UnsupportedEncodingException {
-    boolean inQuote = false;
-    boolean inEscapeSequence = false;
-    String hexChars = null;
-    char inQuoteChar = '"';
-    
-    final byte[] token = new byte[input.length()];
-    int tokenLength = 0;
-    final byte[] inputBytes = input.getBytes(StandardCharsets.UTF_8);
-    for (int i = 0; i < input.length(); ++i) {
-      final char ch = input.charAt(i);
-      
-      // if I ended up in an escape sequence, check for valid escapable character, and add it as a literal
-      if (inEscapeSequence) {
-        inEscapeSequence = false;
-        if (ch == 'x') {
-          hexChars = "";
-        } else if (ch == ' ' || ch == '\'' || ch == '"' || ch == '\\') {
-          token[tokenLength++] = inputBytes[i];
-        } else {
-          throw new BadArgumentException("can only escape single quotes, double quotes, the space character, the backslash, and hex input", input, i);
-        }
-      }
-      // in a hex escape sequence
-      else if (hexChars != null) {
-        final int digit = Character.digit(ch, 16);
-        if (digit < 0) {
-          throw new BadArgumentException("expected hex character", input, i);
-        }
-        hexChars += ch;
-        if (hexChars.length() == 2) {
-          byte b;
-          try {
-            b = (byte) (0xff & Short.parseShort(hexChars, 16));
-            if (!Character.isValidCodePoint(0xff & b))
-              throw new NumberFormatException();
-          } catch (NumberFormatException e) {
-            throw new BadArgumentException("unsupported non-ascii character", input, i);
-          }
-          token[tokenLength++] = b;
-          hexChars = null;
-        }
-      }
-      // in a quote, either end the quote, start escape, or continue a token
-      else if (inQuote) {
-        if (ch == inQuoteChar) {
-          inQuote = false;
-          tokens.add(new String(token, 0, tokenLength, Shell.CHARSET));
-          tokenLength = 0;
-        } else if (ch == '\\') {
-          inEscapeSequence = true;
-        } else {
-          token[tokenLength++] = inputBytes[i];
-        }
-      }
-      // not in a quote, either enter a quote, end a token, start escape, or continue a token
-      else {
-        if (ch == '\'' || ch == '"') {
-          if (tokenLength > 0) {
-            tokens.add(new String(token, 0, tokenLength, Shell.CHARSET));
-            tokenLength = 0;
-          }
-          inQuote = true;
-          inQuoteChar = ch;
-        } else if (ch == ' ' && tokenLength > 0) {
-          tokens.add(new String(token, 0, tokenLength, Shell.CHARSET));
-          tokenLength = 0;
-        } else if (ch == '\\') {
-          inEscapeSequence = true;
-        } else if (ch != ' ') {
-          token[tokenLength++] = inputBytes[i];
-        }
-      }
-    }
-    if (inQuote) {
-      throw new BadArgumentException("missing terminating quote", input, input.length());
-    } else if (inEscapeSequence || hexChars != null) {
-      throw new BadArgumentException("escape sequence not complete", input, input.length());
-    }
-    if (tokenLength > 0) {
-      tokens.add(new String(token, 0, tokenLength, Shell.CHARSET));
-    }
-  }
-  
-  @Override
-  public Iterator<String> iterator() {
-    return tokens.iterator();
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/RenameNamespaceCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/RenameNamespaceCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/RenameNamespaceCommand.java
deleted file mode 100644
index d7ff7c3..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/RenameNamespaceCommand.java
+++ /dev/null
@@ -1,79 +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.accumulo.core.util.shell.commands;
-
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.NamespaceExistsException;
-import org.apache.accumulo.core.client.NamespaceNotFoundException;
-import org.apache.accumulo.core.client.TableExistsException;
-import org.apache.accumulo.core.client.TableNotFoundException;
-import org.apache.accumulo.core.client.impl.Namespaces;
-import org.apache.accumulo.core.client.impl.Tables;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.accumulo.core.util.shell.Token;
-import org.apache.commons.cli.CommandLine;
-
-public class RenameNamespaceCommand extends Command {
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException,
-      TableNotFoundException, TableExistsException, NamespaceNotFoundException, NamespaceExistsException {
-    String old = cl.getArgs()[0];
-    String newer = cl.getArgs()[1];
-    boolean resetContext = false;
-    String currentTableId = "";
-    if (!(shellState.getTableName() == null) && !shellState.getTableName().isEmpty()) {
-      String namespaceId = Namespaces.getNamespaceId(shellState.getInstance(), old);
-      List<String> tableIds = Namespaces.getTableIds(shellState.getInstance(), namespaceId);
-      currentTableId = Tables.getTableId(shellState.getInstance(), shellState.getTableName());
-      resetContext = tableIds.contains(currentTableId);
-    }
-
-    shellState.getConnector().namespaceOperations().rename(old, newer);
-
-    if (resetContext) {
-      shellState.setTableName(Tables.getTableName(shellState.getInstance(), currentTableId));
-    }
-
-    return 0;
-  }
-
-  @Override
-  public String usage() {
-    return getName() + " <current namespace> <new namespace>";
-  }
-
-  @Override
-  public String description() {
-    return "renames a namespace";
-  }
-
-  @Override
-  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> special) {
-    registerCompletionForNamespaces(root, special);
-  }
-
-  @Override
-  public int numArgs() {
-    return 2;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/RenameTableCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/RenameTableCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/RenameTableCommand.java
deleted file mode 100644
index 38d8158..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/RenameTableCommand.java
+++ /dev/null
@@ -1,62 +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.accumulo.core.util.shell.commands;
-
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.TableExistsException;
-import org.apache.accumulo.core.client.TableNotFoundException;
-import org.apache.accumulo.core.client.impl.Tables;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.accumulo.core.util.shell.Token;
-import org.apache.commons.cli.CommandLine;
-
-public class RenameTableCommand extends Command {
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException,
-      TableNotFoundException, TableExistsException {
-    shellState.getConnector().tableOperations().rename(cl.getArgs()[0], cl.getArgs()[1]);
-    if (shellState.getTableName().equals(Tables.qualified(cl.getArgs()[0]))) {
-      shellState.setTableName(cl.getArgs()[1]);
-    }
-    return 0;
-  }
-
-  @Override
-  public String usage() {
-    return getName() + " <current table name> <new table name>";
-  }
-
-  @Override
-  public String description() {
-    return "renames a table";
-  }
-
-  @Override
-  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> completionSet) {
-    registerCompletionForTables(root, completionSet);
-  }
-
-  @Override
-  public int numArgs() {
-    return 2;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/RevokeCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/RevokeCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/RevokeCommand.java
deleted file mode 100644
index dac864d..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/RevokeCommand.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.accumulo.core.util.shell.commands;
-
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.accumulo.core.security.NamespacePermission;
-import org.apache.accumulo.core.security.SystemPermission;
-import org.apache.accumulo.core.security.TablePermission;
-import org.apache.accumulo.core.util.BadArgumentException;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.accumulo.core.util.shell.Token;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.OptionGroup;
-import org.apache.commons.cli.Options;
-
-public class RevokeCommand extends TableOperation {
-  {
-    disableUnflaggedTableOptions();
-  }
-
-  private Option systemOpt, userOpt;
-  private String user;
-  private String[] permission;
-
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    user = cl.hasOption(userOpt.getOpt()) ? cl.getOptionValue(userOpt.getOpt()) : shellState.getConnector().whoami();
-
-    permission = cl.getArgs()[0].split("\\.", 2);
-    if (cl.hasOption(systemOpt.getOpt()) && permission[0].equalsIgnoreCase("System")) {
-      try {
-        shellState.getConnector().securityOperations().revokeSystemPermission(user, SystemPermission.valueOf(permission[1]));
-        Shell.log.debug("Revoked from " + user + " the " + permission[1] + " permission");
-      } catch (IllegalArgumentException e) {
-        throw new BadArgumentException("No such system permission", fullCommand, fullCommand.indexOf(cl.getArgs()[0]));
-      }
-    } else if (permission[0].equalsIgnoreCase("Table")) {
-      super.execute(fullCommand, cl, shellState);
-    } else if (permission[0].equalsIgnoreCase("Namespace")) {
-      if (cl.hasOption(optNamespace.getOpt())) {
-        try {
-          shellState.getConnector().securityOperations()
-              .revokeNamespacePermission(user, cl.getOptionValue(optNamespace.getOpt()), NamespacePermission.valueOf(permission[1]));
-        } catch (IllegalArgumentException e) {
-          throw new BadArgumentException("No such namespace permission", fullCommand, fullCommand.indexOf(cl.getArgs()[0]));
-        }
-      } else {
-        throw new BadArgumentException("No namespace specified to apply permission to", fullCommand, fullCommand.indexOf(cl.getArgs()[0]));
-      }
-    } else {
-      throw new BadArgumentException("Unrecognized permission", fullCommand, fullCommand.indexOf(cl.getArgs()[0]));
-    }
-    return 0;
-  }
-
-  @Override
-  protected void doTableOp(final Shell shellState, final String tableName) throws Exception {
-    try {
-      shellState.getConnector().securityOperations().revokeTablePermission(user, tableName, TablePermission.valueOf(permission[1]));
-      Shell.log.debug("Revoked from " + user + " the " + permission[1] + " permission on table " + tableName);
-    } catch (IllegalArgumentException e) {
-      throw new IllegalArgumentException("No such table permission", e);
-    }
-  }
-
-  @Override
-  public String description() {
-    return "revokes system or table permissions from a user";
-  }
-
-  @Override
-  public String usage() {
-    return getName() + " <permission>";
-  }
-
-  @Override
-  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> completionSet) {
-    final Token cmd = new Token(getName());
-    cmd.addSubcommand(new Token(TablePermission.printableValues()));
-    cmd.addSubcommand(new Token(SystemPermission.printableValues()));
-    cmd.addSubcommand(new Token(NamespacePermission.printableValues()));
-    root.addSubcommand(cmd);
-  }
-
-  @Override
-  public Options getOptions() {
-    super.getOptions();
-    final Options o = new Options();
-
-    final OptionGroup group = new OptionGroup();
-
-    systemOpt = new Option("s", "system", false, "revoke a system permission");
-
-    optNamespace = new Option(Shell.namespaceOption, "namespace", true, "name of a namespace to operate on");
-    optNamespace.setArgName("namespace");
-
-    group.addOption(systemOpt);
-    group.addOption(optTableName);
-    group.addOption(optTablePattern);
-    group.addOption(optNamespace);
-
-    o.addOptionGroup(group);
-    userOpt = new Option(Shell.userOption, "user", true, "user to operate on");
-    userOpt.setArgName("username");
-    userOpt.setRequired(true);
-    o.addOption(userOpt);
-
-    return o;
-  }
-
-  @Override
-  public int numArgs() {
-    return 1;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ScanCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ScanCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ScanCommand.java
deleted file mode 100644
index f3a0663..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ScanCommand.java
+++ /dev/null
@@ -1,334 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.accumulo.core.util.shell.commands;
-
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.util.List;
-import java.util.Map.Entry;
-import java.util.concurrent.TimeUnit;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.IteratorSetting;
-import org.apache.accumulo.core.client.Scanner;
-import org.apache.accumulo.core.client.ScannerBase;
-import org.apache.accumulo.core.conf.AccumuloConfiguration;
-import org.apache.accumulo.core.data.Key;
-import org.apache.accumulo.core.data.Range;
-import org.apache.accumulo.core.data.Value;
-import org.apache.accumulo.core.security.Authorizations;
-import org.apache.accumulo.core.util.format.BinaryFormatter;
-import org.apache.accumulo.core.util.format.Formatter;
-import org.apache.accumulo.core.util.interpret.DefaultScanInterpreter;
-import org.apache.accumulo.core.util.interpret.ScanInterpreter;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.accumulo.core.util.shell.Shell.PrintFile;
-import org.apache.accumulo.start.classloader.vfs.AccumuloVFSClassLoader;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-import org.apache.hadoop.io.Text;
-
-public class ScanCommand extends Command {
-  
-  private Option scanOptAuths, scanOptRow, scanOptColumns, disablePaginationOpt, showFewOpt, formatterOpt, interpreterOpt, formatterInterpeterOpt,
-      outputFileOpt;
-  
-  protected Option timestampOpt;
-  private Option optStartRowExclusive;
-  private Option optEndRowExclusive;
-  private Option timeoutOption;
-  private Option profileOpt;
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    final PrintFile printFile = getOutputFile(cl);
-    final String tableName = OptUtil.getTableOpt(cl, shellState);
-    
-    final Class<? extends Formatter> formatter = getFormatter(cl, tableName, shellState);
-    final ScanInterpreter interpeter = getInterpreter(cl, tableName, shellState);
-    
-    // handle first argument, if present, the authorizations list to
-    // scan with
-    final Authorizations auths = getAuths(cl, shellState);
-    final Scanner scanner = shellState.getConnector().createScanner(tableName, auths);
-    
-    // handle session-specific scan iterators
-    addScanIterators(shellState, cl, scanner, tableName);
-    
-    // handle remaining optional arguments
-    scanner.setRange(getRange(cl, interpeter));
-    
-    // handle columns
-    fetchColumns(cl, scanner, interpeter);
-    
-    // set timeout
-    scanner.setTimeout(getTimeout(cl), TimeUnit.MILLISECONDS);
-    
-    // output the records
-    if (cl.hasOption(showFewOpt.getOpt())) {
-      final String showLength = cl.getOptionValue(showFewOpt.getOpt());
-      try {
-        final int length = Integer.parseInt(showLength);
-        if (length < 1) {
-          throw new IllegalArgumentException();
-        }
-        BinaryFormatter.getlength(length);
-        printBinaryRecords(cl, shellState, scanner, printFile);
-      } catch (NumberFormatException nfe) {
-        shellState.getReader().println("Arg must be an integer.");
-      } catch (IllegalArgumentException iae) {
-        shellState.getReader().println("Arg must be greater than one.");
-      }
-      
-    } else {
-      printRecords(cl, shellState, scanner, formatter, printFile);
-    }
-    if (printFile != null) {
-      printFile.close();
-    }
-    
-    return 0;
-  }
-  
-  protected long getTimeout(final CommandLine cl) {
-    if (cl.hasOption(timeoutOption.getLongOpt())) {
-      return AccumuloConfiguration.getTimeInMillis(cl.getOptionValue(timeoutOption.getLongOpt()));
-    }
-    
-    return Long.MAX_VALUE;
-  }
-  
-  protected void addScanIterators(final Shell shellState, CommandLine cl, final Scanner scanner, final String tableName) {
-    
-    List<IteratorSetting> tableScanIterators;
-    if (cl.hasOption(profileOpt.getOpt())) {
-      String profile = cl.getOptionValue(profileOpt.getOpt());
-      tableScanIterators = shellState.iteratorProfiles.get(profile);
-      
-      if (tableScanIterators == null) {
-        throw new IllegalArgumentException("Profile " + profile + " does not exist");
-      }
-    } else {
-      tableScanIterators = shellState.scanIteratorOptions.get(tableName);
-      if (tableScanIterators == null) {
-        Shell.log.debug("Found no scan iterators to set");
-        return;
-      }
-    }
-    
-    Shell.log.debug("Found " + tableScanIterators.size() + " scan iterators to set");
-    
-    for (IteratorSetting setting : tableScanIterators) {
-      Shell.log.debug("Setting scan iterator " + setting.getName() + " at priority " + setting.getPriority() + " using class name "
-          + setting.getIteratorClass());
-      for (Entry<String,String> option : setting.getOptions().entrySet()) {
-        Shell.log.debug("Setting option for " + setting.getName() + ": " + option.getKey() + "=" + option.getValue());
-      }
-      scanner.addScanIterator(setting);
-    }
-  }
-  
-  protected void printRecords(final CommandLine cl, final Shell shellState, final Iterable<Entry<Key,Value>> scanner, final Class<? extends Formatter> formatter)
-      throws IOException {
-    printRecords(cl, shellState, scanner, formatter, null);
-  }
-  
-  protected void printRecords(final CommandLine cl, final Shell shellState, final Iterable<Entry<Key,Value>> scanner,
-      final Class<? extends Formatter> formatter, PrintFile outFile) throws IOException {
-    if (outFile == null) {
-      shellState.printRecords(scanner, cl.hasOption(timestampOpt.getOpt()), !cl.hasOption(disablePaginationOpt.getOpt()), formatter);
-    } else {
-      shellState.printRecords(scanner, cl.hasOption(timestampOpt.getOpt()), !cl.hasOption(disablePaginationOpt.getOpt()), formatter, outFile);
-    }
-  }
-  
-  protected void printBinaryRecords(final CommandLine cl, final Shell shellState, final Iterable<Entry<Key,Value>> scanner) throws IOException {
-    printBinaryRecords(cl, shellState, scanner, null);
-  }
-  
-  protected void printBinaryRecords(final CommandLine cl, final Shell shellState, final Iterable<Entry<Key,Value>> scanner, PrintFile outFile)
-      throws IOException {
-    if (outFile == null) {
-      shellState.printBinaryRecords(scanner, cl.hasOption(timestampOpt.getOpt()), !cl.hasOption(disablePaginationOpt.getOpt()));
-    } else {
-      shellState.printBinaryRecords(scanner, cl.hasOption(timestampOpt.getOpt()), !cl.hasOption(disablePaginationOpt.getOpt()), outFile);
-    }
-  }
-  
-  protected ScanInterpreter getInterpreter(final CommandLine cl, final String tableName, final Shell shellState) throws Exception {
-    
-    Class<? extends ScanInterpreter> clazz = null;
-    try {
-      if (cl.hasOption(interpreterOpt.getOpt())) {
-        clazz = AccumuloVFSClassLoader.loadClass(cl.getOptionValue(interpreterOpt.getOpt()), ScanInterpreter.class);
-      } else if (cl.hasOption(formatterInterpeterOpt.getOpt())) {
-        clazz = AccumuloVFSClassLoader.loadClass(cl.getOptionValue(formatterInterpeterOpt.getOpt()), ScanInterpreter.class);
-      }
-    } catch (ClassNotFoundException e) {
-      shellState.getReader().println("Interpreter class could not be loaded.\n" + e.getMessage());
-    }
-    
-    if (clazz == null)
-      clazz = InterpreterCommand.getCurrentInterpreter(tableName, shellState);
-    
-    if (clazz == null)
-      clazz = DefaultScanInterpreter.class;
-    
-    return clazz.newInstance();
-  }
-  
-  protected Class<? extends Formatter> getFormatter(final CommandLine cl, final String tableName, final Shell shellState) throws IOException {
-    
-    try {
-      if (cl.hasOption(formatterOpt.getOpt())) {
-        return AccumuloVFSClassLoader.loadClass(cl.getOptionValue(formatterOpt.getOpt()), Formatter.class);
-        
-      } else if (cl.hasOption(formatterInterpeterOpt.getOpt())) {
-        return AccumuloVFSClassLoader.loadClass(cl.getOptionValue(formatterInterpeterOpt.getOpt()), Formatter.class);
-      }
-    } catch (ClassNotFoundException e) {
-      shellState.getReader().println("Formatter class could not be loaded.\n" + e.getMessage());
-    }
-    
-    return shellState.getFormatter(tableName);
-  }
-  
-  protected void fetchColumns(final CommandLine cl, final ScannerBase scanner, final ScanInterpreter formatter) throws UnsupportedEncodingException {
-    if (cl.hasOption(scanOptColumns.getOpt())) {
-      for (String a : cl.getOptionValue(scanOptColumns.getOpt()).split(",")) {
-        final String sa[] = a.split(":", 2);
-        if (sa.length == 1) {
-          scanner.fetchColumnFamily(formatter.interpretColumnFamily(new Text(a.getBytes(Shell.CHARSET))));
-        } else {
-          scanner.fetchColumn(formatter.interpretColumnFamily(new Text(sa[0].getBytes(Shell.CHARSET))),
-              formatter.interpretColumnQualifier(new Text(sa[1].getBytes(Shell.CHARSET))));
-        }
-      }
-    }
-  }
-  
-  protected Range getRange(final CommandLine cl, final ScanInterpreter formatter) throws UnsupportedEncodingException {
-    if ((cl.hasOption(OptUtil.START_ROW_OPT) || cl.hasOption(OptUtil.END_ROW_OPT)) && cl.hasOption(scanOptRow.getOpt())) {
-      // did not see a way to make commons cli do this check... it has mutually exclusive options but does not support the or
-      throw new IllegalArgumentException("Options -" + scanOptRow.getOpt() + " AND (-" + OptUtil.START_ROW_OPT + " OR -" + OptUtil.END_ROW_OPT
-          + ") are mutally exclusive ");
-    }
-    
-    if (cl.hasOption(scanOptRow.getOpt())) {
-      return new Range(formatter.interpretRow(new Text(cl.getOptionValue(scanOptRow.getOpt()).getBytes(Shell.CHARSET))));
-    } else {
-      Text startRow = OptUtil.getStartRow(cl);
-      if (startRow != null)
-        startRow = formatter.interpretBeginRow(startRow);
-      Text endRow = OptUtil.getEndRow(cl);
-      if (endRow != null)
-        endRow = formatter.interpretEndRow(endRow);
-      final boolean startInclusive = !cl.hasOption(optStartRowExclusive.getOpt());
-      final boolean endInclusive = !cl.hasOption(optEndRowExclusive.getOpt());
-      return new Range(startRow, startInclusive, endRow, endInclusive);
-    }
-  }
-  
-  protected Authorizations getAuths(final CommandLine cl, final Shell shellState) throws AccumuloSecurityException, AccumuloException {
-    final String user = shellState.getConnector().whoami();
-    Authorizations auths = shellState.getConnector().securityOperations().getUserAuthorizations(user);
-    if (cl.hasOption(scanOptAuths.getOpt())) {
-      auths = ScanCommand.parseAuthorizations(cl.getOptionValue(scanOptAuths.getOpt()));
-    }
-    return auths;
-  }
-  
-  static Authorizations parseAuthorizations(final String field) {
-    if (field == null || field.isEmpty()) {
-      return Authorizations.EMPTY;
-    }
-    return new Authorizations(field.split(","));
-  }
-  
-  @Override
-  public String description() {
-    return "scans the table, and displays the resulting records";
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-    
-    scanOptAuths = new Option("s", "scan-authorizations", true, "scan authorizations (all user auths are used if this argument is not specified)");
-    optStartRowExclusive = new Option("be", "begin-exclusive", false, "make start row exclusive (by default it's inclusive)");
-    optStartRowExclusive.setArgName("begin-exclusive");
-    optEndRowExclusive = new Option("ee", "end-exclusive", false, "make end row exclusive (by default it's inclusive)");
-    optEndRowExclusive.setArgName("end-exclusive");
-    scanOptRow = new Option("r", "row", true, "row to scan");
-    scanOptColumns = new Option("c", "columns", true, "comma-separated columns");
-    timestampOpt = new Option("st", "show-timestamps", false, "display timestamps");
-    disablePaginationOpt = new Option("np", "no-pagination", false, "disable pagination of output");
-    showFewOpt = new Option("f", "show few", true, "show only a specified number of characters");
-    formatterOpt = new Option("fm", "formatter", true, "fully qualified name of the formatter class to use");
-    interpreterOpt = new Option("i", "interpreter", true, "fully qualified name of the interpreter class to use");
-    formatterInterpeterOpt = new Option("fi", "fmt-interpreter", true, "fully qualified name of a class that is a formatter and interpreter");
-    timeoutOption = new Option(null, "timeout", true,
-        "time before scan should fail if no data is returned. If no unit is given assumes seconds.  Units d,h,m,s,and ms are supported.  e.g. 30s or 100ms");
-    outputFileOpt = new Option("o", "output", true, "local file to write the scan output to");
-    
-    scanOptAuths.setArgName("comma-separated-authorizations");
-    scanOptRow.setArgName("row");
-    scanOptColumns.setArgName("<columnfamily>[:<columnqualifier>]{,<columnfamily>[:<columnqualifier>]}");
-    showFewOpt.setRequired(false);
-    showFewOpt.setArgName("int");
-    formatterOpt.setArgName("className");
-    timeoutOption.setArgName("timeout");
-    outputFileOpt.setArgName("file");
-    
-    profileOpt = new Option("pn", "profile", true, "iterator profile name");
-    profileOpt.setArgName("profile");
-    
-    o.addOption(scanOptAuths);
-    o.addOption(scanOptRow);
-    o.addOption(OptUtil.startRowOpt());
-    o.addOption(OptUtil.endRowOpt());
-    o.addOption(optStartRowExclusive);
-    o.addOption(optEndRowExclusive);
-    o.addOption(scanOptColumns);
-    o.addOption(timestampOpt);
-    o.addOption(disablePaginationOpt);
-    o.addOption(OptUtil.tableOpt("table to be scanned"));
-    o.addOption(showFewOpt);
-    o.addOption(formatterOpt);
-    o.addOption(interpreterOpt);
-    o.addOption(formatterInterpeterOpt);
-    o.addOption(timeoutOption);
-    o.addOption(outputFileOpt);
-    o.addOption(profileOpt);
-    
-    return o;
-  }
-  
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-  
-  protected PrintFile getOutputFile(final CommandLine cl) throws FileNotFoundException {
-    final String outputFile = cl.getOptionValue(outputFileOpt.getOpt());
-    return (outputFile == null ? null : new PrintFile(outputFile));
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ScriptCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ScriptCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ScriptCommand.java
deleted file mode 100644
index 5a0eee0..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ScriptCommand.java
+++ /dev/null
@@ -1,290 +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.accumulo.core.util.shell.commands;
-
-import java.io.File;
-import java.io.FileReader;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.Reader;
-import java.io.Writer;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Set;
-import java.util.TreeSet;
-
-import javax.script.Bindings;
-import javax.script.Compilable;
-import javax.script.CompiledScript;
-import javax.script.Invocable;
-import javax.script.ScriptContext;
-import javax.script.ScriptEngine;
-import javax.script.ScriptEngineFactory;
-import javax.script.ScriptEngineManager;
-import javax.script.ScriptException;
-import javax.script.SimpleScriptContext;
-
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.OptionGroup;
-import org.apache.commons.cli.Options;
-
-public class ScriptCommand extends Command {
-  
-  // Command to allow user to run scripts, see JSR-223
-  // http://www.oracle.com/technetwork/articles/javase/scripting-140262.html
-  
-  protected Option list, engine, script, file, args, out, function, object;
-  private static final String DEFAULT_ENGINE = "rhino";
-  
-  public int execute(String fullCommand, CommandLine cl, Shell shellState) throws Exception {
-
-    boolean invoke = false;
-    ScriptEngineManager mgr = new ScriptEngineManager();
-    
-    if (cl.hasOption(list.getOpt())) {
-      listJSREngineInfo(mgr, shellState);
-    } else if (cl.hasOption(file.getOpt()) || cl.hasOption(script.getOpt())) {
-      String engineName = DEFAULT_ENGINE;
-      if (cl.hasOption(engine.getOpt())) {
-        engineName = cl.getOptionValue(engine.getOpt());
-      }
-      ScriptEngine engine = mgr.getEngineByName(engineName);
-      if (null == engine) {
-        shellState.printException(new Exception(engineName + " not found"));
-        return 1;
-      }
-      
-      if (cl.hasOption(object.getOpt()) || cl.hasOption(function.getOpt())) {
-        if (!(engine instanceof Invocable)) {
-          shellState.printException(new Exception(engineName + " does not support invoking functions or methods"));
-          return 1;
-        }
-        invoke = true;
-      }
-      
-      ScriptContext ctx = new SimpleScriptContext();
-      
-      // Put the following objects into the context so that they
-      // are available to the scripts
-      // TODO: What else should go in here?
-      Bindings b = engine.getBindings(ScriptContext.ENGINE_SCOPE);
-      b.put("connection", shellState.getConnector());
-      
-      List<Object> argValues = new ArrayList<Object>();
-      if (cl.hasOption(args.getOpt())) {
-        String[] argList = cl.getOptionValue(args.getOpt()).split(",");
-        for (String arg : argList) {
-          String[] parts = arg.split("=");
-          if (parts.length == 0) {
-            continue;
-          } else if (parts.length == 1) {
-            b.put(parts[0], null);
-            argValues.add(null);
-          } else if (parts.length == 2) {
-            b.put(parts[0], parts[1]);
-            argValues.add(parts[1]);
-          }
-        }
-      }
-      ctx.setBindings(b, ScriptContext.ENGINE_SCOPE);
-      Object[] argArray = argValues.toArray(new Object[argValues.size()]);
-      
-      Writer writer = null;
-      if (cl.hasOption(out.getOpt())) {
-        File f = new File(cl.getOptionValue(out.getOpt()));
-        writer = new FileWriter(f);
-        ctx.setWriter(writer);
-      }
-      
-      if (cl.hasOption(file.getOpt())) {
-        File f = new File(cl.getOptionValue(file.getOpt()));
-        if (!f.exists()) {
-          if (null != writer) {
-            writer.close();
-          }
-          shellState.printException(new Exception(f.getAbsolutePath() + " not found"));
-          return 1;
-        }
-        Reader reader = new FileReader(f);
-        try {
-          engine.eval(reader, ctx);
-          if (invoke) {
-            this.invokeFunctionOrMethod(shellState, engine, cl, argArray);
-          }
-        } catch (ScriptException ex) {
-          shellState.printException(ex);
-          return 1;
-        } finally {
-          reader.close();
-          if (null != writer) {
-            writer.close();
-          }
-        }
-      } else if (cl.hasOption(script.getOpt())) {
-        String inlineScript = cl.getOptionValue(script.getOpt());
-        try {
-          if (engine instanceof Compilable) {
-            Compilable compiledEng = (Compilable) engine;
-            CompiledScript script = compiledEng.compile(inlineScript);
-            script.eval(ctx);
-            if (invoke) {
-              this.invokeFunctionOrMethod(shellState, engine, cl, argArray);
-            }
-          } else {
-            engine.eval(inlineScript, ctx);
-            if (invoke) {
-              this.invokeFunctionOrMethod(shellState, engine, cl, argArray);
-            }
-          }
-        } catch (ScriptException ex) {
-          shellState.printException(ex);
-          return 1;
-        } finally {
-          if (null != writer) {
-            writer.close();
-          }
-        }
-      }
-      if (null != writer) {
-        writer.close();
-      }
-      
-    } else {
-      printHelp(shellState);
-    }
-    return 0;
-  }
-  
-  public String description() {
-    return "execute JSR-223 scripts";
-  }
-  
-  public int numArgs() {
-    return 0;
-  }
-  
-  @Override
-  public String getName() {
-    return "script";
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-    
-    engine = new Option("e", "engine", false, "engine name, defaults to JDK default (Rhino)");
-    engine.setArgName("engineName");
-    engine.setArgs(1);
-    engine.setRequired(false);
-    o.addOption(engine);
-    
-    OptionGroup inputGroup = new OptionGroup();
-    list = new Option("l", "list", false, "list available script engines");
-    inputGroup.addOption(list);
-
-    script = new Option("s", "script", true, "use inline script");
-    script.setArgName("script text");
-    script.setArgs(1);
-    script.setRequired(false);
-    inputGroup.addOption(script);
-    
-    file = new Option("f", "file", true, "use script file");
-    file.setArgName("fileName");
-    file.setArgs(1);
-    file.setRequired(false);
-    
-    inputGroup.addOption(file);
-    inputGroup.setRequired(true);
-    o.addOptionGroup(inputGroup);
-    
-    OptionGroup invokeGroup = new OptionGroup();
-    object = new Option("obj", "object", true, "name of object");
-    object.setArgs(1);
-    object.setArgName("objectName:methodName");
-    object.setRequired(false);
-    invokeGroup.addOption(object);
-    
-    function = new Option("fx", "function", true, "invoke a script function");
-    function.setArgName("functionName");
-    function.setArgs(1);
-    function.setRequired(false);
-    invokeGroup.addOption(function);
-    invokeGroup.setRequired(false);
-    o.addOptionGroup(invokeGroup);
-    
-    args = new Option("a", "args", true, "comma separated list of key=value arguments");
-    args.setArgName("property1=value1,propert2=value2,...");
-    args.setArgs(Option.UNLIMITED_VALUES);
-    args.setRequired(false);
-    o.addOption(args);
-    
-    out = new Option("o", "output", true, "output file");
-    out.setArgName("fileName");
-    out.setArgs(1);
-    out.setRequired(false);
-    o.addOption(out);
-    
-    return o;
-  }
-  
-  private void listJSREngineInfo(ScriptEngineManager mgr, Shell shellState) throws IOException {
-    List<ScriptEngineFactory> factories = mgr.getEngineFactories();
-    Set<String> lines = new TreeSet<String>();
-    for (ScriptEngineFactory factory : factories) {
-      lines.add("ScriptEngineFactory Info");
-      String engName = factory.getEngineName();
-      String engVersion = factory.getEngineVersion();
-      String langName = factory.getLanguageName();
-      String langVersion = factory.getLanguageVersion();
-      lines.add("\tScript Engine: " + engName + " (" + engVersion + ")");
-      List<String> engNames = factory.getNames();
-      for (String name : engNames) {
-        lines.add("\tEngine Alias: " + name);
-      }
-      lines.add("\tLanguage: " + langName + " (" + langVersion + ")");
-    }
-    shellState.printLines(lines.iterator(), true);
-    
-  }
-  
-  private void invokeFunctionOrMethod(Shell shellState, ScriptEngine engine, CommandLine cl, Object[] args) {
-    try {
-      Invocable inv = (Invocable) engine;
-      if (cl.hasOption(function.getOpt())) {
-        inv.invokeFunction(cl.getOptionValue(function.getOpt()), args);
-      } else if (cl.hasOption(object.getOpt())) {
-        String objectMethod = cl.getOptionValue(object.getOpt());
-        String[] parts = objectMethod.split(":");
-        if (!(parts.length == 2)) {
-          shellState.printException(new Exception("Object and Method must be supplied"));
-          return;
-        }
-        String objectName = parts[0];
-        String methodName = parts[1];
-        Object obj = engine.get(objectName);
-        inv.invokeMethod(obj, methodName, args);
-        
-      }
-    } catch (Exception e) {
-      shellState.printException(e);
-    }
-  }
-  
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SetAuthsCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SetAuthsCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SetAuthsCommand.java
deleted file mode 100644
index 256720c..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SetAuthsCommand.java
+++ /dev/null
@@ -1,77 +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.accumulo.core.util.shell.commands;
-
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.accumulo.core.util.shell.Token;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.OptionGroup;
-import org.apache.commons.cli.Options;
-
-public class SetAuthsCommand extends Command {
-  private Option userOpt;
-  private Option scanOptAuths;
-  private Option clearOptAuths;
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException {
-    final String user = cl.getOptionValue(userOpt.getOpt(), shellState.getConnector().whoami());
-    final String scanOpts = cl.hasOption(clearOptAuths.getOpt()) ? null : cl.getOptionValue(scanOptAuths.getOpt());
-    shellState.getConnector().securityOperations().changeUserAuthorizations(user, ScanCommand.parseAuthorizations(scanOpts));
-    Shell.log.debug("Changed record-level authorizations for user " + user);
-    return 0;
-  }
-  
-  @Override
-  public String description() {
-    return "sets the maximum scan authorizations for a user";
-  }
-  
-  @Override
-  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> completionSet) {
-    registerCompletionForUsers(root, completionSet);
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-    final OptionGroup setOrClear = new OptionGroup();
-    scanOptAuths = new Option("s", "scan-authorizations", true, "scan authorizations to set");
-    scanOptAuths.setArgName("comma-separated-authorizations");
-    setOrClear.addOption(scanOptAuths);
-    clearOptAuths = new Option("c", "clear-authorizations", false, "clear the scan authorizations");
-    setOrClear.addOption(clearOptAuths);
-    setOrClear.setRequired(true);
-    o.addOptionGroup(setOrClear);
-    userOpt = new Option(Shell.userOption, "user", true, "user to operate on");
-    userOpt.setArgName("user");
-    o.addOption(userOpt);
-    return o;
-  }
-  
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SetGroupsCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SetGroupsCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SetGroupsCommand.java
deleted file mode 100644
index 157dbd2..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SetGroupsCommand.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.accumulo.core.util.shell.commands;
-
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Set;
-
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Options;
-import org.apache.hadoop.io.Text;
-
-public class SetGroupsCommand extends Command {
-  @Override
-  public String description() {
-    return "sets the locality groups for a given table (for binary or commas, use Java API)";
-  }
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    final String tableName = OptUtil.getTableOpt(cl, shellState);
-    
-    final HashMap<String,Set<Text>> groups = new HashMap<String,Set<Text>>();
-    
-    for (String arg : cl.getArgs()) {
-      final String sa[] = arg.split("=", 2);
-      if (sa.length < 2) {
-        throw new IllegalArgumentException("Missing '='");
-      }
-      final String group = sa[0];
-      final HashSet<Text> colFams = new HashSet<Text>();
-      
-      for (String family : sa[1].split(",")) {
-        colFams.add(new Text(family.getBytes(Shell.CHARSET)));
-      }
-      
-      groups.put(group, colFams);
-    }
-    
-    shellState.getConnector().tableOperations().setLocalityGroups(tableName, groups);
-    
-    return 0;
-  }
-  
-  @Override
-  public int numArgs() {
-    return Shell.NO_FIXED_ARG_LENGTH_CHECK;
-  }
-  
-  @Override
-  public String usage() {
-    return getName() + " <group>=<col fam>{,<col fam>}{ <group>=<col fam>{,<col fam>}}";
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options opts = new Options();
-    opts.addOption(OptUtil.tableOpt("table to fetch locality groups for"));
-    return opts;
-  }
-  
-}


[20/53] [abbrv] Revert "ACCUMULO-1897 Move shell into new package and module"

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/test/src/test/java/org/apache/accumulo/test/ShellServerIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/accumulo/test/ShellServerIT.java b/test/src/test/java/org/apache/accumulo/test/ShellServerIT.java
index bff8c3a..b3d44e3 100644
--- a/test/src/test/java/org/apache/accumulo/test/ShellServerIT.java
+++ b/test/src/test/java/org/apache/accumulo/test/ShellServerIT.java
@@ -56,7 +56,7 @@ import org.apache.accumulo.core.metadata.MetadataTable;
 import org.apache.accumulo.core.metadata.RootTable;
 import org.apache.accumulo.core.security.Authorizations;
 import org.apache.accumulo.core.util.UtilWaitThread;
-import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.core.util.shell.Shell;
 import org.apache.accumulo.test.functional.FunctionalTestUtils;
 import org.apache.accumulo.test.functional.SimpleMacIT;
 import org.apache.accumulo.test.functional.SlowIterator;


[39/53] [abbrv] ACCUMULO-1879 Move shell into new package and module

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/Shell.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/Shell.java b/shell/src/main/java/org/apache/accumulo/shell/Shell.java
new file mode 100644
index 0000000..48d8bd0
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/Shell.java
@@ -0,0 +1,1168 @@
+/*
+ * 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.accumulo.shell;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.net.InetAddress;
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.UUID;
+
+import jline.console.ConsoleReader;
+import jline.console.UserInterruptException;
+import jline.console.history.FileHistory;
+
+import org.apache.accumulo.core.Constants;
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.ClientConfiguration;
+import org.apache.accumulo.core.client.ClientConfiguration.ClientProperty;
+import org.apache.accumulo.core.client.Connector;
+import org.apache.accumulo.core.client.Instance;
+import org.apache.accumulo.core.client.IteratorSetting;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.core.client.ZooKeeperInstance;
+import org.apache.accumulo.core.client.impl.ServerConfigurationUtil;
+import org.apache.accumulo.core.client.impl.Tables;
+import org.apache.accumulo.core.client.mock.MockInstance;
+import org.apache.accumulo.core.client.security.tokens.AuthenticationToken;
+import org.apache.accumulo.core.client.security.tokens.PasswordToken;
+import org.apache.accumulo.core.conf.AccumuloConfiguration;
+import org.apache.accumulo.core.conf.DefaultConfiguration;
+import org.apache.accumulo.core.conf.Property;
+import org.apache.accumulo.core.conf.SiteConfiguration;
+import org.apache.accumulo.core.data.Key;
+import org.apache.accumulo.core.data.Value;
+import org.apache.accumulo.core.data.thrift.TConstraintViolationSummary;
+import org.apache.accumulo.core.tabletserver.thrift.ConstraintViolationException;
+import org.apache.accumulo.core.trace.DistributedTrace;
+import org.apache.accumulo.core.util.BadArgumentException;
+import org.apache.accumulo.core.util.format.BinaryFormatter;
+import org.apache.accumulo.core.util.format.DefaultFormatter;
+import org.apache.accumulo.core.util.format.Formatter;
+import org.apache.accumulo.core.util.format.FormatterFactory;
+import org.apache.accumulo.core.volume.VolumeConfiguration;
+import org.apache.accumulo.core.zookeeper.ZooUtil;
+import org.apache.accumulo.fate.zookeeper.ZooReader;
+import org.apache.accumulo.shell.commands.AboutCommand;
+import org.apache.accumulo.shell.commands.AddAuthsCommand;
+import org.apache.accumulo.shell.commands.AddSplitsCommand;
+import org.apache.accumulo.shell.commands.AuthenticateCommand;
+import org.apache.accumulo.shell.commands.ByeCommand;
+import org.apache.accumulo.shell.commands.ClasspathCommand;
+import org.apache.accumulo.shell.commands.ClearCommand;
+import org.apache.accumulo.shell.commands.CloneTableCommand;
+import org.apache.accumulo.shell.commands.ClsCommand;
+import org.apache.accumulo.shell.commands.CompactCommand;
+import org.apache.accumulo.shell.commands.ConfigCommand;
+import org.apache.accumulo.shell.commands.ConstraintCommand;
+import org.apache.accumulo.shell.commands.CreateNamespaceCommand;
+import org.apache.accumulo.shell.commands.CreateTableCommand;
+import org.apache.accumulo.shell.commands.CreateUserCommand;
+import org.apache.accumulo.shell.commands.DUCommand;
+import org.apache.accumulo.shell.commands.DebugCommand;
+import org.apache.accumulo.shell.commands.DeleteCommand;
+import org.apache.accumulo.shell.commands.DeleteIterCommand;
+import org.apache.accumulo.shell.commands.DeleteManyCommand;
+import org.apache.accumulo.shell.commands.DeleteNamespaceCommand;
+import org.apache.accumulo.shell.commands.DeleteRowsCommand;
+import org.apache.accumulo.shell.commands.DeleteScanIterCommand;
+import org.apache.accumulo.shell.commands.DeleteShellIterCommand;
+import org.apache.accumulo.shell.commands.DeleteTableCommand;
+import org.apache.accumulo.shell.commands.DeleteUserCommand;
+import org.apache.accumulo.shell.commands.DropTableCommand;
+import org.apache.accumulo.shell.commands.DropUserCommand;
+import org.apache.accumulo.shell.commands.EGrepCommand;
+import org.apache.accumulo.shell.commands.ExecfileCommand;
+import org.apache.accumulo.shell.commands.ExitCommand;
+import org.apache.accumulo.shell.commands.ExportTableCommand;
+import org.apache.accumulo.shell.commands.ExtensionCommand;
+import org.apache.accumulo.shell.commands.FateCommand;
+import org.apache.accumulo.shell.commands.FlushCommand;
+import org.apache.accumulo.shell.commands.FormatterCommand;
+import org.apache.accumulo.shell.commands.GetAuthsCommand;
+import org.apache.accumulo.shell.commands.GetGroupsCommand;
+import org.apache.accumulo.shell.commands.GetSplitsCommand;
+import org.apache.accumulo.shell.commands.GrantCommand;
+import org.apache.accumulo.shell.commands.GrepCommand;
+import org.apache.accumulo.shell.commands.HelpCommand;
+import org.apache.accumulo.shell.commands.HiddenCommand;
+import org.apache.accumulo.shell.commands.HistoryCommand;
+import org.apache.accumulo.shell.commands.ImportDirectoryCommand;
+import org.apache.accumulo.shell.commands.ImportTableCommand;
+import org.apache.accumulo.shell.commands.InfoCommand;
+import org.apache.accumulo.shell.commands.InsertCommand;
+import org.apache.accumulo.shell.commands.InterpreterCommand;
+import org.apache.accumulo.shell.commands.ListCompactionsCommand;
+import org.apache.accumulo.shell.commands.ListIterCommand;
+import org.apache.accumulo.shell.commands.ListScansCommand;
+import org.apache.accumulo.shell.commands.ListShellIterCommand;
+import org.apache.accumulo.shell.commands.MaxRowCommand;
+import org.apache.accumulo.shell.commands.MergeCommand;
+import org.apache.accumulo.shell.commands.NamespacePermissionsCommand;
+import org.apache.accumulo.shell.commands.NamespacesCommand;
+import org.apache.accumulo.shell.commands.NoTableCommand;
+import org.apache.accumulo.shell.commands.OfflineCommand;
+import org.apache.accumulo.shell.commands.OnlineCommand;
+import org.apache.accumulo.shell.commands.PasswdCommand;
+import org.apache.accumulo.shell.commands.PingCommand;
+import org.apache.accumulo.shell.commands.QuestionCommand;
+import org.apache.accumulo.shell.commands.QuitCommand;
+import org.apache.accumulo.shell.commands.QuotedStringTokenizer;
+import org.apache.accumulo.shell.commands.RenameNamespaceCommand;
+import org.apache.accumulo.shell.commands.RenameTableCommand;
+import org.apache.accumulo.shell.commands.RevokeCommand;
+import org.apache.accumulo.shell.commands.ScanCommand;
+import org.apache.accumulo.shell.commands.ScriptCommand;
+import org.apache.accumulo.shell.commands.SetAuthsCommand;
+import org.apache.accumulo.shell.commands.SetGroupsCommand;
+import org.apache.accumulo.shell.commands.SetIterCommand;
+import org.apache.accumulo.shell.commands.SetScanIterCommand;
+import org.apache.accumulo.shell.commands.SetShellIterCommand;
+import org.apache.accumulo.shell.commands.SleepCommand;
+import org.apache.accumulo.shell.commands.SystemPermissionsCommand;
+import org.apache.accumulo.shell.commands.TableCommand;
+import org.apache.accumulo.shell.commands.TablePermissionsCommand;
+import org.apache.accumulo.shell.commands.TablesCommand;
+import org.apache.accumulo.shell.commands.TraceCommand;
+import org.apache.accumulo.shell.commands.UserCommand;
+import org.apache.accumulo.shell.commands.UserPermissionsCommand;
+import org.apache.accumulo.shell.commands.UsersCommand;
+import org.apache.accumulo.shell.commands.WhoAmICommand;
+import org.apache.commons.cli.BasicParser;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.HelpFormatter;
+import org.apache.commons.cli.MissingOptionException;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+import org.apache.commons.cli.ParseException;
+import org.apache.hadoop.fs.Path;
+import org.apache.log4j.Level;
+import org.apache.log4j.Logger;
+
+import com.beust.jcommander.JCommander;
+import com.beust.jcommander.ParameterException;
+
+/**
+ * A convenient console interface to perform basic accumulo functions Includes auto-complete, help, and quoted strings with escape sequences
+ */
+public class Shell extends ShellOptions {
+  public static final Logger log = Logger.getLogger(Shell.class);
+  private static final Logger audit = Logger.getLogger(Shell.class.getName() + ".audit");
+
+  public static final String CHARSET = "ISO-8859-1";
+  public static final int NO_FIXED_ARG_LENGTH_CHECK = -1;
+  public static final String COMMENT_PREFIX = "#";
+  public static final String HISTORY_DIR_NAME = ".accumulo";
+  public static final String HISTORY_FILE_NAME = "shell_history.txt";
+  private static final String SHELL_DESCRIPTION = "Shell - Apache Accumulo Interactive Shell";
+
+  protected int exitCode = 0;
+  private String tableName;
+  protected Instance instance;
+  private Connector connector;
+  protected ConsoleReader reader;
+  private String principal;
+  private AuthenticationToken token;
+  private final Class<? extends Formatter> defaultFormatterClass = DefaultFormatter.class;
+  private final Class<? extends Formatter> binaryFormatterClass = BinaryFormatter.class;
+  public Map<String,List<IteratorSetting>> scanIteratorOptions = new HashMap<String,List<IteratorSetting>>();
+  public Map<String,List<IteratorSetting>> iteratorProfiles = new HashMap<String,List<IteratorSetting>>();
+
+  private Token rootToken;
+  public final Map<String,Command> commandFactory = new TreeMap<String,Command>();
+  public final Map<String,Command[]> commandGrouping = new TreeMap<String,Command[]>();
+  protected boolean configError = false;
+
+  // exit if true
+  private boolean exit = false;
+
+  // file to execute commands from
+  protected File execFile = null;
+  // single command to execute from the command line
+  protected String execCommand = null;
+  protected boolean verbose = true;
+
+  private boolean tabCompletion;
+  private boolean disableAuthTimeout;
+  private long authTimeout;
+  private long lastUserActivity = System.currentTimeMillis();
+  private boolean logErrorsToConsole = false;
+  private PrintWriter writer = null;
+  private boolean masking = false;
+
+  public Shell() throws IOException {
+    this(new ConsoleReader(), new PrintWriter(
+        new OutputStreamWriter(System.out,
+        System.getProperty("jline.WindowsTerminal.output.encoding", System.getProperty("file.encoding")))));
+  }
+
+  public Shell(ConsoleReader reader, PrintWriter writer) {
+    super();
+    this.reader = reader;
+    this.writer = writer;
+  }
+
+  // Not for client use
+  public boolean config(String... args) {
+    ShellOptionsJC options = new ShellOptionsJC();
+    JCommander jc = new JCommander();
+
+    jc.setProgramName("accumulo shell");
+    jc.addObject(options);
+    try {
+      jc.parse(args);
+    } catch (ParameterException e) {
+      configError = true;
+    }
+
+    if (options.isHelpEnabled()) {
+      configError = true;
+    }
+
+    if (!configError && options.getUnrecognizedOptions() != null) {
+      configError = true;
+      logError("Unrecognized Options: " + options.getUnrecognizedOptions().toString());
+    }
+
+    if (configError) {
+      jc.usage();
+      return true;
+    }
+
+    setDebugging(options.isDebugEnabled());
+    authTimeout = options.getAuthTimeout() * 60 * 1000; // convert minutes to milliseconds
+    disableAuthTimeout = options.isAuthTimeoutDisabled();
+
+    // get the options that were parsed
+    String user = options.getUsername();
+    String password = options.getPassword();
+
+    tabCompletion = !options.isTabCompletionDisabled();
+
+    // Use a fake (Mock), ZK, or HdfsZK Accumulo instance
+    setInstance(options);
+
+    // AuthenticationToken options
+    token = options.getAuthenticationToken();
+    Map<String,String> loginOptions = options.getTokenProperties();
+
+    // process default parameters if unspecified
+    try {
+      boolean hasToken = (token != null);
+      boolean hasTokenOptions = !loginOptions.isEmpty();
+
+      if (hasToken && password != null) {
+        throw new ParameterException("Can not supply '--pass' option with '--tokenClass' option");
+      }
+
+      Runtime.getRuntime().addShutdownHook(new Thread() {
+        @Override
+        public void run() {
+          reader.getTerminal().setEchoEnabled(true);
+        }
+      });
+
+      // Need either both a token and options, or neither, but not just one.
+      if (hasToken != hasTokenOptions) {
+        throw new ParameterException("Must supply either both or neither of '--tokenClass' and '--tokenProperty'");
+      } else if (hasToken) { // implied hasTokenOptions
+        // Fully qualified name so we don't shadow java.util.Properties
+        org.apache.accumulo.core.client.security.tokens.AuthenticationToken.Properties props;
+        // and line wrap it because the package name is so long
+        props = new org.apache.accumulo.core.client.security.tokens.AuthenticationToken.Properties();
+
+        props.putAllStrings(loginOptions);
+        token.init(props);
+      } else {
+        // Read password if the user explicitly asked for it, or didn't specify anything at all
+        if ("stdin".equals(password) || password == null) {
+          password = reader.readLine("Password: ", '*');
+        }
+
+        if (password == null) {
+          // User cancel, e.g. Ctrl-D pressed
+          throw new ParameterException("No password or token option supplied");
+        } else {
+          this.token = new PasswordToken(password);
+        }
+      }
+
+      if (!options.isFake()) {
+        ZooReader zr = new ZooReader(instance.getZooKeepers(), instance.getZooKeepersSessionTimeOut());
+        DistributedTrace.enable(instance, zr, "shell", InetAddress.getLocalHost().getHostName());
+      }
+
+      this.setTableName("");
+      this.principal = user;
+      connector = instance.getConnector(this.principal, token);
+
+    } catch (Exception e) {
+      printException(e);
+      configError = true;
+    }
+
+    // decide whether to execute commands from a file and quit
+    if (options.getExecFile() != null) {
+      execFile = options.getExecFile();
+      verbose = false;
+    } else if (options.getExecFileVerbose() != null) {
+      execFile = options.getExecFileVerbose();
+      verbose = true;
+    }
+    execCommand = options.getExecCommand();
+    if (execCommand != null) {
+      verbose = false;
+    }
+
+    rootToken = new Token();
+
+    Command[] dataCommands = {new DeleteCommand(), new DeleteManyCommand(), new DeleteRowsCommand(), new EGrepCommand(), new FormatterCommand(),
+        new InterpreterCommand(), new GrepCommand(), new ImportDirectoryCommand(), new InsertCommand(), new MaxRowCommand(), new ScanCommand()};
+    Command[] debuggingCommands = {new ClasspathCommand(), new DebugCommand(), new ListScansCommand(), new ListCompactionsCommand(), new TraceCommand(),
+        new PingCommand()};
+    Command[] execCommands = {new ExecfileCommand(), new HistoryCommand(), new ExtensionCommand(), new ScriptCommand()};
+    Command[] exitCommands = {new ByeCommand(), new ExitCommand(), new QuitCommand()};
+    Command[] helpCommands = {new AboutCommand(), new HelpCommand(), new InfoCommand(), new QuestionCommand()};
+    Command[] iteratorCommands = {new DeleteIterCommand(), new DeleteScanIterCommand(), new ListIterCommand(), new SetIterCommand(), new SetScanIterCommand(),
+        new SetShellIterCommand(), new ListShellIterCommand(), new DeleteShellIterCommand()};
+    Command[] otherCommands = {new HiddenCommand()};
+    Command[] permissionsCommands = {new GrantCommand(), new RevokeCommand(), new SystemPermissionsCommand(), new TablePermissionsCommand(),
+        new UserPermissionsCommand(), new NamespacePermissionsCommand()};
+    Command[] stateCommands = {new AuthenticateCommand(), new ClsCommand(), new ClearCommand(), new FateCommand(), new NoTableCommand(), new SleepCommand(),
+        new TableCommand(), new UserCommand(), new WhoAmICommand()};
+    Command[] tableCommands = {new CloneTableCommand(), new ConfigCommand(), new CreateTableCommand(), new DeleteTableCommand(), new DropTableCommand(),
+        new DUCommand(), new ExportTableCommand(), new ImportTableCommand(), new OfflineCommand(), new OnlineCommand(), new RenameTableCommand(),
+        new TablesCommand(), new NamespacesCommand(), new CreateNamespaceCommand(), new DeleteNamespaceCommand(), new RenameNamespaceCommand()};
+    Command[] tableControlCommands = {new AddSplitsCommand(), new CompactCommand(), new ConstraintCommand(), new FlushCommand(), new GetGroupsCommand(),
+        new GetSplitsCommand(), new MergeCommand(), new SetGroupsCommand()};
+    Command[] userCommands = {new AddAuthsCommand(), new CreateUserCommand(), new DeleteUserCommand(), new DropUserCommand(), new GetAuthsCommand(),
+        new PasswdCommand(), new SetAuthsCommand(), new UsersCommand()};
+    commandGrouping.put("-- Writing, Reading, and Removing Data --", dataCommands);
+    commandGrouping.put("-- Debugging Commands -------------------", debuggingCommands);
+    commandGrouping.put("-- Shell Execution Commands -------------", execCommands);
+    commandGrouping.put("-- Exiting Commands ---------------------", exitCommands);
+    commandGrouping.put("-- Help Commands ------------------------", helpCommands);
+    commandGrouping.put("-- Iterator Configuration ---------------", iteratorCommands);
+    commandGrouping.put("-- Permissions Administration Commands --", permissionsCommands);
+    commandGrouping.put("-- Shell State Commands -----------------", stateCommands);
+    commandGrouping.put("-- Table Administration Commands --------", tableCommands);
+    commandGrouping.put("-- Table Control Commands ---------------", tableControlCommands);
+    commandGrouping.put("-- User Administration Commands ---------", userCommands);
+
+    for (Command[] cmds : commandGrouping.values()) {
+      for (Command cmd : cmds)
+        commandFactory.put(cmd.getName(), cmd);
+    }
+    for (Command cmd : otherCommands) {
+      commandFactory.put(cmd.getName(), cmd);
+    }
+    return configError;
+  }
+
+  /**
+   * Sets the instance used by the shell based on the given options.
+   * 
+   * @param options
+   *          shell options
+   */
+  protected void setInstance(ShellOptionsJC options) {
+    // should only be one set of instance options set
+    instance = null;
+    if (options.isFake()) {
+      instance = new MockInstance("fake");
+    } else {
+      String instanceName, hosts;
+      if (options.isHdfsZooInstance()) {
+        instanceName = hosts = null;
+      } else if (options.getZooKeeperInstance().size() > 0) {
+        List<String> zkOpts = options.getZooKeeperInstance();
+        instanceName = zkOpts.get(0);
+        hosts = zkOpts.get(1);
+      } else {
+        instanceName = options.getZooKeeperInstanceName();
+        hosts = options.getZooKeeperHosts();
+      }
+      try {
+        instance = getZooInstance(instanceName, hosts, options.getClientConfiguration());
+      } catch (Exception e) {
+        throw new IllegalArgumentException("Unable to load client config from " + options.getClientConfigFile(), e);
+      }
+    }
+  }
+
+  /*
+   * Takes instanceName and keepers as separate arguments, rather than just packaged into the clientConfig, so that we can fail over to accumulo-site.xml or
+   * HDFS config if they're unspecified.
+   */
+  private static Instance getZooInstance(String instanceName, String keepers, ClientConfiguration clientConfig) {
+    UUID instanceId = null;
+    if (instanceName == null) {
+      instanceName = clientConfig.get(ClientProperty.INSTANCE_NAME);
+    }
+    if (instanceName == null || keepers == null) {
+      AccumuloConfiguration conf = SiteConfiguration.getInstance(ServerConfigurationUtil.convertClientConfig(DefaultConfiguration.getInstance(), clientConfig));
+      if (instanceName == null) {
+        Path instanceDir = new Path(VolumeConfiguration.getVolumeUris(conf)[0], "instance_id");
+        instanceId = UUID.fromString(ZooUtil.getInstanceIDFromHdfs(instanceDir, conf));
+      }
+      if (keepers == null) {
+        keepers = conf.get(Property.INSTANCE_ZK_HOST);
+      }
+    }
+    if (instanceId != null) {
+      return new ZooKeeperInstance(clientConfig.withInstance(instanceId).withZkHosts(keepers));
+    } else {
+      return new ZooKeeperInstance(clientConfig.withInstance(instanceName).withZkHosts(keepers));
+    }
+  }
+
+  public Connector getConnector() {
+    return connector;
+  }
+
+  public Instance getInstance() {
+    return instance;
+  }
+
+  public static void main(String args[]) throws IOException {
+    Shell shell = new Shell();
+    try {
+      shell.config(args);
+
+      System.exit(shell.start());
+    } finally {
+      shell.shutdown();
+    }
+  }
+
+  public int start() throws IOException {
+    if (configError)
+      return 1;
+
+    String input;
+    if (isVerbose())
+      printInfo();
+
+    String home = System.getProperty("HOME");
+    if (home == null)
+      home = System.getenv("HOME");
+    String configDir = home + "/" + HISTORY_DIR_NAME;
+    String historyPath = configDir + "/" + HISTORY_FILE_NAME;
+    File accumuloDir = new File(configDir);
+    if (!accumuloDir.exists() && !accumuloDir.mkdirs())
+      log.warn("Unable to make directory for history at " + accumuloDir);
+    try {
+      final FileHistory history = new FileHistory(new File(historyPath));
+      reader.setHistory(history);
+      // Add shutdown hook to flush file history, per jline javadocs
+      Runtime.getRuntime().addShutdownHook(new Thread() {
+        @Override
+        public void run() {
+          try {
+            history.flush();
+          } catch (IOException e) {
+            log.warn("Could not flush history to file.");
+          }
+        }
+      });
+    } catch (IOException e) {
+      log.warn("Unable to load history file at " + historyPath);
+    }
+
+    // Turn Ctrl+C into Exception instead of JVM exit
+    reader.setHandleUserInterrupt(true);
+
+    ShellCompletor userCompletor = null;
+
+    if (execFile != null) {
+      java.util.Scanner scanner = new java.util.Scanner(execFile, StandardCharsets.UTF_8.name());
+      try {
+        while (scanner.hasNextLine() && !hasExited()) {
+          execCommand(scanner.nextLine(), true, isVerbose());
+        }
+      } finally {
+        scanner.close();
+      }
+    } else if (execCommand != null) {
+      for (String command : execCommand.split("\n")) {
+        execCommand(command, true, isVerbose());
+      }
+      return exitCode;
+    }
+
+    while (true) {
+      try {
+        if (hasExited())
+          return exitCode;
+
+        // If tab completion is true we need to reset
+        if (tabCompletion) {
+          if (userCompletor != null)
+            reader.removeCompleter(userCompletor);
+
+          userCompletor = setupCompletion();
+          reader.addCompleter(userCompletor);
+        }
+
+        reader.setPrompt(getDefaultPrompt());
+        input = reader.readLine();
+        if (input == null) {
+          reader.println();
+          return exitCode;
+        } // User Canceled (Ctrl+D)
+
+        execCommand(input, disableAuthTimeout, false);
+      } catch (UserInterruptException uie) {
+        // User Cancelled (Ctrl+C)
+        reader.println();
+
+        String partialLine = uie.getPartialLine();
+        if (partialLine == null || "".equals(uie.getPartialLine().trim())) {
+          // No content, actually exit
+          return exitCode;
+        }
+      } finally {
+        reader.flush();
+      }
+    }
+  }
+
+  public void shutdown() {
+    if (reader != null) {
+      reader.shutdown();
+    }
+  }
+
+  public void printInfo() throws IOException {
+    reader.print("\n" + SHELL_DESCRIPTION + "\n" + "- \n" + "- version: " + Constants.VERSION + "\n" + "- instance name: "
+        + connector.getInstance().getInstanceName() + "\n" + "- instance id: " + connector.getInstance().getInstanceID() + "\n" + "- \n"
+        + "- type 'help' for a list of available commands\n" + "- \n");
+    reader.flush();
+  }
+
+  public void printVerboseInfo() throws IOException {
+    StringBuilder sb = new StringBuilder("-\n");
+    sb.append("- Current user: ").append(connector.whoami()).append("\n");
+    if (execFile != null)
+      sb.append("- Executing commands from: ").append(execFile).append("\n");
+    if (disableAuthTimeout)
+      sb.append("- Authorization timeout: disabled\n");
+    else
+      sb.append("- Authorization timeout: ").append(String.format("%.2fs%n", authTimeout / 1000.0));
+    sb.append("- Debug: ").append(isDebuggingEnabled() ? "on" : "off").append("\n");
+    if (!scanIteratorOptions.isEmpty()) {
+      for (Entry<String,List<IteratorSetting>> entry : scanIteratorOptions.entrySet()) {
+        sb.append("- Session scan iterators for table ").append(entry.getKey()).append(":\n");
+        for (IteratorSetting setting : entry.getValue()) {
+          sb.append("-    Iterator ").append(setting.getName()).append(" options:\n");
+          sb.append("-        ").append("iteratorPriority").append(" = ").append(setting.getPriority()).append("\n");
+          sb.append("-        ").append("iteratorClassName").append(" = ").append(setting.getIteratorClass()).append("\n");
+          for (Entry<String,String> optEntry : setting.getOptions().entrySet()) {
+            sb.append("-        ").append(optEntry.getKey()).append(" = ").append(optEntry.getValue()).append("\n");
+          }
+        }
+      }
+    }
+    sb.append("-\n");
+    reader.print(sb.toString());
+  }
+
+  public String getDefaultPrompt() {
+    return connector.whoami() + "@" + connector.getInstance().getInstanceName() + (getTableName().isEmpty() ? "" : " ") + getTableName() + "> ";
+  }
+
+  public void execCommand(String input, boolean ignoreAuthTimeout, boolean echoPrompt) throws IOException {
+    audit.log(Level.INFO, getDefaultPrompt() + input);
+    if (echoPrompt) {
+      reader.print(getDefaultPrompt());
+      reader.println(input);
+    }
+
+    if (input.startsWith(COMMENT_PREFIX)) {
+      return;
+    }
+
+    String fields[];
+    try {
+      fields = new QuotedStringTokenizer(input).getTokens();
+    } catch (BadArgumentException e) {
+      printException(e);
+      ++exitCode;
+      return;
+    }
+    if (fields.length == 0)
+      return;
+
+    String command = fields[0];
+    fields = fields.length > 1 ? Arrays.copyOfRange(fields, 1, fields.length) : new String[] {};
+
+    Command sc = null;
+    if (command.length() > 0) {
+      try {
+        // Obtain the command from the command table
+        sc = commandFactory.get(command);
+        if (sc == null) {
+          reader.println(String.format("Unknown command \"%s\".  Enter \"help\" for a list possible commands.", command));
+          reader.flush();
+          return;
+        }
+
+        if (!(sc instanceof ExitCommand) && !ignoreAuthTimeout && System.currentTimeMillis() - lastUserActivity > authTimeout) {
+          reader.println("Shell has been idle for too long. Please re-authenticate.");
+          boolean authFailed = true;
+          do {
+            String pwd = readMaskedLine("Enter current password for '" + connector.whoami() + "': ", '*');
+            if (pwd == null) {
+              reader.println();
+              return;
+            } // user canceled
+
+            try {
+              authFailed = !connector.securityOperations().authenticateUser(connector.whoami(), new PasswordToken(pwd));
+            } catch (Exception e) {
+              ++exitCode;
+              printException(e);
+            }
+
+            if (authFailed)
+              reader.print("Invalid password. ");
+          } while (authFailed);
+          lastUserActivity = System.currentTimeMillis();
+        }
+
+        // Get the options from the command on how to parse the string
+        Options parseOpts = sc.getOptionsWithHelp();
+
+        // Parse the string using the given options
+        CommandLine cl = new BasicParser().parse(parseOpts, fields);
+
+        int actualArgLen = cl.getArgs().length;
+        int expectedArgLen = sc.numArgs();
+        if (cl.hasOption(helpOption)) {
+          // Display help if asked to; otherwise execute the command
+          sc.printHelp(this);
+        } else if (expectedArgLen != NO_FIXED_ARG_LENGTH_CHECK && actualArgLen != expectedArgLen) {
+          ++exitCode;
+          // Check for valid number of fixed arguments (if not
+          // negative; negative means it is not checked, for
+          // vararg-like commands)
+          printException(new IllegalArgumentException(String.format("Expected %d argument%s. There %s %d.", expectedArgLen, expectedArgLen == 1 ? "" : "s",
+              actualArgLen == 1 ? "was" : "were", actualArgLen)));
+          sc.printHelp(this);
+        } else {
+          int tmpCode = sc.execute(input, cl, this);
+          exitCode += tmpCode;
+          reader.flush();
+        }
+
+      } catch (ConstraintViolationException e) {
+        ++exitCode;
+        printConstraintViolationException(e);
+      } catch (TableNotFoundException e) {
+        ++exitCode;
+        if (getTableName().equals(e.getTableName()))
+          setTableName("");
+        printException(e);
+      } catch (ParseException e) {
+        // not really an error if the exception is a missing required
+        // option when the user is asking for help
+        if (!(e instanceof MissingOptionException && (Arrays.asList(fields).contains("-" + helpOption) || Arrays.asList(fields).contains("--" + helpLongOption)))) {
+          ++exitCode;
+          printException(e);
+        }
+        if (sc != null)
+          sc.printHelp(this);
+      } catch (UserInterruptException e) {
+        ++exitCode;
+      } catch (Exception e) {
+        ++exitCode;
+        printException(e);
+      }
+    } else {
+      ++exitCode;
+      printException(new BadArgumentException("Unrecognized empty command", command, -1));
+    }
+    reader.flush();
+  }
+
+  /**
+   * The command tree is built in reverse so that the references are more easily linked up. There is some code in token to allow forward building of the command
+   * tree.
+   */
+  private ShellCompletor setupCompletion() {
+    rootToken = new Token();
+
+    Set<String> tableNames = null;
+    try {
+      tableNames = connector.tableOperations().list();
+    } catch (Exception e) {
+      log.debug("Unable to obtain list of tables", e);
+      tableNames = Collections.emptySet();
+    }
+
+    Set<String> userlist = null;
+    try {
+      userlist = connector.securityOperations().listLocalUsers();
+    } catch (Exception e) {
+      log.debug("Unable to obtain list of users", e);
+      userlist = Collections.emptySet();
+    }
+
+    Set<String> namespaces = null;
+    try {
+      namespaces = connector.namespaceOperations().list();
+    } catch (Exception e) {
+      log.debug("Unable to obtain list of namespaces", e);
+      namespaces = Collections.emptySet();
+    }
+
+    Map<Command.CompletionSet,Set<String>> options = new HashMap<Command.CompletionSet,Set<String>>();
+
+    Set<String> commands = new HashSet<String>();
+    for (String a : commandFactory.keySet())
+      commands.add(a);
+
+    Set<String> modifiedUserlist = new HashSet<String>();
+    Set<String> modifiedTablenames = new HashSet<String>();
+    Set<String> modifiedNamespaces = new HashSet<String>();
+
+    for (String a : tableNames)
+      modifiedTablenames.add(a.replaceAll("([\\s'\"])", "\\\\$1"));
+    for (String a : userlist)
+      modifiedUserlist.add(a.replaceAll("([\\s'\"])", "\\\\$1"));
+    for (String a : namespaces) {
+      String b = a.replaceAll("([\\s'\"])", "\\\\$1");
+      modifiedNamespaces.add(b.isEmpty() ? "\"\"" : b);
+    }
+
+    options.put(Command.CompletionSet.USERNAMES, modifiedUserlist);
+    options.put(Command.CompletionSet.TABLENAMES, modifiedTablenames);
+    options.put(Command.CompletionSet.NAMESPACES, modifiedNamespaces);
+    options.put(Command.CompletionSet.COMMANDS, commands);
+
+    for (Command[] cmdGroup : commandGrouping.values()) {
+      for (Command c : cmdGroup) {
+        c.getOptionsWithHelp(); // prep the options for the command
+        // so that the completion can
+        // include them
+        c.registerCompletion(rootToken, options);
+      }
+    }
+    return new ShellCompletor(rootToken, options);
+  }
+
+  /**
+   * The Command class represents a command to be run in the shell. It contains the methods to execute along with some methods to help tab completion, and
+   * return the command name, help, and usage.
+   */
+  public static abstract class Command {
+    // Helper methods for completion
+    public enum CompletionSet {
+      TABLENAMES, USERNAMES, COMMANDS, NAMESPACES
+    }
+
+    static Set<String> getCommandNames(Map<CompletionSet,Set<String>> objects) {
+      return objects.get(CompletionSet.COMMANDS);
+    }
+
+    static Set<String> getTableNames(Map<CompletionSet,Set<String>> objects) {
+      return objects.get(CompletionSet.TABLENAMES);
+    }
+
+    static Set<String> getUserNames(Map<CompletionSet,Set<String>> objects) {
+      return objects.get(CompletionSet.USERNAMES);
+    }
+
+    static Set<String> getNamespaces(Map<CompletionSet,Set<String>> objects) {
+      return objects.get(CompletionSet.NAMESPACES);
+    }
+
+    public void registerCompletionGeneral(Token root, Set<String> args, boolean caseSens) {
+      Token t = new Token(args);
+      t.setCaseSensitive(caseSens);
+
+      Token command = new Token(getName());
+      command.addSubcommand(t);
+
+      root.addSubcommand(command);
+    }
+
+    public void registerCompletionForTables(Token root, Map<CompletionSet,Set<String>> completionSet) {
+      registerCompletionGeneral(root, completionSet.get(CompletionSet.TABLENAMES), true);
+    }
+
+    public void registerCompletionForUsers(Token root, Map<CompletionSet,Set<String>> completionSet) {
+      registerCompletionGeneral(root, completionSet.get(CompletionSet.USERNAMES), true);
+    }
+
+    public void registerCompletionForCommands(Token root, Map<CompletionSet,Set<String>> completionSet) {
+      registerCompletionGeneral(root, completionSet.get(CompletionSet.COMMANDS), false);
+    }
+
+    public void registerCompletionForNamespaces(Token root, Map<CompletionSet,Set<String>> completionSet) {
+      registerCompletionGeneral(root, completionSet.get(CompletionSet.NAMESPACES), true);
+    }
+
+    // abstract methods to override
+    public abstract int execute(String fullCommand, CommandLine cl, Shell shellState) throws Exception;
+
+    public abstract String description();
+
+    /**
+     * If the number of arguments is not always zero (not including those arguments handled through Options), make sure to override the {@link #usage()} method.
+     * Otherwise, {@link #usage()} does need to be overridden.
+     */
+    public abstract int numArgs();
+
+    // OPTIONAL methods to override:
+
+    // the general version of getname uses reflection to get the class name
+    // and then cuts off the suffix -Command to get the name of the command
+    public String getName() {
+      String s = this.getClass().getName();
+      int st = Math.max(s.lastIndexOf('$'), s.lastIndexOf('.'));
+      int i = s.indexOf("Command");
+      return i > 0 ? s.substring(st + 1, i).toLowerCase(Locale.ENGLISH) : null;
+    }
+
+    // The general version of this method adds the name
+    // of the command to the completion tree
+    public void registerCompletion(Token root, Map<CompletionSet,Set<String>> completion_set) {
+      root.addSubcommand(new Token(getName()));
+    }
+
+    // The general version of this method uses the HelpFormatter
+    // that comes with the apache Options package to print out the help
+    public final void printHelp(Shell shellState) {
+      shellState.printHelp(usage(), "description: " + this.description(), getOptionsWithHelp());
+    }
+
+    public final void printHelp(Shell shellState, int width) {
+      shellState.printHelp(usage(), "description: " + this.description(), getOptionsWithHelp(), width);
+    }
+
+    // Get options with help
+    public final Options getOptionsWithHelp() {
+      Options opts = getOptions();
+      opts.addOption(new Option(helpOption, helpLongOption, false, "display this help"));
+      return opts;
+    }
+
+    // General usage is just the command
+    public String usage() {
+      return getName();
+    }
+
+    // General Options are empty
+    public Options getOptions() {
+      return new Options();
+    }
+  }
+
+  public interface PrintLine {
+    void print(String s);
+
+    void close();
+  }
+
+  public static class PrintShell implements PrintLine {
+    ConsoleReader reader;
+
+    public PrintShell(ConsoleReader reader) {
+      this.reader = reader;
+    }
+
+    @Override
+    public void print(String s) {
+      try {
+        reader.println(s);
+      } catch (Exception ex) {
+        throw new RuntimeException(ex);
+      }
+    }
+
+    @Override
+    public void close() {}
+  };
+
+  public static class PrintFile implements PrintLine {
+    PrintWriter writer;
+
+    public PrintFile(String filename) throws FileNotFoundException {
+      writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(filename), StandardCharsets.UTF_8)));
+    }
+
+    @Override
+    public void print(String s) {
+      writer.println(s);
+    }
+
+    @Override
+    public void close() {
+      writer.close();
+    }
+  };
+
+  public final void printLines(Iterator<String> lines, boolean paginate) throws IOException {
+    printLines(lines, paginate, null);
+  }
+
+  public final void printLines(Iterator<String> lines, boolean paginate, PrintLine out) throws IOException {
+    int linesPrinted = 0;
+    String prompt = "-- hit any key to continue or 'q' to quit --";
+    int lastPromptLength = prompt.length();
+    int termWidth = reader.getTerminal().getWidth();
+    int maxLines = reader.getTerminal().getHeight();
+
+    String peek = null;
+    while (lines.hasNext()) {
+      String nextLine = lines.next();
+      if (nextLine == null)
+        continue;
+      for (String line : nextLine.split("\\n")) {
+        if (out == null) {
+          if (peek != null) {
+            reader.println(peek);
+            if (paginate) {
+              linesPrinted += peek.length() == 0 ? 0 : Math.ceil(peek.length() * 1.0 / termWidth);
+
+              // check if displaying the next line would result in
+              // scrolling off the screen
+              if (linesPrinted + Math.ceil(lastPromptLength * 1.0 / termWidth) + Math.ceil(prompt.length() * 1.0 / termWidth)
+                  + Math.ceil(line.length() * 1.0 / termWidth) > maxLines) {
+                linesPrinted = 0;
+                int numdashes = (termWidth - prompt.length()) / 2;
+                String nextPrompt = repeat("-", numdashes) + prompt + repeat("-", numdashes);
+                lastPromptLength = nextPrompt.length();
+                reader.print(nextPrompt);
+                reader.flush();
+
+                if (Character.toUpperCase((char) reader.readCharacter()) == 'Q') {
+                  reader.println();
+                  return;
+                }
+                reader.println();
+                termWidth = reader.getTerminal().getWidth();
+                maxLines = reader.getTerminal().getHeight();
+              }
+            }
+          }
+          peek = line;
+        } else {
+          out.print(line);
+        }
+      }
+    }
+    if (out == null && peek != null) {
+      reader.println(peek);
+    }
+  }
+
+  public final void printRecords(Iterable<Entry<Key,Value>> scanner, boolean printTimestamps, boolean paginate, Class<? extends Formatter> formatterClass,
+      PrintLine outFile) throws IOException {
+    printLines(FormatterFactory.getFormatter(formatterClass, scanner, printTimestamps), paginate, outFile);
+  }
+
+  public final void printRecords(Iterable<Entry<Key,Value>> scanner, boolean printTimestamps, boolean paginate, Class<? extends Formatter> formatterClass)
+      throws IOException {
+    printLines(FormatterFactory.getFormatter(formatterClass, scanner, printTimestamps), paginate);
+  }
+
+  public final void printBinaryRecords(Iterable<Entry<Key,Value>> scanner, boolean printTimestamps, boolean paginate, PrintLine outFile) throws IOException {
+    printLines(FormatterFactory.getFormatter(binaryFormatterClass, scanner, printTimestamps), paginate, outFile);
+  }
+
+  public final void printBinaryRecords(Iterable<Entry<Key,Value>> scanner, boolean printTimestamps, boolean paginate) throws IOException {
+    printLines(FormatterFactory.getFormatter(binaryFormatterClass, scanner, printTimestamps), paginate);
+  }
+
+  public static String repeat(String s, int c) {
+    StringBuilder sb = new StringBuilder();
+    for (int i = 0; i < c; i++)
+      sb.append(s);
+    return sb.toString();
+  }
+
+  public void checkTableState() {
+    if (getTableName().isEmpty())
+      throw new IllegalStateException(
+          "Not in a table context. Please use 'table <tableName>' to switch to a table, or use '-t' to specify a table if option is available.");
+  }
+
+  private final void printConstraintViolationException(ConstraintViolationException cve) {
+    printException(cve, "");
+    int COL1 = 50, COL2 = 14;
+    int col3 = Math.max(1, Math.min(Integer.MAX_VALUE, reader.getTerminal().getWidth() - COL1 - COL2 - 6));
+    logError(String.format("%" + COL1 + "s-+-%" + COL2 + "s-+-%" + col3 + "s%n", repeat("-", COL1), repeat("-", COL2), repeat("-", col3)));
+    logError(String.format("%-" + COL1 + "s | %" + COL2 + "s | %-" + col3 + "s%n", "Constraint class", "Violation code", "Violation Description"));
+    logError(String.format("%" + COL1 + "s-+-%" + COL2 + "s-+-%" + col3 + "s%n", repeat("-", COL1), repeat("-", COL2), repeat("-", col3)));
+    for (TConstraintViolationSummary cvs : cve.violationSummaries)
+      logError(String.format("%-" + COL1 + "s | %" + COL2 + "d | %-" + col3 + "s%n", cvs.constrainClass, cvs.violationCode, cvs.violationDescription));
+    logError(String.format("%" + COL1 + "s-+-%" + COL2 + "s-+-%" + col3 + "s%n", repeat("-", COL1), repeat("-", COL2), repeat("-", col3)));
+  }
+
+  public final void printException(Exception e) {
+    printException(e, e.getMessage());
+  }
+
+  private final void printException(Exception e, String msg) {
+    logError(e.getClass().getName() + (msg != null ? ": " + msg : ""));
+    log.debug(e.getClass().getName() + (msg != null ? ": " + msg : ""), e);
+  }
+
+  public static final void setDebugging(boolean debuggingEnabled) {
+    Logger.getLogger(Constants.CORE_PACKAGE_NAME).setLevel(debuggingEnabled ? Level.TRACE : Level.INFO);
+  }
+
+  public static final boolean isDebuggingEnabled() {
+    return Logger.getLogger(Constants.CORE_PACKAGE_NAME).isTraceEnabled();
+  }
+
+  private final void printHelp(String usage, String description, Options opts) {
+    printHelp(usage, description, opts, Integer.MAX_VALUE);
+  }
+
+  private final void printHelp(String usage, String description, Options opts, int width) {
+    // TODO Use the OutputStream from the JLine ConsoleReader if we can ever get access to it
+    new HelpFormatter().printHelp(writer, width, usage, description, opts, 2, 5, null, true);
+    writer.flush();
+  }
+
+  public int getExitCode() {
+    return exitCode;
+  }
+
+  public void resetExitCode() {
+    exitCode = 0;
+  }
+
+  public void setExit(boolean exit) {
+    this.exit = exit;
+  }
+
+  public boolean getExit() {
+    return this.exit;
+  }
+
+  public boolean isVerbose() {
+    return verbose;
+  }
+
+  public void setTableName(String tableName) {
+    this.tableName = (tableName == null || tableName.isEmpty()) ? "" : Tables.qualified(tableName);
+  }
+
+  public String getTableName() {
+    return tableName;
+  }
+
+  public ConsoleReader getReader() {
+    return reader;
+  }
+
+  public void updateUser(String principal, AuthenticationToken token) throws AccumuloException, AccumuloSecurityException {
+    connector = instance.getConnector(principal, token);
+    this.principal = principal;
+    this.token = token;
+  }
+
+  public String getPrincipal() {
+    return principal;
+  }
+
+  public AuthenticationToken getToken() {
+    return token;
+  }
+
+  /**
+   * Return the formatter for the current table.
+   * 
+   * @return the formatter class for the current table
+   */
+  public Class<? extends Formatter> getFormatter() {
+    return getFormatter(this.tableName);
+  }
+
+  /**
+   * Return the formatter for the given table.
+   * 
+   * @param tableName
+   *          the table name
+   * @return the formatter class for the given table
+   */
+  public Class<? extends Formatter> getFormatter(String tableName) {
+    Class<? extends Formatter> formatter = FormatterCommand.getCurrentFormatter(tableName, this);
+
+    if (null == formatter) {
+      logError("Could not load the specified formatter. Using the DefaultFormatter");
+      return this.defaultFormatterClass;
+    } else {
+      return formatter;
+    }
+  }
+
+  public void setLogErrorsToConsole() {
+    this.logErrorsToConsole = true;
+  }
+
+  private void logError(String s) {
+    log.error(s);
+    if (logErrorsToConsole) {
+      try {
+        reader.println("ERROR: " + s);
+        reader.flush();
+      } catch (IOException e) {}
+    }
+  }
+
+  public String readMaskedLine(String prompt, Character mask) throws IOException {
+    this.masking = true;
+    String s = reader.readLine(prompt, mask);
+    this.masking = false;
+    return s;
+  }
+
+  public boolean isMasking() {
+    return masking;
+  }
+
+  public boolean hasExited() {
+    return exit;
+  }
+
+  public boolean isTabCompletion() {
+    return tabCompletion;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/ShellCommandException.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/ShellCommandException.java b/shell/src/main/java/org/apache/accumulo/shell/ShellCommandException.java
new file mode 100644
index 0000000..b25e9da
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/ShellCommandException.java
@@ -0,0 +1,59 @@
+/*
+ * 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.accumulo.shell;
+
+public class ShellCommandException extends Exception {
+  private static final long serialVersionUID = 1L;
+  
+  public enum ErrorCode {
+    UNKNOWN_ERROR("Unknown error"),
+    UNSUPPORTED_LANGUAGE("Programming language used is not supported"),
+    UNRECOGNIZED_COMMAND("Command is not supported"),
+    INITIALIZATION_FAILURE("Command could not be initialized"),
+    XML_PARSING_ERROR("Failed to parse the XML file");
+    
+    private String description;
+    
+    private ErrorCode(String description) {
+      this.description = description;
+    }
+    
+    public String getDescription() {
+      return this.description;
+    }
+    
+    public String toString() {
+      return getDescription();
+    }
+  }
+  
+  private ErrorCode code;
+  private String command;
+  
+  public ShellCommandException(ErrorCode code) {
+    this(code, null);
+  }
+  
+  public ShellCommandException(ErrorCode code, String command) {
+    this.code = code;
+    this.command = command;
+  }
+  
+  public String getMessage() {
+    return code + (command != null ? " (" + command + ")" : "");
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/ShellCompletor.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/ShellCompletor.java b/shell/src/main/java/org/apache/accumulo/shell/ShellCompletor.java
new file mode 100644
index 0000000..3ed6a04
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/ShellCompletor.java
@@ -0,0 +1,162 @@
+/*
+ * 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.accumulo.shell;
+
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import jline.console.completer.Completer;
+
+import org.apache.accumulo.shell.Shell.Command.CompletionSet;
+import org.apache.accumulo.shell.commands.QuotedStringTokenizer;
+
+public class ShellCompletor implements Completer {
+
+  // private static final Logger log = Logger.getLogger(ShellCompletor.class);
+
+  Map<CompletionSet,Set<String>> options;
+  Token root = null;
+
+  public ShellCompletor() {}
+
+  public ShellCompletor(Token root) {
+    this.root = root;
+  }
+
+  public ShellCompletor(Token rootToken, Map<CompletionSet,Set<String>> options) {
+    this.root = rootToken;
+    this.options = options;
+  }
+
+  @Override
+  @SuppressWarnings({"unchecked", "rawtypes"})
+  public int complete(String buffer, int cursor, List candidates) {
+    try {
+      return _complete(buffer, cursor, candidates);
+    } catch (Exception e) {
+      candidates.add("");
+      candidates.add(e.getMessage());
+      return cursor;
+    }
+  }
+
+  private int _complete(String fullBuffer, int cursor, List<String> candidates) {
+    boolean inTableFlag = false, inUserFlag = false, inNamespaceFlag = false;
+    // Only want to grab the buffer up to the cursor because
+    // the user could be trying to tab complete in the middle
+    // of the line
+    String buffer = fullBuffer.substring(0, cursor);
+
+    Token current_command_token = root;
+    String current_string_token = null;
+    boolean end_space = buffer.endsWith(" ");
+
+    // tabbing with no text
+    if (buffer.length() == 0) {
+      candidates.addAll(root.getSubcommandNames());
+      return 0;
+    }
+
+    String prefix = "";
+
+    QuotedStringTokenizer qst = new QuotedStringTokenizer(buffer);
+
+    Iterator<String> iter = qst.iterator();
+    while (iter.hasNext()) {
+      current_string_token = iter.next();
+      current_string_token = current_string_token.replaceAll("([\\s'\"])", "\\\\$1");
+
+      if (!iter.hasNext()) {
+        // if we end in a space and that space isn't part of the last token
+        // (which would be the case at the start of a quote) OR the buffer
+        // ends with a " indicating that we need to start on the next command
+        // and not complete the current command.
+        if (end_space && !current_string_token.endsWith(" ") || buffer.endsWith("\"")) {
+          // match subcommands
+
+          // we're in a subcommand so try to match the universal
+          // option flags if we're there
+          if (current_string_token.trim().equals("-" + Shell.tableOption)) {
+            candidates.addAll(options.get(Shell.Command.CompletionSet.TABLENAMES));
+            prefix += "-" + Shell.tableOption + " ";
+          } else if (current_string_token.trim().equals("-" + Shell.userOption)) {
+            candidates.addAll(options.get(Shell.Command.CompletionSet.USERNAMES));
+            prefix += "-" + Shell.userOption + " ";
+          } else if (current_string_token.trim().equals("-" + Shell.namespaceOption)) {
+            candidates.addAll(options.get(Shell.Command.CompletionSet.NAMESPACES));
+            prefix += "-" + Shell.namespaceOption + " ";
+          } else if (current_command_token != null) {
+            Token next = current_command_token.getSubcommand(current_string_token);
+            if (next != null) {
+              current_command_token = next;
+
+              if (current_command_token.getCaseSensitive())
+                prefix += current_string_token + " ";
+              else
+                prefix += current_string_token.toUpperCase() + " ";
+
+              candidates.addAll(current_command_token.getSubcommandNames());
+            }
+          }
+          Collections.sort(candidates);
+          return (prefix.length());
+        }
+        // need to match current command
+        // if we're in -t <table>, -u <user>, or -tn <namespace> complete those
+        if (inTableFlag) {
+          for (String a : options.get(Shell.Command.CompletionSet.TABLENAMES))
+            if (a.startsWith(current_string_token))
+              candidates.add(a);
+        } else if (inUserFlag) {
+          for (String a : options.get(Shell.Command.CompletionSet.USERNAMES))
+            if (a.startsWith(current_string_token))
+              candidates.add(a);
+        } else if (inNamespaceFlag) {
+          for (String a : options.get(Shell.Command.CompletionSet.NAMESPACES))
+            if (a.startsWith(current_string_token))
+              candidates.add(a);
+        } else if (current_command_token != null)
+          candidates.addAll(current_command_token.getSubcommandNames(current_string_token));
+
+        Collections.sort(candidates);
+        return (prefix.length());
+      }
+
+      if (current_string_token.trim().equals("-" + Shell.tableOption))
+        inTableFlag = true;
+      else if (current_string_token.trim().equals("-" + Shell.userOption))
+        inUserFlag = true;
+      else if (current_string_token.trim().equals("-" + Shell.namespaceOption))
+        inNamespaceFlag = true;
+      else
+        inUserFlag = inTableFlag = inNamespaceFlag = false;
+
+      if (current_command_token != null && current_command_token.getCaseSensitive())
+        prefix += current_string_token + " ";
+      else
+        prefix += current_string_token.toUpperCase() + " ";
+
+      if (current_command_token != null && current_command_token.getSubcommandNames().contains(current_string_token))
+        current_command_token = current_command_token.getSubcommand(current_string_token);
+
+    }
+    return 0;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/ShellExtension.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/ShellExtension.java b/shell/src/main/java/org/apache/accumulo/shell/ShellExtension.java
new file mode 100644
index 0000000..d29d276
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/ShellExtension.java
@@ -0,0 +1,27 @@
+/*
+ * 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.accumulo.shell;
+
+import org.apache.accumulo.shell.Shell.Command;
+
+public abstract class ShellExtension {
+    
+    public abstract String getExtensionName();
+
+    public abstract Command[] getCommands();
+    
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/ShellOptions.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/ShellOptions.java b/shell/src/main/java/org/apache/accumulo/shell/ShellOptions.java
new file mode 100644
index 0000000..302a8a9
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/ShellOptions.java
@@ -0,0 +1,33 @@
+/*
+ * 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.accumulo.shell;
+
+import org.apache.commons.cli.Option;
+
+/**
+ * Abstract class to encompass the Options available on the Accumulo Shell
+ */
+public abstract class ShellOptions {
+  // Global options flags
+  public static final String userOption = "u";
+  public static final String tableOption = "t";
+  public static final String namespaceOption = "ns";
+  public static final String helpOption = "?";
+  public static final String helpLongOption = "help";
+
+  final Option helpOpt = new Option(helpOption, helpLongOption, false, "display this help");
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/ShellOptionsJC.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/ShellOptionsJC.java b/shell/src/main/java/org/apache/accumulo/shell/ShellOptionsJC.java
new file mode 100644
index 0000000..35cef9f
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/ShellOptionsJC.java
@@ -0,0 +1,280 @@
+/*
+ * 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.accumulo.shell;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Scanner;
+import java.util.TreeMap;
+
+import org.apache.accumulo.core.client.ClientConfiguration;
+import org.apache.accumulo.core.client.ClientConfiguration.ClientProperty;
+import org.apache.accumulo.core.client.security.tokens.AuthenticationToken;
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.commons.configuration.PropertiesConfiguration;
+import org.apache.log4j.Logger;
+
+import com.beust.jcommander.DynamicParameter;
+import com.beust.jcommander.IStringConverter;
+import com.beust.jcommander.Parameter;
+import com.beust.jcommander.ParameterException;
+import com.beust.jcommander.converters.FileConverter;
+
+public class ShellOptionsJC {
+  // Use the Shell logger because this is really just an extension.
+  public static final Logger log = Logger.getLogger(Shell.class);
+
+  @Parameter(names = {"-u", "--user"}, description = "username (defaults to your OS user)")
+  private String username = System.getProperty("user.name", "root");
+
+  public static class PasswordConverter implements IStringConverter<String> {
+    public static final String STDIN = "stdin";
+
+    private enum KeyType {
+      PASS("pass:"), ENV("env:") {
+        @Override
+        String process(String value) {
+          return System.getenv(value);
+        }
+      },
+      FILE("file:") {
+        @Override
+        String process(String value) {
+          Scanner scanner = null;
+          try {
+            scanner = new Scanner(new File(value));
+            return scanner.nextLine();
+          } catch (FileNotFoundException e) {
+            throw new ParameterException(e);
+          } finally {
+            if (scanner != null) {
+              scanner.close();
+            }
+          }
+        }
+      },
+      STDIN(PasswordConverter.STDIN) {
+        @Override
+        public boolean matches(String value) {
+          return prefix.equals(value);
+        }
+
+        @Override
+        public String convert(String value) {
+          // Will check for this later
+          return prefix;
+        }
+      };
+
+      String prefix;
+
+      private KeyType(String prefix) {
+        this.prefix = prefix;
+      }
+
+      public boolean matches(String value) {
+        return value.startsWith(prefix);
+      }
+
+      public String convert(String value) {
+        return process(value.substring(prefix.length()));
+      }
+
+      String process(String value) {
+        return value;
+      }
+    };
+
+    @Override
+    public String convert(String value) {
+      for (KeyType keyType : KeyType.values()) {
+        if (keyType.matches(value)) {
+          return keyType.convert(value);
+        }
+      }
+
+      return value;
+    }
+  }
+
+  // Note: Don't use "password = true" because then it will prompt even if we have a token
+  @Parameter(names = {"-p", "--password"}, description = "password (can be specified as 'pass:<password>', 'file:<local file containing the password>', "
+      + "'env:<variable containing the pass>', or stdin)", converter = PasswordConverter.class)
+  private String password;
+
+  public static class TokenConverter implements IStringConverter<AuthenticationToken> {
+    @Override
+    public AuthenticationToken convert(String value) {
+      try {
+        return Class.forName(value).asSubclass(AuthenticationToken.class).newInstance();
+      } catch (Exception e) {
+        // Catching ClassNotFoundException, ClassCastException, InstantiationException and IllegalAccessException
+        throw new ParameterException(e);
+      }
+    }
+  }
+
+  @Parameter(names = {"-tc", "--tokenClass"}, description = "token type to create, use the -l to pass options", converter = TokenConverter.class)
+  private AuthenticationToken authenticationToken;
+
+  @DynamicParameter(names = {"-l", "--tokenProperty"}, description = "login properties in the format key=value. Reuse -l for each property")
+  private Map<String,String> tokenProperties = new TreeMap<String,String>();
+
+  @Parameter(names = "--disable-tab-completion", description = "disables tab completion (for less overhead when scripting)")
+  private boolean tabCompletionDisabled;
+
+  @Parameter(names = "--debug", description = "enables client debugging")
+  private boolean debugEnabled;
+
+  @Parameter(names = "--fake", description = "fake a connection to accumulo")
+  private boolean fake;
+
+  @Parameter(names = {"-?", "--help"}, help = true, description = "display this help")
+  private boolean helpEnabled;
+
+  @Parameter(names = {"-e", "--execute-command"}, description = "executes a command, and then exits")
+  private String execCommand;
+
+  @Parameter(names = {"-f", "--execute-file"}, description = "executes commands from a file at startup", converter = FileConverter.class)
+  private File execFile;
+
+  @Parameter(names = {"-fv", "--execute-file-verbose"}, description = "executes commands from a file at startup, with commands shown",
+      converter = FileConverter.class)
+  private File execFileVerbose;
+
+  @Parameter(names = {"-h", "--hdfsZooInstance"}, description = "use hdfs zoo instance")
+  private boolean hdfsZooInstance;
+
+  @Parameter(names = {"-z", "--zooKeeperInstance"}, description = "use a zookeeper instance with the given instance name and list of zoo hosts", arity = 2)
+  private List<String> zooKeeperInstance = new ArrayList<String>();
+
+  @Parameter(names = {"--ssl"}, description = "use ssl to connect to accumulo")
+  private boolean useSsl = false;
+
+  @Parameter(
+      names = "--config-file",
+      description = "read the given client config file.  If omitted, the path searched can be specified with $ACCUMULO_CLIENT_CONF_PATH, which defaults to ~/.accumulo/config:$ACCUMULO_CONF_DIR/client.conf:/etc/accumulo/client.conf")
+  private String clientConfigFile = null;
+
+  @Parameter(names = {"-zi", "--zooKeeperInstanceName"}, description = "use a zookeeper instance with the given instance name")
+  private String zooKeeperInstanceName;
+
+  @Parameter(names = {"-zh", "--zooKeeperHosts"}, description = "use a zookeeper instance with the given list of zoo hosts")
+  private String zooKeeperHosts;
+
+  @Parameter(names = "--auth-timeout", description = "minutes the shell can be idle without re-entering a password")
+  private int authTimeout = 60; // TODO Add validator for positive number
+
+  @Parameter(names = "--disable-auth-timeout", description = "disables requiring the user to re-type a password after being idle")
+  private boolean authTimeoutDisabled;
+
+  @Parameter(hidden = true)
+  private List<String> unrecognizedOptions;
+
+  public String getUsername() {
+    return username;
+  }
+
+  public String getPassword() {
+    return password;
+  }
+
+  public AuthenticationToken getAuthenticationToken() {
+    return authenticationToken;
+  }
+
+  public Map<String,String> getTokenProperties() {
+    return tokenProperties;
+  }
+
+  public boolean isTabCompletionDisabled() {
+    return tabCompletionDisabled;
+  }
+
+  public boolean isDebugEnabled() {
+    return debugEnabled;
+  }
+
+  public boolean isFake() {
+    return fake;
+  }
+
+  public boolean isHelpEnabled() {
+    return helpEnabled;
+  }
+
+  public String getExecCommand() {
+    return execCommand;
+  }
+
+  public File getExecFile() {
+    return execFile;
+  }
+
+  public File getExecFileVerbose() {
+    return execFileVerbose;
+  }
+
+  public boolean isHdfsZooInstance() {
+    return hdfsZooInstance;
+  }
+
+  public List<String> getZooKeeperInstance() {
+    return zooKeeperInstance;
+  }
+
+  public String getZooKeeperInstanceName() {
+    return zooKeeperInstanceName;
+  }
+
+  public String getZooKeeperHosts() {
+    return zooKeeperHosts;
+  }
+
+  public int getAuthTimeout() {
+    return authTimeout;
+  }
+
+  public boolean isAuthTimeoutDisabled() {
+    return authTimeoutDisabled;
+  }
+
+  public List<String> getUnrecognizedOptions() {
+    return unrecognizedOptions;
+  }
+
+  public boolean useSsl() {
+    return useSsl;
+  }
+
+  public String getClientConfigFile() {
+    return clientConfigFile;
+  }
+
+  public ClientConfiguration getClientConfiguration() throws ConfigurationException, FileNotFoundException {
+    ClientConfiguration clientConfig = clientConfigFile == null ? ClientConfiguration.loadDefault() : new ClientConfiguration(new PropertiesConfiguration(
+        getClientConfigFile()));
+    if (useSsl()) {
+      clientConfig.setProperty(ClientProperty.INSTANCE_RPC_SSL_ENABLED, "true");
+    }
+    return clientConfig;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/ShellUtil.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/ShellUtil.java b/shell/src/main/java/org/apache/accumulo/shell/ShellUtil.java
new file mode 100644
index 0000000..c0f7a9a
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/ShellUtil.java
@@ -0,0 +1,60 @@
+/*
+ * 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.accumulo.shell;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.nio.charset.StandardCharsets;
+import java.util.List;
+import java.util.Scanner;
+
+import org.apache.commons.codec.binary.Base64;
+import org.apache.hadoop.io.Text;
+
+import com.google.common.collect.Lists;
+
+public class ShellUtil {
+
+  /**
+   * Scans the given file line-by-line (ignoring empty lines) and returns a list containing those lines. If decode is set to true, every line is decoded using
+   * {@link Base64#decodeBase64(byte[])} from the UTF-8 bytes of that line before inserting in the list.
+   * 
+   * @param filename
+   *          Path to the file that needs to be scanned
+   * @param decode
+   *          Whether to decode lines in the file
+   * @return List of {@link Text} objects containing data in the given file
+   * @throws FileNotFoundException
+   *           if the given file doesn't exist
+   */
+  public static List<Text> scanFile(String filename, boolean decode) throws FileNotFoundException {
+    String line;
+    Scanner file = new Scanner(new File(filename), StandardCharsets.UTF_8.name());
+    List<Text> result = Lists.newArrayList();
+    try {
+      while (file.hasNextLine()) {
+        line = file.nextLine();
+        if (!line.isEmpty()) {
+          result.add(decode ? new Text(Base64.decodeBase64(line.getBytes(StandardCharsets.UTF_8))) : new Text(line));
+        }
+      }
+    } finally {
+      file.close();
+    }
+    return result;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/Token.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/Token.java b/shell/src/main/java/org/apache/accumulo/shell/Token.java
new file mode 100644
index 0000000..5083457
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/Token.java
@@ -0,0 +1,137 @@
+/*
+ * 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.accumulo.shell;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+/*
+ * A token is a word in a command in the shell.  The tree that this builds is used for
+ * tab-completion of tables, users, commands and certain other parts of the shell that
+ * can be realistically and quickly gathered. Tokens can have multiple commands grouped 
+ * together and many possible subcommands, although they are stored in a set so duplicates
+ * aren't allowed.
+ */
+
+public class Token {
+  private Set<String> command = new HashSet<String>();
+  private Set<Token> subcommands = new HashSet<Token>();
+  private boolean caseSensitive = false;
+  
+  public Token() {}
+  
+  public Token(String commandName) {
+    this();
+    command.add(commandName);
+  }
+  
+  public Token(Collection<String> commandNames) {
+    this();
+    command.addAll(commandNames);
+  }
+  
+  public Token(Set<String> commandNames, Set<Token> subCommandNames) {
+    this();
+    command.addAll(commandNames);
+    subcommands.addAll(subCommandNames);
+  }
+  
+  public void setCaseSensitive(boolean cs) {
+    caseSensitive = cs;
+  }
+  
+  public boolean getCaseSensitive() {
+    return caseSensitive;
+  }
+  
+  public Set<String> getCommandNames() {
+    return command;
+  }
+  
+  public Set<Token> getSubcommandList() {
+    return subcommands;
+  }
+  
+  public Token getSubcommand(String name) {
+    Iterator<Token> iter = subcommands.iterator();
+    while (iter.hasNext()) {
+      Token t = iter.next();
+      if (t.containsCommand(name))
+        return t;
+    }
+    return null;
+  }
+  
+  public Set<String> getSubcommandNames() {
+    HashSet<String> set = new HashSet<String>();
+    for (Token t : subcommands)
+      set.addAll(t.getCommandNames());
+    return set;
+  }
+  
+  public Set<String> getSubcommandNames(String startsWith) {
+    Iterator<Token> iter = subcommands.iterator();
+    HashSet<String> set = new HashSet<String>();
+    while (iter.hasNext()) {
+      Token t = iter.next();
+      Set<String> subset = t.getCommandNames();
+      for (String s : subset) {
+        if (!t.getCaseSensitive()) {
+          if (s.toLowerCase().startsWith(startsWith.toLowerCase())) {
+            set.add(s);
+          }
+        } else {
+          if (s.startsWith(startsWith)) {
+            set.add(s);
+          }
+        }
+      }
+    }
+    return set;
+  }
+  
+  public boolean containsCommand(String match) {
+    Iterator<String> iter = command.iterator();
+    while (iter.hasNext()) {
+      String t = iter.next();
+      if (caseSensitive) {
+        if (t.equals(match))
+          return true;
+      } else {
+        if (t.equalsIgnoreCase(match))
+          return true;
+      }
+    }
+    return false;
+  }
+  
+  public void addSubcommand(Token t) {
+    subcommands.add(t);
+  }
+  
+  public void addSubcommand(Collection<String> t) {
+    for (String a : t) {
+      addSubcommand(new Token(a));
+    }
+  }
+  
+  public String toString() {
+    return this.command.toString();
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/AboutCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/AboutCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/AboutCommand.java
new file mode 100644
index 0000000..9ba8460
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/AboutCommand.java
@@ -0,0 +1,56 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.io.IOException;
+
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+
+public class AboutCommand extends Command {
+  private Option verboseOption;
+  
+  @Override
+  public String description() {
+    return "displays information about this program";
+  }
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws IOException {
+    shellState.printInfo();
+    if (cl.hasOption(verboseOption.getOpt())) {
+      shellState.printVerboseInfo();
+    }
+    return 0;
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options opts = new Options();
+    verboseOption = new Option("v", "verbose", false, "display detailed session information");
+    opts.addOption(verboseOption);
+    return opts;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/ActiveCompactionIterator.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/ActiveCompactionIterator.java b/shell/src/main/java/org/apache/accumulo/shell/commands/ActiveCompactionIterator.java
new file mode 100644
index 0000000..159a2a6
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/ActiveCompactionIterator.java
@@ -0,0 +1,136 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.accumulo.core.client.IteratorSetting;
+import org.apache.accumulo.core.client.admin.ActiveCompaction;
+import org.apache.accumulo.core.client.admin.InstanceOperations;
+import org.apache.accumulo.core.util.Duration;
+
+class ActiveCompactionIterator implements Iterator<String> {
+  
+  private InstanceOperations instanceOps;
+  private Iterator<String> tsIter;
+  private Iterator<String> compactionIter;
+  
+  private static String maxDecimal(double count) {
+    if (count < 9.995)
+      return String.format("%.2f", count);
+    if (count < 99.95)
+      return String.format("%.1f", count);
+    return String.format("%.0f", count);
+  }
+
+  private static String shortenCount(long count) {
+    if (count < 1000)
+      return count + "";
+    if (count < 1000000)
+      return maxDecimal(count / 1000.0) + "K";
+    if (count < 1000000000)
+      return maxDecimal(count / 1000000.0) + "M";
+    return maxDecimal(count / 1000000000.0) + "B";
+  }
+
+  private void readNext() {
+    final List<String> compactions = new ArrayList<String>();
+    
+    while (tsIter.hasNext()) {
+      
+      final String tserver = tsIter.next();
+      try {
+        List<ActiveCompaction> acl = instanceOps.getActiveCompactions(tserver);
+        
+        acl = new ArrayList<ActiveCompaction>(acl);
+        
+        Collections.sort(acl, new Comparator<ActiveCompaction>() {
+          @Override
+          public int compare(ActiveCompaction o1, ActiveCompaction o2) {
+            return (int) (o2.getAge() - o1.getAge());
+          }
+        });
+
+        for (ActiveCompaction ac : acl) {
+          String output = ac.getOutputFile();
+          int index = output.indexOf("tables");
+          if (index > 0) {
+            output = output.substring(index + 6);
+          }
+          
+          ac.getIterators();
+          
+          List<String> iterList = new ArrayList<String>();
+          Map<String,Map<String,String>> iterOpts = new HashMap<String,Map<String,String>>();
+          for (IteratorSetting is : ac.getIterators()) {
+            iterList.add(is.getName() + "=" + is.getPriority() + "," + is.getIteratorClass());
+            iterOpts.put(is.getName(), is.getOptions());
+          }
+
+          compactions.add(String.format("%21s | %9s | %5s | %6s | %5s | %5s | %15s | %-40s | %5s | %35s | %9s | %s", tserver,
+              Duration.format(ac.getAge(), "", "-"), ac.getType(), ac.getReason(), shortenCount(ac.getEntriesRead()), shortenCount(ac.getEntriesWritten()),
+              ac.getTable(), ac.getExtent(), ac.getInputFiles().size(), output, iterList, iterOpts));
+        }
+      } catch (Exception e) {
+        compactions.add(tserver + " ERROR " + e.getMessage());
+      }
+      
+      if (compactions.size() > 0) {
+        break;
+      }
+    }
+    
+    compactionIter = compactions.iterator();
+  }
+  
+  ActiveCompactionIterator(List<String> tservers, InstanceOperations instanceOps) {
+    this.instanceOps = instanceOps;
+    this.tsIter = tservers.iterator();
+    
+    final String header = String.format(" %-21s| %-9s | %-5s | %-6s | %-5s | %-5s | %-15s | %-40s | %-5s | %-35s | %-9s | %s", "TABLET SERVER", "AGE", "TYPE",
+        "REASON", "READ", "WROTE", "TABLE", "TABLET", "INPUT", "OUTPUT", "ITERATORS", "ITERATOR OPTIONS");
+    
+    compactionIter = Collections.singletonList(header).iterator();
+  }
+  
+  @Override
+  public boolean hasNext() {
+    return compactionIter.hasNext();
+  }
+  
+  @Override
+  public String next() {
+    final String next = compactionIter.next();
+    
+    if (!compactionIter.hasNext())
+      readNext();
+    
+    return next;
+  }
+  
+  @Override
+  public void remove() {
+    throw new UnsupportedOperationException();
+  }
+  
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/ActiveScanIterator.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/ActiveScanIterator.java b/shell/src/main/java/org/apache/accumulo/shell/commands/ActiveScanIterator.java
new file mode 100644
index 0000000..0412317
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/ActiveScanIterator.java
@@ -0,0 +1,91 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.accumulo.core.client.admin.ActiveScan;
+import org.apache.accumulo.core.client.admin.InstanceOperations;
+import org.apache.accumulo.core.client.admin.ScanType;
+import org.apache.accumulo.core.util.Duration;
+
+class ActiveScanIterator implements Iterator<String> {
+  
+  private InstanceOperations instanceOps;
+  private Iterator<String> tsIter;
+  private Iterator<String> scansIter;
+  
+  private void readNext() {
+    final List<String> scans = new ArrayList<String>();
+    
+    while (tsIter.hasNext()) {
+      
+      final String tserver = tsIter.next();
+      try {
+        final List<ActiveScan> asl = instanceOps.getActiveScans(tserver);
+        
+        for (ActiveScan as : asl) {
+          scans.add(String.format("%21s |%21s |%9s |%9s |%7s |%6s |%8s |%8s |%10s |%20s |%10s |%10s | %s", tserver, as.getClient(),
+              Duration.format(as.getAge(), "", "-"), Duration.format(as.getLastContactTime(), "", "-"), as.getState(), as.getType(), as.getUser(),
+              as.getTable(), as.getColumns(), as.getAuthorizations(), (as.getType() == ScanType.SINGLE ? as.getExtent() : "N/A"), as.getSsiList(), as.getSsio()));
+        }
+      } catch (Exception e) {
+        scans.add(tserver + " ERROR " + e.getMessage());
+      }
+      
+      if (scans.size() > 0) {
+        break;
+      }
+    }
+    
+    scansIter = scans.iterator();
+  }
+  
+  ActiveScanIterator(List<String> tservers, InstanceOperations instanceOps) {
+    this.instanceOps = instanceOps;
+    this.tsIter = tservers.iterator();
+    
+    final String header = String.format(" %-21s| %-21s| %-9s| %-9s| %-7s| %-6s| %-8s| %-8s| %-10s| %-20s| %-10s| %-10s | %s", "TABLET SERVER", "CLIENT", "AGE",
+        "LAST", "STATE", "TYPE", "USER", "TABLE", "COLUMNS", "AUTHORIZATIONS", "TABLET", "ITERATORS", "ITERATOR OPTIONS");
+    
+    scansIter = Collections.singletonList(header).iterator();
+  }
+  
+  @Override
+  public boolean hasNext() {
+    return scansIter.hasNext();
+  }
+  
+  @Override
+  public String next() {
+    final String next = scansIter.next();
+    
+    if (!scansIter.hasNext())
+      readNext();
+    
+    return next;
+  }
+  
+  @Override
+  public void remove() {
+    throw new UnsupportedOperationException();
+  }
+  
+}


[13/53] [abbrv] ACCUMULO-1897 Move shell into new package and module

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/ShellOptionsJC.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/ShellOptionsJC.java b/core/src/main/java/org/apache/accumulo/core/util/shell/ShellOptionsJC.java
deleted file mode 100644
index 38692a0..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/ShellOptionsJC.java
+++ /dev/null
@@ -1,280 +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.accumulo.core.util.shell;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Scanner;
-import java.util.TreeMap;
-
-import org.apache.accumulo.core.client.ClientConfiguration;
-import org.apache.accumulo.core.client.ClientConfiguration.ClientProperty;
-import org.apache.accumulo.core.client.security.tokens.AuthenticationToken;
-import org.apache.commons.configuration.ConfigurationException;
-import org.apache.commons.configuration.PropertiesConfiguration;
-import org.apache.log4j.Logger;
-
-import com.beust.jcommander.DynamicParameter;
-import com.beust.jcommander.IStringConverter;
-import com.beust.jcommander.Parameter;
-import com.beust.jcommander.ParameterException;
-import com.beust.jcommander.converters.FileConverter;
-
-public class ShellOptionsJC {
-  // Use the Shell logger because this is really just an extension.
-  public static final Logger log = Logger.getLogger(Shell.class);
-
-  @Parameter(names = {"-u", "--user"}, description = "username (defaults to your OS user)")
-  private String username = System.getProperty("user.name", "root");
-
-  public static class PasswordConverter implements IStringConverter<String> {
-    public static final String STDIN = "stdin";
-
-    private enum KeyType {
-      PASS("pass:"), ENV("env:") {
-        @Override
-        String process(String value) {
-          return System.getenv(value);
-        }
-      },
-      FILE("file:") {
-        @Override
-        String process(String value) {
-          Scanner scanner = null;
-          try {
-            scanner = new Scanner(new File(value));
-            return scanner.nextLine();
-          } catch (FileNotFoundException e) {
-            throw new ParameterException(e);
-          } finally {
-            if (scanner != null) {
-              scanner.close();
-            }
-          }
-        }
-      },
-      STDIN(PasswordConverter.STDIN) {
-        @Override
-        public boolean matches(String value) {
-          return prefix.equals(value);
-        }
-
-        @Override
-        public String convert(String value) {
-          // Will check for this later
-          return prefix;
-        }
-      };
-
-      String prefix;
-
-      private KeyType(String prefix) {
-        this.prefix = prefix;
-      }
-
-      public boolean matches(String value) {
-        return value.startsWith(prefix);
-      }
-
-      public String convert(String value) {
-        return process(value.substring(prefix.length()));
-      }
-
-      String process(String value) {
-        return value;
-      }
-    };
-
-    @Override
-    public String convert(String value) {
-      for (KeyType keyType : KeyType.values()) {
-        if (keyType.matches(value)) {
-          return keyType.convert(value);
-        }
-      }
-
-      return value;
-    }
-  }
-
-  // Note: Don't use "password = true" because then it will prompt even if we have a token
-  @Parameter(names = {"-p", "--password"}, description = "password (can be specified as 'pass:<password>', 'file:<local file containing the password>', "
-      + "'env:<variable containing the pass>', or stdin)", converter = PasswordConverter.class)
-  private String password;
-
-  public static class TokenConverter implements IStringConverter<AuthenticationToken> {
-    @Override
-    public AuthenticationToken convert(String value) {
-      try {
-        return Class.forName(value).asSubclass(AuthenticationToken.class).newInstance();
-      } catch (Exception e) {
-        // Catching ClassNotFoundException, ClassCastException, InstantiationException and IllegalAccessException
-        throw new ParameterException(e);
-      }
-    }
-  }
-
-  @Parameter(names = {"-tc", "--tokenClass"}, description = "token type to create, use the -l to pass options", converter = TokenConverter.class)
-  private AuthenticationToken authenticationToken;
-
-  @DynamicParameter(names = {"-l", "--tokenProperty"}, description = "login properties in the format key=value. Reuse -l for each property")
-  private Map<String,String> tokenProperties = new TreeMap<String,String>();
-
-  @Parameter(names = "--disable-tab-completion", description = "disables tab completion (for less overhead when scripting)")
-  private boolean tabCompletionDisabled;
-
-  @Parameter(names = "--debug", description = "enables client debugging")
-  private boolean debugEnabled;
-
-  @Parameter(names = "--fake", description = "fake a connection to accumulo")
-  private boolean fake;
-
-  @Parameter(names = {"-?", "--help"}, help = true, description = "display this help")
-  private boolean helpEnabled;
-
-  @Parameter(names = {"-e", "--execute-command"}, description = "executes a command, and then exits")
-  private String execCommand;
-
-  @Parameter(names = {"-f", "--execute-file"}, description = "executes commands from a file at startup", converter = FileConverter.class)
-  private File execFile;
-
-  @Parameter(names = {"-fv", "--execute-file-verbose"}, description = "executes commands from a file at startup, with commands shown",
-      converter = FileConverter.class)
-  private File execFileVerbose;
-
-  @Parameter(names = {"-h", "--hdfsZooInstance"}, description = "use hdfs zoo instance")
-  private boolean hdfsZooInstance;
-
-  @Parameter(names = {"-z", "--zooKeeperInstance"}, description = "use a zookeeper instance with the given instance name and list of zoo hosts", arity = 2)
-  private List<String> zooKeeperInstance = new ArrayList<String>();
-
-  @Parameter(names = {"--ssl"}, description = "use ssl to connect to accumulo")
-  private boolean useSsl = false;
-
-  @Parameter(
-      names = "--config-file",
-      description = "read the given client config file.  If omitted, the path searched can be specified with $ACCUMULO_CLIENT_CONF_PATH, which defaults to ~/.accumulo/config:$ACCUMULO_CONF_DIR/client.conf:/etc/accumulo/client.conf")
-  private String clientConfigFile = null;
-
-  @Parameter(names = {"-zi", "--zooKeeperInstanceName"}, description = "use a zookeeper instance with the given instance name")
-  private String zooKeeperInstanceName;
-
-  @Parameter(names = {"-zh", "--zooKeeperHosts"}, description = "use a zookeeper instance with the given list of zoo hosts")
-  private String zooKeeperHosts;
-
-  @Parameter(names = "--auth-timeout", description = "minutes the shell can be idle without re-entering a password")
-  private int authTimeout = 60; // TODO Add validator for positive number
-
-  @Parameter(names = "--disable-auth-timeout", description = "disables requiring the user to re-type a password after being idle")
-  private boolean authTimeoutDisabled;
-
-  @Parameter(hidden = true)
-  private List<String> unrecognizedOptions;
-
-  public String getUsername() {
-    return username;
-  }
-
-  public String getPassword() {
-    return password;
-  }
-
-  public AuthenticationToken getAuthenticationToken() {
-    return authenticationToken;
-  }
-
-  public Map<String,String> getTokenProperties() {
-    return tokenProperties;
-  }
-
-  public boolean isTabCompletionDisabled() {
-    return tabCompletionDisabled;
-  }
-
-  public boolean isDebugEnabled() {
-    return debugEnabled;
-  }
-
-  public boolean isFake() {
-    return fake;
-  }
-
-  public boolean isHelpEnabled() {
-    return helpEnabled;
-  }
-
-  public String getExecCommand() {
-    return execCommand;
-  }
-
-  public File getExecFile() {
-    return execFile;
-  }
-
-  public File getExecFileVerbose() {
-    return execFileVerbose;
-  }
-
-  public boolean isHdfsZooInstance() {
-    return hdfsZooInstance;
-  }
-
-  public List<String> getZooKeeperInstance() {
-    return zooKeeperInstance;
-  }
-
-  public String getZooKeeperInstanceName() {
-    return zooKeeperInstanceName;
-  }
-
-  public String getZooKeeperHosts() {
-    return zooKeeperHosts;
-  }
-
-  public int getAuthTimeout() {
-    return authTimeout;
-  }
-
-  public boolean isAuthTimeoutDisabled() {
-    return authTimeoutDisabled;
-  }
-
-  public List<String> getUnrecognizedOptions() {
-    return unrecognizedOptions;
-  }
-
-  public boolean useSsl() {
-    return useSsl;
-  }
-
-  public String getClientConfigFile() {
-    return clientConfigFile;
-  }
-
-  public ClientConfiguration getClientConfiguration() throws ConfigurationException, FileNotFoundException {
-    ClientConfiguration clientConfig = clientConfigFile == null ? ClientConfiguration.loadDefault() : new ClientConfiguration(new PropertiesConfiguration(
-        getClientConfigFile()));
-    if (useSsl()) {
-      clientConfig.setProperty(ClientProperty.INSTANCE_RPC_SSL_ENABLED, "true");
-    }
-    return clientConfig;
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/ShellUtil.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/ShellUtil.java b/core/src/main/java/org/apache/accumulo/core/util/shell/ShellUtil.java
deleted file mode 100644
index f0dd505..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/ShellUtil.java
+++ /dev/null
@@ -1,60 +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.accumulo.core.util.shell;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.nio.charset.StandardCharsets;
-import java.util.List;
-import java.util.Scanner;
-
-import org.apache.commons.codec.binary.Base64;
-import org.apache.hadoop.io.Text;
-
-import com.google.common.collect.Lists;
-
-public class ShellUtil {
-
-  /**
-   * Scans the given file line-by-line (ignoring empty lines) and returns a list containing those lines. If decode is set to true, every line is decoded using
-   * {@link Base64#decodeBase64(byte[])} from the UTF-8 bytes of that line before inserting in the list.
-   * 
-   * @param filename
-   *          Path to the file that needs to be scanned
-   * @param decode
-   *          Whether to decode lines in the file
-   * @return List of {@link Text} objects containing data in the given file
-   * @throws FileNotFoundException
-   *           if the given file doesn't exist
-   */
-  public static List<Text> scanFile(String filename, boolean decode) throws FileNotFoundException {
-    String line;
-    Scanner file = new Scanner(new File(filename), StandardCharsets.UTF_8.name());
-    List<Text> result = Lists.newArrayList();
-    try {
-      while (file.hasNextLine()) {
-        line = file.nextLine();
-        if (!line.isEmpty()) {
-          result.add(decode ? new Text(Base64.decodeBase64(line.getBytes(StandardCharsets.UTF_8))) : new Text(line));
-        }
-      }
-    } finally {
-      file.close();
-    }
-    return result;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/Token.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/Token.java b/core/src/main/java/org/apache/accumulo/core/util/shell/Token.java
deleted file mode 100644
index b6c5869..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/Token.java
+++ /dev/null
@@ -1,137 +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.accumulo.core.util.shell;
-
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Set;
-
-/*
- * A token is a word in a command in the shell.  The tree that this builds is used for
- * tab-completion of tables, users, commands and certain other parts of the shell that
- * can be realistically and quickly gathered. Tokens can have multiple commands grouped 
- * together and many possible subcommands, although they are stored in a set so duplicates
- * aren't allowed.
- */
-
-public class Token {
-  private Set<String> command = new HashSet<String>();
-  private Set<Token> subcommands = new HashSet<Token>();
-  private boolean caseSensitive = false;
-  
-  public Token() {}
-  
-  public Token(String commandName) {
-    this();
-    command.add(commandName);
-  }
-  
-  public Token(Collection<String> commandNames) {
-    this();
-    command.addAll(commandNames);
-  }
-  
-  public Token(Set<String> commandNames, Set<Token> subCommandNames) {
-    this();
-    command.addAll(commandNames);
-    subcommands.addAll(subCommandNames);
-  }
-  
-  public void setCaseSensitive(boolean cs) {
-    caseSensitive = cs;
-  }
-  
-  public boolean getCaseSensitive() {
-    return caseSensitive;
-  }
-  
-  public Set<String> getCommandNames() {
-    return command;
-  }
-  
-  public Set<Token> getSubcommandList() {
-    return subcommands;
-  }
-  
-  public Token getSubcommand(String name) {
-    Iterator<Token> iter = subcommands.iterator();
-    while (iter.hasNext()) {
-      Token t = iter.next();
-      if (t.containsCommand(name))
-        return t;
-    }
-    return null;
-  }
-  
-  public Set<String> getSubcommandNames() {
-    HashSet<String> set = new HashSet<String>();
-    for (Token t : subcommands)
-      set.addAll(t.getCommandNames());
-    return set;
-  }
-  
-  public Set<String> getSubcommandNames(String startsWith) {
-    Iterator<Token> iter = subcommands.iterator();
-    HashSet<String> set = new HashSet<String>();
-    while (iter.hasNext()) {
-      Token t = iter.next();
-      Set<String> subset = t.getCommandNames();
-      for (String s : subset) {
-        if (!t.getCaseSensitive()) {
-          if (s.toLowerCase().startsWith(startsWith.toLowerCase())) {
-            set.add(s);
-          }
-        } else {
-          if (s.startsWith(startsWith)) {
-            set.add(s);
-          }
-        }
-      }
-    }
-    return set;
-  }
-  
-  public boolean containsCommand(String match) {
-    Iterator<String> iter = command.iterator();
-    while (iter.hasNext()) {
-      String t = iter.next();
-      if (caseSensitive) {
-        if (t.equals(match))
-          return true;
-      } else {
-        if (t.equalsIgnoreCase(match))
-          return true;
-      }
-    }
-    return false;
-  }
-  
-  public void addSubcommand(Token t) {
-    subcommands.add(t);
-  }
-  
-  public void addSubcommand(Collection<String> t) {
-    for (String a : t) {
-      addSubcommand(new Token(a));
-    }
-  }
-  
-  public String toString() {
-    return this.command.toString();
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/AboutCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/AboutCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/AboutCommand.java
deleted file mode 100644
index a0a73e4..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/AboutCommand.java
+++ /dev/null
@@ -1,56 +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.accumulo.core.util.shell.commands;
-
-import java.io.IOException;
-
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-
-public class AboutCommand extends Command {
-  private Option verboseOption;
-  
-  @Override
-  public String description() {
-    return "displays information about this program";
-  }
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws IOException {
-    shellState.printInfo();
-    if (cl.hasOption(verboseOption.getOpt())) {
-      shellState.printVerboseInfo();
-    }
-    return 0;
-  }
-  
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options opts = new Options();
-    verboseOption = new Option("v", "verbose", false, "display detailed session information");
-    opts.addOption(verboseOption);
-    return opts;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ActiveCompactionIterator.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ActiveCompactionIterator.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ActiveCompactionIterator.java
deleted file mode 100644
index bd7d9b2..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ActiveCompactionIterator.java
+++ /dev/null
@@ -1,136 +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.accumulo.core.util.shell.commands;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.accumulo.core.client.IteratorSetting;
-import org.apache.accumulo.core.client.admin.ActiveCompaction;
-import org.apache.accumulo.core.client.admin.InstanceOperations;
-import org.apache.accumulo.core.util.Duration;
-
-class ActiveCompactionIterator implements Iterator<String> {
-  
-  private InstanceOperations instanceOps;
-  private Iterator<String> tsIter;
-  private Iterator<String> compactionIter;
-  
-  private static String maxDecimal(double count) {
-    if (count < 9.995)
-      return String.format("%.2f", count);
-    if (count < 99.95)
-      return String.format("%.1f", count);
-    return String.format("%.0f", count);
-  }
-
-  private static String shortenCount(long count) {
-    if (count < 1000)
-      return count + "";
-    if (count < 1000000)
-      return maxDecimal(count / 1000.0) + "K";
-    if (count < 1000000000)
-      return maxDecimal(count / 1000000.0) + "M";
-    return maxDecimal(count / 1000000000.0) + "B";
-  }
-
-  private void readNext() {
-    final List<String> compactions = new ArrayList<String>();
-    
-    while (tsIter.hasNext()) {
-      
-      final String tserver = tsIter.next();
-      try {
-        List<ActiveCompaction> acl = instanceOps.getActiveCompactions(tserver);
-        
-        acl = new ArrayList<ActiveCompaction>(acl);
-        
-        Collections.sort(acl, new Comparator<ActiveCompaction>() {
-          @Override
-          public int compare(ActiveCompaction o1, ActiveCompaction o2) {
-            return (int) (o2.getAge() - o1.getAge());
-          }
-        });
-
-        for (ActiveCompaction ac : acl) {
-          String output = ac.getOutputFile();
-          int index = output.indexOf("tables");
-          if (index > 0) {
-            output = output.substring(index + 6);
-          }
-          
-          ac.getIterators();
-          
-          List<String> iterList = new ArrayList<String>();
-          Map<String,Map<String,String>> iterOpts = new HashMap<String,Map<String,String>>();
-          for (IteratorSetting is : ac.getIterators()) {
-            iterList.add(is.getName() + "=" + is.getPriority() + "," + is.getIteratorClass());
-            iterOpts.put(is.getName(), is.getOptions());
-          }
-
-          compactions.add(String.format("%21s | %9s | %5s | %6s | %5s | %5s | %15s | %-40s | %5s | %35s | %9s | %s", tserver,
-              Duration.format(ac.getAge(), "", "-"), ac.getType(), ac.getReason(), shortenCount(ac.getEntriesRead()), shortenCount(ac.getEntriesWritten()),
-              ac.getTable(), ac.getExtent(), ac.getInputFiles().size(), output, iterList, iterOpts));
-        }
-      } catch (Exception e) {
-        compactions.add(tserver + " ERROR " + e.getMessage());
-      }
-      
-      if (compactions.size() > 0) {
-        break;
-      }
-    }
-    
-    compactionIter = compactions.iterator();
-  }
-  
-  ActiveCompactionIterator(List<String> tservers, InstanceOperations instanceOps) {
-    this.instanceOps = instanceOps;
-    this.tsIter = tservers.iterator();
-    
-    final String header = String.format(" %-21s| %-9s | %-5s | %-6s | %-5s | %-5s | %-15s | %-40s | %-5s | %-35s | %-9s | %s", "TABLET SERVER", "AGE", "TYPE",
-        "REASON", "READ", "WROTE", "TABLE", "TABLET", "INPUT", "OUTPUT", "ITERATORS", "ITERATOR OPTIONS");
-    
-    compactionIter = Collections.singletonList(header).iterator();
-  }
-  
-  @Override
-  public boolean hasNext() {
-    return compactionIter.hasNext();
-  }
-  
-  @Override
-  public String next() {
-    final String next = compactionIter.next();
-    
-    if (!compactionIter.hasNext())
-      readNext();
-    
-    return next;
-  }
-  
-  @Override
-  public void remove() {
-    throw new UnsupportedOperationException();
-  }
-  
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ActiveScanIterator.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ActiveScanIterator.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ActiveScanIterator.java
deleted file mode 100644
index f1e736f..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ActiveScanIterator.java
+++ /dev/null
@@ -1,91 +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.accumulo.core.util.shell.commands;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-
-import org.apache.accumulo.core.client.admin.ActiveScan;
-import org.apache.accumulo.core.client.admin.InstanceOperations;
-import org.apache.accumulo.core.client.admin.ScanType;
-import org.apache.accumulo.core.util.Duration;
-
-class ActiveScanIterator implements Iterator<String> {
-  
-  private InstanceOperations instanceOps;
-  private Iterator<String> tsIter;
-  private Iterator<String> scansIter;
-  
-  private void readNext() {
-    final List<String> scans = new ArrayList<String>();
-    
-    while (tsIter.hasNext()) {
-      
-      final String tserver = tsIter.next();
-      try {
-        final List<ActiveScan> asl = instanceOps.getActiveScans(tserver);
-        
-        for (ActiveScan as : asl) {
-          scans.add(String.format("%21s |%21s |%9s |%9s |%7s |%6s |%8s |%8s |%10s |%20s |%10s |%10s | %s", tserver, as.getClient(),
-              Duration.format(as.getAge(), "", "-"), Duration.format(as.getLastContactTime(), "", "-"), as.getState(), as.getType(), as.getUser(),
-              as.getTable(), as.getColumns(), as.getAuthorizations(), (as.getType() == ScanType.SINGLE ? as.getExtent() : "N/A"), as.getSsiList(), as.getSsio()));
-        }
-      } catch (Exception e) {
-        scans.add(tserver + " ERROR " + e.getMessage());
-      }
-      
-      if (scans.size() > 0) {
-        break;
-      }
-    }
-    
-    scansIter = scans.iterator();
-  }
-  
-  ActiveScanIterator(List<String> tservers, InstanceOperations instanceOps) {
-    this.instanceOps = instanceOps;
-    this.tsIter = tservers.iterator();
-    
-    final String header = String.format(" %-21s| %-21s| %-9s| %-9s| %-7s| %-6s| %-8s| %-8s| %-10s| %-20s| %-10s| %-10s | %s", "TABLET SERVER", "CLIENT", "AGE",
-        "LAST", "STATE", "TYPE", "USER", "TABLE", "COLUMNS", "AUTHORIZATIONS", "TABLET", "ITERATORS", "ITERATOR OPTIONS");
-    
-    scansIter = Collections.singletonList(header).iterator();
-  }
-  
-  @Override
-  public boolean hasNext() {
-    return scansIter.hasNext();
-  }
-  
-  @Override
-  public String next() {
-    final String next = scansIter.next();
-    
-    if (!scansIter.hasNext())
-      readNext();
-    
-    return next;
-  }
-  
-  @Override
-  public void remove() {
-    throw new UnsupportedOperationException();
-  }
-  
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/AddAuthsCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/AddAuthsCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/AddAuthsCommand.java
deleted file mode 100644
index bd478de..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/AddAuthsCommand.java
+++ /dev/null
@@ -1,82 +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.accumulo.core.util.shell.commands;
-
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.security.Authorizations;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.accumulo.core.util.shell.Token;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.OptionGroup;
-import org.apache.commons.cli.Options;
-
-public class AddAuthsCommand extends Command {
-  private Option userOpt;
-  private Option scanOptAuths;
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException {
-    final String user = cl.getOptionValue(userOpt.getOpt(), shellState.getConnector().whoami());
-    final String scanOpts = cl.getOptionValue(scanOptAuths.getOpt());
-    Authorizations auths = shellState.getConnector().securityOperations().getUserAuthorizations(user);
-    StringBuilder userAuths = new StringBuilder();
-    if (!auths.isEmpty()) {
-      userAuths.append(auths.toString());
-      userAuths.append(",");
-    }
-    userAuths.append(scanOpts);
-    shellState.getConnector().securityOperations().changeUserAuthorizations(user, ScanCommand.parseAuthorizations(userAuths.toString()));
-    Shell.log.debug("Changed record-level authorizations for user " + user);
-    return 0;
-  }
-  
-  @Override
-  public String description() {
-    return "adds authorizations to the maximum scan authorizations for a user";
-  }
-  
-  @Override
-  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> completionSet) {
-    registerCompletionForUsers(root, completionSet);
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-    final OptionGroup setOrClear = new OptionGroup();
-    scanOptAuths = new Option("s", "scan-authorizations", true, "scan authorizations to set");
-    scanOptAuths.setArgName("comma-separated-authorizations");
-    setOrClear.addOption(scanOptAuths);
-    setOrClear.setRequired(true);
-    o.addOptionGroup(setOrClear);
-    userOpt = new Option(Shell.userOption, "user", true, "user to operate on");
-    userOpt.setArgName("user");
-    o.addOption(userOpt);
-    return o;
-  }
-  
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/AddSplitsCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/AddSplitsCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/AddSplitsCommand.java
deleted file mode 100644
index b8ba621..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/AddSplitsCommand.java
+++ /dev/null
@@ -1,88 +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.accumulo.core.util.shell.commands;
-
-import java.util.TreeSet;
-
-import org.apache.accumulo.core.client.TableNotFoundException;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.accumulo.core.util.shell.ShellUtil;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.MissingArgumentException;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-import org.apache.hadoop.io.Text;
-
-public class AddSplitsCommand extends Command {
-  private Option optSplitsFile, base64Opt;
-  
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    final String tableName = OptUtil.getTableOpt(cl, shellState);
-    final boolean decode = cl.hasOption(base64Opt.getOpt());
-    
-    final TreeSet<Text> splits = new TreeSet<Text>();
-    
-    if (cl.hasOption(optSplitsFile.getOpt())) {
-      splits.addAll(ShellUtil.scanFile(cl.getOptionValue(optSplitsFile.getOpt()), decode));
-    } else {
-      if (cl.getArgList().isEmpty()) {
-        throw new MissingArgumentException("No split points specified");
-      }
-      for (String s : cl.getArgs()) {
-        splits.add(new Text(s.getBytes(Shell.CHARSET)));
-      }
-    }
-    
-    if (!shellState.getConnector().tableOperations().exists(tableName)) {
-      throw new TableNotFoundException(null, tableName, null);
-    }
-    shellState.getConnector().tableOperations().addSplits(tableName, splits);
-    
-    return 0;
-  }
-  
-  @Override
-  public String description() {
-    return "adds split points to an existing table";
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-    
-    optSplitsFile = new Option("sf", "splits-file", true, "file with a newline-separated list of rows to split the table with");
-    optSplitsFile.setArgName("filename");
-    
-    base64Opt = new Option("b64", "base64encoded", false, "decode encoded split points (splits file only)");
-    
-    o.addOption(OptUtil.tableOpt("name of the table to add split points to"));
-    o.addOption(optSplitsFile);
-    o.addOption(base64Opt);
-    return o;
-  }
-  
-  @Override
-  public String usage() {
-    return getName() + " [<split>{ <split>} ]";
-  }
-  
-  @Override
-  public int numArgs() {
-    return Shell.NO_FIXED_ARG_LENGTH_CHECK;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/AuthenticateCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/AuthenticateCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/AuthenticateCommand.java
deleted file mode 100644
index 8ebdae8..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/AuthenticateCommand.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.accumulo.core.util.shell.commands;
-
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.security.tokens.PasswordToken;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.accumulo.core.util.shell.Token;
-import org.apache.commons.cli.CommandLine;
-
-public class AuthenticateCommand extends Command {
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException, IOException {
-    final String user = cl.getArgs()[0];
-    final String p = shellState.readMaskedLine("Enter current password for '" + user + "': ", '*');
-    if (p == null) {
-      shellState.getReader().println();
-      return 0;
-    } // user canceled
-    final byte[] password = p.getBytes(StandardCharsets.UTF_8);
-    final boolean valid = shellState.getConnector().securityOperations().authenticateUser(user, new PasswordToken(password));
-    shellState.getReader().println((valid ? "V" : "Not v") + "alid");
-    return 0;
-  }
-  
-  @Override
-  public String description() {
-    return "verifies a user's credentials";
-  }
-  
-  @Override
-  public String usage() {
-    return getName() + " <username>";
-  }
-  
-  @Override
-  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> completionSet) {
-    registerCompletionForUsers(root, completionSet);
-  }
-  
-  @Override
-  public int numArgs() {
-    return 1;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ByeCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ByeCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ByeCommand.java
deleted file mode 100644
index f0c9d24..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ByeCommand.java
+++ /dev/null
@@ -1,19 +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.accumulo.core.util.shell.commands;
-
-public class ByeCommand extends ExitCommand {}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ClasspathCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ClasspathCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ClasspathCommand.java
deleted file mode 100644
index b2fe300..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ClasspathCommand.java
+++ /dev/null
@@ -1,55 +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.accumulo.core.util.shell.commands;
-
-import java.io.IOException;
-
-import jline.console.ConsoleReader;
-
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.accumulo.start.classloader.vfs.AccumuloVFSClassLoader;
-import org.apache.accumulo.start.classloader.vfs.AccumuloVFSClassLoader.Printer;
-import org.apache.commons.cli.CommandLine;
-
-public class ClasspathCommand extends Command {
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) {
-    final ConsoleReader reader = shellState.getReader();
-    AccumuloVFSClassLoader.printClassPath(new Printer() {
-      @Override
-      public void print(String s) {
-        try {
-          reader.println(s);
-        } catch (IOException ex) {
-          throw new RuntimeException(ex);
-        }
-      }
-    });
-    return 0;
-  }
-  
-  @Override
-  public String description() {
-    return "lists the current files on the classpath";
-  }
-  
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ClearCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ClearCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ClearCommand.java
deleted file mode 100644
index 4f15650..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ClearCommand.java
+++ /dev/null
@@ -1,52 +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.accumulo.core.util.shell.commands;
-
-import java.io.IOException;
-
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-
-public class ClearCommand extends Command {
-  @Override
-  public String description() {
-    return "clears the screen";
-  }
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws IOException {
-    // custom clear screen, so I don't have to redraw the prompt twice
-    if (!shellState.getReader().getTerminal().isAnsiSupported()) {
-      throw new IOException("Terminal does not support ANSI commands");
-    }
-    // send the ANSI code to clear the screen
-    shellState.getReader().print(((char) 27) + "[2J");
-    shellState.getReader().flush();
-    
-    // then send the ANSI code to go to position 1,1
-    shellState.getReader().print(((char) 27) + "[1;1H");
-    shellState.getReader().flush();
-    
-    return 0;
-  }
-  
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/CloneTableCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/CloneTableCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/CloneTableCommand.java
deleted file mode 100644
index 207e530..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/CloneTableCommand.java
+++ /dev/null
@@ -1,102 +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.accumulo.core.util.shell.commands;
-
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.TableExistsException;
-import org.apache.accumulo.core.client.TableNotFoundException;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.accumulo.core.util.shell.Token;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-
-public class CloneTableCommand extends Command {
-  
-  private Option setPropsOption;
-  private Option excludePropsOption;
-  private Option noFlushOption;
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException, TableNotFoundException,
-      TableExistsException {
-    
-    final HashMap<String,String> props = new HashMap<String,String>();
-    final HashSet<String> exclude = new HashSet<String>();
-    boolean flush = true;
-    
-    if (cl.hasOption(setPropsOption.getOpt())) {
-      String[] keyVals = cl.getOptionValue(setPropsOption.getOpt()).split(",");
-      for (String keyVal : keyVals) {
-        String[] sa = keyVal.split("=");
-        props.put(sa[0], sa[1]);
-      }
-    }
-    
-    if (cl.hasOption(excludePropsOption.getOpt())) {
-      String[] keys = cl.getOptionValue(excludePropsOption.getOpt()).split(",");
-      for (String key : keys) {
-        exclude.add(key);
-      }
-    }
-    
-    if (cl.hasOption(noFlushOption.getOpt())) {
-      flush = false;
-    }
-    
-    shellState.getConnector().tableOperations().clone(cl.getArgs()[0], cl.getArgs()[1], flush, props, exclude);
-    return 0;
-  }
-  
-  @Override
-  public String usage() {
-    return getName() + " <current table name> <new table name>";
-  }
-  
-  @Override
-  public String description() {
-    return "clones a table";
-  }
-  
-  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> completionSet) {
-    registerCompletionForTables(root, completionSet);
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-    setPropsOption = new Option("s", "set", true, "set initial properties before the table comes online. Expects <prop>=<value>{,<prop>=<value>}");
-    o.addOption(setPropsOption);
-    excludePropsOption = new Option("e", "exclude", true, "exclude properties that should not be copied from source table. Expects <prop>{,<prop>}");
-    o.addOption(excludePropsOption);
-    noFlushOption = new Option("nf", "noFlush", false, "do not flush table data in memory before cloning.");
-    o.addOption(noFlushOption);
-    return o;
-  }
-  
-  @Override
-  public int numArgs() {
-    return 2;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ClsCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ClsCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ClsCommand.java
deleted file mode 100644
index cef6098..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ClsCommand.java
+++ /dev/null
@@ -1,19 +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.accumulo.core.util.shell.commands;
-
-public class ClsCommand extends ClearCommand {}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/CompactCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/CompactCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/CompactCommand.java
deleted file mode 100644
index 55e9395..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/CompactCommand.java
+++ /dev/null
@@ -1,129 +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.accumulo.core.util.shell.commands;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.IteratorSetting;
-import org.apache.accumulo.core.client.TableNotFoundException;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-import org.apache.hadoop.io.Text;
-
-public class CompactCommand extends TableOperation {
-  private Option noFlushOption, waitOpt, profileOpt, cancelOpt;
-  private boolean flush;
-  private Text startRow;
-  private Text endRow;
-  private List<IteratorSetting> iterators;
-  
-  boolean override = false;
-  private boolean wait;
-  
-  private boolean cancel = false;
-
-  @Override
-  public String description() {
-    return "sets all tablets for a table to major compact as soon as possible (based on current time)";
-  }
-  
-  protected void doTableOp(final Shell shellState, final String tableName) throws AccumuloException, AccumuloSecurityException {
-    // compact the tables
-    
-    if (cancel) {
-      try {
-        shellState.getConnector().tableOperations().cancelCompaction(tableName);
-        Shell.log.info("Compaction canceled for table " + tableName);
-      } catch (TableNotFoundException e) {
-        throw new AccumuloException(e);
-      }
-    } else {
-      try {
-        if (wait) {
-          Shell.log.info("Compacting table ...");
-        }
-        
-        shellState.getConnector().tableOperations().compact(tableName, startRow, endRow, iterators, flush, wait);
-        
-        Shell.log.info("Compaction of table " + tableName + " " + (wait ? "completed" : "started") + " for given range");
-      } catch (Exception ex) {
-        throw new AccumuloException(ex);
-      }
-    }
-  }
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    
-    if (cl.hasOption(cancelOpt.getLongOpt())) {
-      cancel = true;
-      
-      if (cl.getOptions().length > 2) {
-        throw new IllegalArgumentException("Can not specify other options with cancel");
-      }
-    } else {
-      cancel = false;
-    }
-
-    flush = !cl.hasOption(noFlushOption.getOpt());
-    startRow = OptUtil.getStartRow(cl);
-    endRow = OptUtil.getEndRow(cl);
-    wait = cl.hasOption(waitOpt.getOpt());
-    
-    if (cl.hasOption(profileOpt.getOpt())) {
-      List<IteratorSetting> iterators = shellState.iteratorProfiles.get(cl.getOptionValue(profileOpt.getOpt()));
-      if (iterators == null) {
-        Shell.log.error("Profile " + cl.getOptionValue(profileOpt.getOpt()) + " does not exist");
-        return -1;
-      }
-      
-      this.iterators = new ArrayList<IteratorSetting>(iterators);
-    } else {
-      this.iterators = Collections.emptyList();
-    }
-
-
-    return super.execute(fullCommand, cl, shellState);
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options opts = super.getOptions();
-    
-    opts.addOption(OptUtil.startRowOpt());
-    opts.addOption(OptUtil.endRowOpt());
-    noFlushOption = new Option("nf", "noFlush", false, "do not flush table data in memory before compacting.");
-    opts.addOption(noFlushOption);
-    waitOpt = new Option("w", "wait", false, "wait for compact to finish");
-    opts.addOption(waitOpt);
-    
-    profileOpt = new Option("pn", "profile", true, "iterator profile name");
-    profileOpt.setArgName("profile");
-    opts.addOption(profileOpt);
-
-    cancelOpt = new Option(null, "cancel", false, "cancel user initiated compactions");
-    opts.addOption(cancelOpt);
-
-    return opts;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ConfigCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ConfigCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ConfigCommand.java
deleted file mode 100644
index c76a51f..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ConfigCommand.java
+++ /dev/null
@@ -1,315 +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.accumulo.core.util.shell.commands;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.TreeMap;
-
-import jline.console.ConsoleReader;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.NamespaceNotFoundException;
-import org.apache.accumulo.core.client.TableNotFoundException;
-import org.apache.accumulo.core.client.impl.Namespaces;
-import org.apache.accumulo.core.client.impl.Tables;
-import org.apache.accumulo.core.conf.AccumuloConfiguration;
-import org.apache.accumulo.core.conf.Property;
-import org.apache.accumulo.core.security.ColumnVisibility;
-import org.apache.accumulo.core.util.BadArgumentException;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.accumulo.core.util.shell.Shell.PrintFile;
-import org.apache.accumulo.core.util.shell.Token;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.OptionGroup;
-import org.apache.commons.cli.Options;
-
-public class ConfigCommand extends Command {
-  private Option tableOpt, deleteOpt, setOpt, filterOpt, disablePaginationOpt, outputFileOpt, namespaceOpt;
-
-  private int COL1 = 10, COL2 = 7;
-  private ConsoleReader reader;
-
-  @Override
-  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> completionSet) {
-    final Token cmd = new Token(getName());
-    final Token sub = new Token("-" + setOpt.getOpt());
-    for (Property p : Property.values()) {
-      if (!(p.getKey().endsWith(".")) && !p.isExperimental()) {
-        sub.addSubcommand(new Token(p.toString()));
-      }
-    }
-    cmd.addSubcommand(sub);
-    root.addSubcommand(cmd);
-  }
-
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException,
-      TableNotFoundException, IOException, ClassNotFoundException, NamespaceNotFoundException {
-    reader = shellState.getReader();
-
-    final String tableName = cl.getOptionValue(tableOpt.getOpt());
-    if (tableName != null && !shellState.getConnector().tableOperations().exists(tableName)) {
-      throw new TableNotFoundException(null, tableName, null);
-    }
-    final String namespace = cl.getOptionValue(namespaceOpt.getOpt());
-    if (namespace != null && !shellState.getConnector().namespaceOperations().exists(namespace)) {
-      throw new NamespaceNotFoundException(null, namespace, null);
-    }
-    if (cl.hasOption(deleteOpt.getOpt())) {
-      // delete property from table
-      String property = cl.getOptionValue(deleteOpt.getOpt());
-      if (property.contains("=")) {
-        throw new BadArgumentException("Invalid '=' operator in delete operation.", fullCommand, fullCommand.indexOf('='));
-      }
-      if (tableName != null) {
-        if (!Property.isValidTablePropertyKey(property)) {
-          Shell.log.warn("Invalid per-table property : " + property + ", still removing from zookeeper if it's there.");
-        }
-        shellState.getConnector().tableOperations().removeProperty(tableName, property);
-        Shell.log.debug("Successfully deleted table configuration option.");
-      } else if (namespace != null) {
-        if (!Property.isValidTablePropertyKey(property)) {
-          Shell.log.warn("Invalid per-table property : " + property + ", still removing from zookeeper if it's there.");
-        }
-        shellState.getConnector().namespaceOperations().removeProperty(namespace, property);
-        Shell.log.debug("Successfully deleted namespace configuration option.");
-      } else {
-        if (!Property.isValidZooPropertyKey(property)) {
-          Shell.log.warn("Invalid per-table property : " + property + ", still removing from zookeeper if it's there.");
-        }
-        shellState.getConnector().instanceOperations().removeProperty(property);
-        Shell.log.debug("Successfully deleted system configuration option");
-      }
-    } else if (cl.hasOption(setOpt.getOpt())) {
-      // set property on table
-      String property = cl.getOptionValue(setOpt.getOpt()), value = null;
-      if (!property.contains("=")) {
-        throw new BadArgumentException("Missing '=' operator in set operation.", fullCommand, fullCommand.indexOf(property));
-      }
-      final String pair[] = property.split("=", 2);
-      property = pair[0];
-      value = pair[1];
-
-      if (tableName != null) {
-        if (!Property.isValidTablePropertyKey(property)) {
-          throw new BadArgumentException("Invalid per-table property.", fullCommand, fullCommand.indexOf(property));
-        }
-        if (property.equals(Property.TABLE_DEFAULT_SCANTIME_VISIBILITY.getKey())) {
-          new ColumnVisibility(value); // validate that it is a valid expression
-        }
-        shellState.getConnector().tableOperations().setProperty(tableName, property, value);
-        Shell.log.debug("Successfully set table configuration option.");
-      } else if (namespace != null) {
-        if (!Property.isValidTablePropertyKey(property)) {
-          throw new BadArgumentException("Invalid per-table property.", fullCommand, fullCommand.indexOf(property));
-        }
-        if (property.equals(Property.TABLE_DEFAULT_SCANTIME_VISIBILITY.getKey())) {
-          new ColumnVisibility(value); // validate that it is a valid expression
-        }
-        shellState.getConnector().namespaceOperations().setProperty(namespace, property, value);
-        Shell.log.debug("Successfully set table configuration option.");
-      } else {
-        if (!Property.isValidZooPropertyKey(property)) {
-          throw new BadArgumentException("Property cannot be modified in zookeeper", fullCommand, fullCommand.indexOf(property));
-        }
-        shellState.getConnector().instanceOperations().setProperty(property, value);
-        Shell.log.debug("Successfully set system configuration option");
-      }
-    } else {
-      // display properties
-      final TreeMap<String,String> systemConfig = new TreeMap<String,String>();
-      systemConfig.putAll(shellState.getConnector().instanceOperations().getSystemConfiguration());
-
-      final String outputFile = cl.getOptionValue(outputFileOpt.getOpt());
-      final PrintFile printFile = outputFile == null ? null : new PrintFile(outputFile);
-
-      final TreeMap<String,String> siteConfig = new TreeMap<String,String>();
-      siteConfig.putAll(shellState.getConnector().instanceOperations().getSiteConfiguration());
-
-      final TreeMap<String,String> defaults = new TreeMap<String,String>();
-      for (Entry<String,String> defaultEntry : AccumuloConfiguration.getDefaultConfiguration()) {
-        defaults.put(defaultEntry.getKey(), defaultEntry.getValue());
-      }
-
-      final TreeMap<String,String> namespaceConfig = new TreeMap<String,String>();
-      if (tableName != null) {
-        String n = Namespaces.getNamespaceName(shellState.getInstance(),
-            Tables.getNamespaceId(shellState.getInstance(), Tables.getTableId(shellState.getInstance(), tableName)));
-        for (Entry<String,String> e : shellState.getConnector().namespaceOperations().getProperties(n)) {
-          namespaceConfig.put(e.getKey(), e.getValue());
-        }
-      }
-
-      Iterable<Entry<String,String>> acuconf = shellState.getConnector().instanceOperations().getSystemConfiguration().entrySet();
-      if (tableName != null) {
-        acuconf = shellState.getConnector().tableOperations().getProperties(tableName);
-      } else if (namespace != null) {
-        acuconf = shellState.getConnector().namespaceOperations().getProperties(namespace);
-      }
-      final TreeMap<String,String> sortedConf = new TreeMap<String,String>();
-      for (Entry<String,String> propEntry : acuconf) {
-        sortedConf.put(propEntry.getKey(), propEntry.getValue());
-      }
-
-      for (Entry<String,String> propEntry : acuconf) {
-        final String key = propEntry.getKey();
-        // only show properties with similar names to that
-        // specified, or all of them if none specified
-        if (cl.hasOption(filterOpt.getOpt()) && !key.contains(cl.getOptionValue(filterOpt.getOpt()))) {
-          continue;
-        }
-        if ((tableName != null || namespace != null) && !Property.isValidTablePropertyKey(key)) {
-          continue;
-        }
-        COL2 = Math.max(COL2, propEntry.getKey().length() + 3);
-      }
-
-      final ArrayList<String> output = new ArrayList<String>();
-      printConfHeader(output);
-
-      for (Entry<String,String> propEntry : sortedConf.entrySet()) {
-        final String key = propEntry.getKey();
-
-        // only show properties with similar names to that
-        // specified, or all of them if none specified
-        if (cl.hasOption(filterOpt.getOpt()) && !key.contains(cl.getOptionValue(filterOpt.getOpt()))) {
-          continue;
-        }
-        if ((tableName != null || namespace != null) && !Property.isValidTablePropertyKey(key)) {
-          continue;
-        }
-        String siteVal = siteConfig.get(key);
-        String sysVal = systemConfig.get(key);
-        String curVal = propEntry.getValue();
-        String dfault = defaults.get(key);
-        String nspVal = namespaceConfig.get(key);
-        boolean printed = false;
-
-        if (dfault != null && key.toLowerCase().contains("password")) {
-          siteVal = sysVal = dfault = curVal = curVal.replaceAll(".", "*");
-        }
-        if (sysVal != null) {
-          if (defaults.containsKey(key) && !Property.getPropertyByKey(key).isExperimental()) {
-            printConfLine(output, "default", key, dfault);
-            printed = true;
-          }
-          if (!defaults.containsKey(key) || !defaults.get(key).equals(siteVal)) {
-            printConfLine(output, "site", printed ? "   @override" : key, siteVal == null ? "" : siteVal);
-            printed = true;
-          }
-          if (!siteConfig.containsKey(key) || !siteVal.equals(sysVal)) {
-            printConfLine(output, "system", printed ? "   @override" : key, sysVal == null ? "" : sysVal);
-            printed = true;
-          }
-
-        }
-        if (nspVal != null) {
-          if (!systemConfig.containsKey(key) || !sysVal.equals(nspVal)) {
-            printConfLine(output, "namespace", printed ? "   @override" : key, nspVal == null ? "" : nspVal);
-            printed = true;
-          }
-        }
-
-        // show per-table value only if it is different (overridden)
-        if (tableName != null && !curVal.equals(nspVal)) {
-          printConfLine(output, "table", printed ? "   @override" : key, curVal);
-        } else if (namespace != null && !curVal.equals(sysVal)) {
-          printConfLine(output, "namespace", printed ? "   @override" : key, curVal);
-        }
-      }
-      printConfFooter(output);
-      shellState.printLines(output.iterator(), !cl.hasOption(disablePaginationOpt.getOpt()), printFile);
-      if (printFile != null) {
-        printFile.close();
-      }
-    }
-    return 0;
-  }
-
-  private void printConfHeader(List<String> output) {
-    printConfFooter(output);
-    output.add(String.format("%-" + COL1 + "s | %-" + COL2 + "s | %s", "SCOPE", "NAME", "VALUE"));
-    printConfFooter(output);
-  }
-
-  private void printConfLine(List<String> output, String s1, String s2, String s3) {
-    if (s2.length() < COL2) {
-      s2 += " " + Shell.repeat(".", COL2 - s2.length() - 1);
-    }
-    output.add(String.format("%-" + COL1 + "s | %-" + COL2 + "s | %s", s1, s2,
-        s3.replace("\n", "\n" + Shell.repeat(" ", COL1 + 1) + "|" + Shell.repeat(" ", COL2 + 2) + "|" + " ")));
-  }
-
-  private void printConfFooter(List<String> output) {
-    int col3 = Math.max(1, Math.min(Integer.MAX_VALUE, reader.getTerminal().getWidth() - COL1 - COL2 - 6));
-    output.add(String.format("%" + COL1 + "s-+-%" + COL2 + "s-+-%-" + col3 + "s", Shell.repeat("-", COL1), Shell.repeat("-", COL2), Shell.repeat("-", col3)));
-  }
-
-  @Override
-  public String description() {
-    return "prints system properties and table specific properties";
-  }
-
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-    final OptionGroup og = new OptionGroup();
-    final OptionGroup tgroup = new OptionGroup();
-
-    tableOpt = new Option(Shell.tableOption, "table", true, "table to display/set/delete properties for");
-    deleteOpt = new Option("d", "delete", true, "delete a per-table property");
-    setOpt = new Option("s", "set", true, "set a per-table property");
-    filterOpt = new Option("f", "filter", true, "show only properties that contain this string");
-    disablePaginationOpt = new Option("np", "no-pagination", false, "disables pagination of output");
-    outputFileOpt = new Option("o", "output", true, "local file to write the scan output to");
-    namespaceOpt = new Option(Shell.namespaceOption, "namespace", true, "namespace to display/set/delete properties for");
-
-    tableOpt.setArgName("table");
-    deleteOpt.setArgName("property");
-    setOpt.setArgName("property=value");
-    filterOpt.setArgName("string");
-    outputFileOpt.setArgName("file");
-    namespaceOpt.setArgName("namespace");
-
-    og.addOption(deleteOpt);
-    og.addOption(setOpt);
-    og.addOption(filterOpt);
-
-    tgroup.addOption(tableOpt);
-    tgroup.addOption(namespaceOpt);
-
-    o.addOptionGroup(tgroup);
-    o.addOptionGroup(og);
-    o.addOption(disablePaginationOpt);
-    o.addOption(outputFileOpt);
-
-    return o;
-  }
-
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ConstraintCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ConstraintCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ConstraintCommand.java
deleted file mode 100644
index 208ac4a..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ConstraintCommand.java
+++ /dev/null
@@ -1,134 +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.accumulo.core.util.shell.commands;
-
-import java.util.Map.Entry;
-
-import org.apache.accumulo.core.constraints.Constraint;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.accumulo.core.util.shell.ShellCommandException;
-import org.apache.accumulo.core.util.shell.ShellCommandException.ErrorCode;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.OptionGroup;
-import org.apache.commons.cli.Options;
-
-public class ConstraintCommand extends Command {
-  protected Option namespaceOpt;
-
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    final String tableName;
-    final String namespace;
-
-    if (cl.hasOption(namespaceOpt.getOpt())) {
-      namespace = cl.getOptionValue(namespaceOpt.getOpt());
-    } else {
-      namespace = null;
-    }
-
-    if (cl.hasOption(OptUtil.tableOpt().getOpt()) || !shellState.getTableName().isEmpty()) {
-      tableName = OptUtil.getTableOpt(cl, shellState);
-    } else {
-      tableName = null;
-    }
-
-    int i;
-    switch (OptUtil.getAldOpt(cl)) {
-      case ADD:
-        for (String constraint : cl.getArgs()) {
-          if (namespace != null) {
-            if (!shellState.getConnector().namespaceOperations().testClassLoad(namespace, constraint, Constraint.class.getName())) {
-              throw new ShellCommandException(ErrorCode.INITIALIZATION_FAILURE, "Servers are unable to load " + constraint + " as type "
-                  + Constraint.class.getName());
-            }
-            i = shellState.getConnector().namespaceOperations().addConstraint(namespace, constraint);
-            shellState.getReader().println("Added constraint " + constraint + " to namespace " + namespace + " with number " + i);
-          } else if (tableName != null && !tableName.isEmpty()) {
-            if (!shellState.getConnector().tableOperations().testClassLoad(tableName, constraint, Constraint.class.getName())) {
-              throw new ShellCommandException(ErrorCode.INITIALIZATION_FAILURE, "Servers are unable to load " + constraint + " as type "
-                  + Constraint.class.getName());
-            }
-            i = shellState.getConnector().tableOperations().addConstraint(tableName, constraint);
-            shellState.getReader().println("Added constraint " + constraint + " to table " + tableName + " with number " + i);
-          } else {
-            throw new IllegalArgumentException("Please specify either a table or a namespace");
-          }
-        }
-        break;
-      case DELETE:
-        for (String constraint : cl.getArgs()) {
-          i = Integer.parseInt(constraint);
-          if (namespace != null) {
-            shellState.getConnector().namespaceOperations().removeConstraint(namespace, i);
-            shellState.getReader().println("Removed constraint " + i + " from namespace " + namespace);
-          } else if (tableName != null) {
-            shellState.getConnector().tableOperations().removeConstraint(tableName, i);
-            shellState.getReader().println("Removed constraint " + i + " from table " + tableName);
-          } else {
-            throw new IllegalArgumentException("Please specify either a table or a namespace");
-          }
-        }
-        break;
-      case LIST:
-        if (namespace != null) {
-          for (Entry<String,Integer> property : shellState.getConnector().namespaceOperations().listConstraints(namespace).entrySet()) {
-            shellState.getReader().println(property.toString());
-          }
-        } else if (tableName != null) {
-          for (Entry<String,Integer> property : shellState.getConnector().tableOperations().listConstraints(tableName).entrySet()) {
-            shellState.getReader().println(property.toString());
-          }
-        } else {
-          throw new IllegalArgumentException("Please specify either a table or a namespace");
-        }
-    }
-
-    return 0;
-  }
-
-  @Override
-  public String description() {
-    return "adds, deletes, or lists constraints for a table";
-  }
-
-  @Override
-  public int numArgs() {
-    return Shell.NO_FIXED_ARG_LENGTH_CHECK;
-  }
-
-  @Override
-  public String usage() {
-    return getName() + " <constraint>{ <constraint>}";
-  }
-
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-    o.addOptionGroup(OptUtil.addListDeleteGroup("constraint"));
-
-    OptionGroup grp = new OptionGroup();
-    grp.addOption(OptUtil.tableOpt("table to add, delete, or list constraints for"));
-    namespaceOpt = new Option(Shell.namespaceOption, "namespace", true, "name of a namespace to operate on");
-    namespaceOpt.setArgName("namespace");
-    grp.addOption(namespaceOpt);
-
-    o.addOptionGroup(grp);
-    return o;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/CreateNamespaceCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/CreateNamespaceCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/CreateNamespaceCommand.java
deleted file mode 100644
index a9f3deb..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/CreateNamespaceCommand.java
+++ /dev/null
@@ -1,99 +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.accumulo.core.util.shell.commands;
-
-import java.io.IOException;
-import java.util.Map.Entry;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.NamespaceExistsException;
-import org.apache.accumulo.core.client.NamespaceNotFoundException;
-import org.apache.accumulo.core.client.TableExistsException;
-import org.apache.accumulo.core.client.TableNotFoundException;
-import org.apache.accumulo.core.conf.Property;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.OptionGroup;
-import org.apache.commons.cli.Options;
-
-public class CreateNamespaceCommand extends Command {
-  private Option createNamespaceOptCopyConfig;
-
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException,
-      TableExistsException, TableNotFoundException, IOException, ClassNotFoundException, NamespaceExistsException, NamespaceNotFoundException {
-
-    if (createNamespaceOptCopyConfig == null) {
-      getOptions();
-    }
-
-    String namespace = cl.getArgs()[0];
-
-    shellState.getConnector().namespaceOperations().create(namespace);
-
-    // Copy options if flag was set
-    Iterable<Entry<String,String>> configuration = null;
-    if (cl.hasOption(createNamespaceOptCopyConfig.getOpt())) {
-      String copy = cl.getOptionValue(createNamespaceOptCopyConfig.getOpt());
-      if (shellState.getConnector().namespaceOperations().exists(namespace)) {
-        configuration = shellState.getConnector().namespaceOperations().getProperties(copy);
-      }
-    } 
-    if (configuration != null) {
-      for (Entry<String,String> entry : configuration) {
-        if (Property.isValidTablePropertyKey(entry.getKey())) {
-          shellState.getConnector().namespaceOperations().setProperty(namespace, entry.getKey(), entry.getValue());
-        }
-      }
-    }
-
-    return 0;
-  }
-
-  @Override
-  public String description() {
-    return "creates a new namespace";
-  }
-
-  @Override
-  public String usage() {
-    return getName() + " <namespaceName>";
-  }
-
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-
-    createNamespaceOptCopyConfig = new Option("cc", "copy-config", true, "namespace to copy configuration from");
-    createNamespaceOptCopyConfig.setArgName("namespace");
-
-    OptionGroup ogp = new OptionGroup();
-    ogp.addOption(createNamespaceOptCopyConfig);
-
-    o.addOptionGroup(ogp);
-
-    return o;
-  }
-
-  @Override
-  public int numArgs() {
-    return 1;
-  }
-}


[22/53] [abbrv] Revert "ACCUMULO-1897 Move shell into new package and module"

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/RevokeCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/RevokeCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/RevokeCommand.java
deleted file mode 100644
index 373c0b0..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/RevokeCommand.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.accumulo.shell.commands;
-
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.accumulo.core.security.NamespacePermission;
-import org.apache.accumulo.core.security.SystemPermission;
-import org.apache.accumulo.core.security.TablePermission;
-import org.apache.accumulo.core.util.BadArgumentException;
-import org.apache.accumulo.shell.Shell;
-import org.apache.accumulo.shell.Token;
-import org.apache.accumulo.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.OptionGroup;
-import org.apache.commons.cli.Options;
-
-public class RevokeCommand extends TableOperation {
-  {
-    disableUnflaggedTableOptions();
-  }
-
-  private Option systemOpt, userOpt;
-  private String user;
-  private String[] permission;
-
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    user = cl.hasOption(userOpt.getOpt()) ? cl.getOptionValue(userOpt.getOpt()) : shellState.getConnector().whoami();
-
-    permission = cl.getArgs()[0].split("\\.", 2);
-    if (cl.hasOption(systemOpt.getOpt()) && permission[0].equalsIgnoreCase("System")) {
-      try {
-        shellState.getConnector().securityOperations().revokeSystemPermission(user, SystemPermission.valueOf(permission[1]));
-        Shell.log.debug("Revoked from " + user + " the " + permission[1] + " permission");
-      } catch (IllegalArgumentException e) {
-        throw new BadArgumentException("No such system permission", fullCommand, fullCommand.indexOf(cl.getArgs()[0]));
-      }
-    } else if (permission[0].equalsIgnoreCase("Table")) {
-      super.execute(fullCommand, cl, shellState);
-    } else if (permission[0].equalsIgnoreCase("Namespace")) {
-      if (cl.hasOption(optNamespace.getOpt())) {
-        try {
-          shellState.getConnector().securityOperations()
-              .revokeNamespacePermission(user, cl.getOptionValue(optNamespace.getOpt()), NamespacePermission.valueOf(permission[1]));
-        } catch (IllegalArgumentException e) {
-          throw new BadArgumentException("No such namespace permission", fullCommand, fullCommand.indexOf(cl.getArgs()[0]));
-        }
-      } else {
-        throw new BadArgumentException("No namespace specified to apply permission to", fullCommand, fullCommand.indexOf(cl.getArgs()[0]));
-      }
-    } else {
-      throw new BadArgumentException("Unrecognized permission", fullCommand, fullCommand.indexOf(cl.getArgs()[0]));
-    }
-    return 0;
-  }
-
-  @Override
-  protected void doTableOp(final Shell shellState, final String tableName) throws Exception {
-    try {
-      shellState.getConnector().securityOperations().revokeTablePermission(user, tableName, TablePermission.valueOf(permission[1]));
-      Shell.log.debug("Revoked from " + user + " the " + permission[1] + " permission on table " + tableName);
-    } catch (IllegalArgumentException e) {
-      throw new IllegalArgumentException("No such table permission", e);
-    }
-  }
-
-  @Override
-  public String description() {
-    return "revokes system or table permissions from a user";
-  }
-
-  @Override
-  public String usage() {
-    return getName() + " <permission>";
-  }
-
-  @Override
-  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> completionSet) {
-    final Token cmd = new Token(getName());
-    cmd.addSubcommand(new Token(TablePermission.printableValues()));
-    cmd.addSubcommand(new Token(SystemPermission.printableValues()));
-    cmd.addSubcommand(new Token(NamespacePermission.printableValues()));
-    root.addSubcommand(cmd);
-  }
-
-  @Override
-  public Options getOptions() {
-    super.getOptions();
-    final Options o = new Options();
-
-    final OptionGroup group = new OptionGroup();
-
-    systemOpt = new Option("s", "system", false, "revoke a system permission");
-
-    optNamespace = new Option(Shell.namespaceOption, "namespace", true, "name of a namespace to operate on");
-    optNamespace.setArgName("namespace");
-
-    group.addOption(systemOpt);
-    group.addOption(optTableName);
-    group.addOption(optTablePattern);
-    group.addOption(optNamespace);
-
-    o.addOptionGroup(group);
-    userOpt = new Option(Shell.userOption, "user", true, "user to operate on");
-    userOpt.setArgName("username");
-    userOpt.setRequired(true);
-    o.addOption(userOpt);
-
-    return o;
-  }
-
-  @Override
-  public int numArgs() {
-    return 1;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/ScanCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/ScanCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/ScanCommand.java
deleted file mode 100644
index 37a33a4..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/ScanCommand.java
+++ /dev/null
@@ -1,334 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.accumulo.shell.commands;
-
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.util.List;
-import java.util.Map.Entry;
-import java.util.concurrent.TimeUnit;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.IteratorSetting;
-import org.apache.accumulo.core.client.Scanner;
-import org.apache.accumulo.core.client.ScannerBase;
-import org.apache.accumulo.core.conf.AccumuloConfiguration;
-import org.apache.accumulo.core.data.Key;
-import org.apache.accumulo.core.data.Range;
-import org.apache.accumulo.core.data.Value;
-import org.apache.accumulo.core.security.Authorizations;
-import org.apache.accumulo.core.util.format.BinaryFormatter;
-import org.apache.accumulo.core.util.format.Formatter;
-import org.apache.accumulo.core.util.interpret.DefaultScanInterpreter;
-import org.apache.accumulo.core.util.interpret.ScanInterpreter;
-import org.apache.accumulo.shell.Shell;
-import org.apache.accumulo.shell.Shell.Command;
-import org.apache.accumulo.shell.Shell.PrintFile;
-import org.apache.accumulo.start.classloader.vfs.AccumuloVFSClassLoader;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-import org.apache.hadoop.io.Text;
-
-public class ScanCommand extends Command {
-  
-  private Option scanOptAuths, scanOptRow, scanOptColumns, disablePaginationOpt, showFewOpt, formatterOpt, interpreterOpt, formatterInterpeterOpt,
-      outputFileOpt;
-  
-  protected Option timestampOpt;
-  private Option optStartRowExclusive;
-  private Option optEndRowExclusive;
-  private Option timeoutOption;
-  private Option profileOpt;
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    final PrintFile printFile = getOutputFile(cl);
-    final String tableName = OptUtil.getTableOpt(cl, shellState);
-    
-    final Class<? extends Formatter> formatter = getFormatter(cl, tableName, shellState);
-    final ScanInterpreter interpeter = getInterpreter(cl, tableName, shellState);
-    
-    // handle first argument, if present, the authorizations list to
-    // scan with
-    final Authorizations auths = getAuths(cl, shellState);
-    final Scanner scanner = shellState.getConnector().createScanner(tableName, auths);
-    
-    // handle session-specific scan iterators
-    addScanIterators(shellState, cl, scanner, tableName);
-    
-    // handle remaining optional arguments
-    scanner.setRange(getRange(cl, interpeter));
-    
-    // handle columns
-    fetchColumns(cl, scanner, interpeter);
-    
-    // set timeout
-    scanner.setTimeout(getTimeout(cl), TimeUnit.MILLISECONDS);
-    
-    // output the records
-    if (cl.hasOption(showFewOpt.getOpt())) {
-      final String showLength = cl.getOptionValue(showFewOpt.getOpt());
-      try {
-        final int length = Integer.parseInt(showLength);
-        if (length < 1) {
-          throw new IllegalArgumentException();
-        }
-        BinaryFormatter.getlength(length);
-        printBinaryRecords(cl, shellState, scanner, printFile);
-      } catch (NumberFormatException nfe) {
-        shellState.getReader().println("Arg must be an integer.");
-      } catch (IllegalArgumentException iae) {
-        shellState.getReader().println("Arg must be greater than one.");
-      }
-      
-    } else {
-      printRecords(cl, shellState, scanner, formatter, printFile);
-    }
-    if (printFile != null) {
-      printFile.close();
-    }
-    
-    return 0;
-  }
-  
-  protected long getTimeout(final CommandLine cl) {
-    if (cl.hasOption(timeoutOption.getLongOpt())) {
-      return AccumuloConfiguration.getTimeInMillis(cl.getOptionValue(timeoutOption.getLongOpt()));
-    }
-    
-    return Long.MAX_VALUE;
-  }
-  
-  protected void addScanIterators(final Shell shellState, CommandLine cl, final Scanner scanner, final String tableName) {
-    
-    List<IteratorSetting> tableScanIterators;
-    if (cl.hasOption(profileOpt.getOpt())) {
-      String profile = cl.getOptionValue(profileOpt.getOpt());
-      tableScanIterators = shellState.iteratorProfiles.get(profile);
-      
-      if (tableScanIterators == null) {
-        throw new IllegalArgumentException("Profile " + profile + " does not exist");
-      }
-    } else {
-      tableScanIterators = shellState.scanIteratorOptions.get(tableName);
-      if (tableScanIterators == null) {
-        Shell.log.debug("Found no scan iterators to set");
-        return;
-      }
-    }
-    
-    Shell.log.debug("Found " + tableScanIterators.size() + " scan iterators to set");
-    
-    for (IteratorSetting setting : tableScanIterators) {
-      Shell.log.debug("Setting scan iterator " + setting.getName() + " at priority " + setting.getPriority() + " using class name "
-          + setting.getIteratorClass());
-      for (Entry<String,String> option : setting.getOptions().entrySet()) {
-        Shell.log.debug("Setting option for " + setting.getName() + ": " + option.getKey() + "=" + option.getValue());
-      }
-      scanner.addScanIterator(setting);
-    }
-  }
-  
-  protected void printRecords(final CommandLine cl, final Shell shellState, final Iterable<Entry<Key,Value>> scanner, final Class<? extends Formatter> formatter)
-      throws IOException {
-    printRecords(cl, shellState, scanner, formatter, null);
-  }
-  
-  protected void printRecords(final CommandLine cl, final Shell shellState, final Iterable<Entry<Key,Value>> scanner,
-      final Class<? extends Formatter> formatter, PrintFile outFile) throws IOException {
-    if (outFile == null) {
-      shellState.printRecords(scanner, cl.hasOption(timestampOpt.getOpt()), !cl.hasOption(disablePaginationOpt.getOpt()), formatter);
-    } else {
-      shellState.printRecords(scanner, cl.hasOption(timestampOpt.getOpt()), !cl.hasOption(disablePaginationOpt.getOpt()), formatter, outFile);
-    }
-  }
-  
-  protected void printBinaryRecords(final CommandLine cl, final Shell shellState, final Iterable<Entry<Key,Value>> scanner) throws IOException {
-    printBinaryRecords(cl, shellState, scanner, null);
-  }
-  
-  protected void printBinaryRecords(final CommandLine cl, final Shell shellState, final Iterable<Entry<Key,Value>> scanner, PrintFile outFile)
-      throws IOException {
-    if (outFile == null) {
-      shellState.printBinaryRecords(scanner, cl.hasOption(timestampOpt.getOpt()), !cl.hasOption(disablePaginationOpt.getOpt()));
-    } else {
-      shellState.printBinaryRecords(scanner, cl.hasOption(timestampOpt.getOpt()), !cl.hasOption(disablePaginationOpt.getOpt()), outFile);
-    }
-  }
-  
-  protected ScanInterpreter getInterpreter(final CommandLine cl, final String tableName, final Shell shellState) throws Exception {
-    
-    Class<? extends ScanInterpreter> clazz = null;
-    try {
-      if (cl.hasOption(interpreterOpt.getOpt())) {
-        clazz = AccumuloVFSClassLoader.loadClass(cl.getOptionValue(interpreterOpt.getOpt()), ScanInterpreter.class);
-      } else if (cl.hasOption(formatterInterpeterOpt.getOpt())) {
-        clazz = AccumuloVFSClassLoader.loadClass(cl.getOptionValue(formatterInterpeterOpt.getOpt()), ScanInterpreter.class);
-      }
-    } catch (ClassNotFoundException e) {
-      shellState.getReader().println("Interpreter class could not be loaded.\n" + e.getMessage());
-    }
-    
-    if (clazz == null)
-      clazz = InterpreterCommand.getCurrentInterpreter(tableName, shellState);
-    
-    if (clazz == null)
-      clazz = DefaultScanInterpreter.class;
-    
-    return clazz.newInstance();
-  }
-  
-  protected Class<? extends Formatter> getFormatter(final CommandLine cl, final String tableName, final Shell shellState) throws IOException {
-    
-    try {
-      if (cl.hasOption(formatterOpt.getOpt())) {
-        return AccumuloVFSClassLoader.loadClass(cl.getOptionValue(formatterOpt.getOpt()), Formatter.class);
-        
-      } else if (cl.hasOption(formatterInterpeterOpt.getOpt())) {
-        return AccumuloVFSClassLoader.loadClass(cl.getOptionValue(formatterInterpeterOpt.getOpt()), Formatter.class);
-      }
-    } catch (ClassNotFoundException e) {
-      shellState.getReader().println("Formatter class could not be loaded.\n" + e.getMessage());
-    }
-    
-    return shellState.getFormatter(tableName);
-  }
-  
-  protected void fetchColumns(final CommandLine cl, final ScannerBase scanner, final ScanInterpreter formatter) throws UnsupportedEncodingException {
-    if (cl.hasOption(scanOptColumns.getOpt())) {
-      for (String a : cl.getOptionValue(scanOptColumns.getOpt()).split(",")) {
-        final String sa[] = a.split(":", 2);
-        if (sa.length == 1) {
-          scanner.fetchColumnFamily(formatter.interpretColumnFamily(new Text(a.getBytes(Shell.CHARSET))));
-        } else {
-          scanner.fetchColumn(formatter.interpretColumnFamily(new Text(sa[0].getBytes(Shell.CHARSET))),
-              formatter.interpretColumnQualifier(new Text(sa[1].getBytes(Shell.CHARSET))));
-        }
-      }
-    }
-  }
-  
-  protected Range getRange(final CommandLine cl, final ScanInterpreter formatter) throws UnsupportedEncodingException {
-    if ((cl.hasOption(OptUtil.START_ROW_OPT) || cl.hasOption(OptUtil.END_ROW_OPT)) && cl.hasOption(scanOptRow.getOpt())) {
-      // did not see a way to make commons cli do this check... it has mutually exclusive options but does not support the or
-      throw new IllegalArgumentException("Options -" + scanOptRow.getOpt() + " AND (-" + OptUtil.START_ROW_OPT + " OR -" + OptUtil.END_ROW_OPT
-          + ") are mutally exclusive ");
-    }
-    
-    if (cl.hasOption(scanOptRow.getOpt())) {
-      return new Range(formatter.interpretRow(new Text(cl.getOptionValue(scanOptRow.getOpt()).getBytes(Shell.CHARSET))));
-    } else {
-      Text startRow = OptUtil.getStartRow(cl);
-      if (startRow != null)
-        startRow = formatter.interpretBeginRow(startRow);
-      Text endRow = OptUtil.getEndRow(cl);
-      if (endRow != null)
-        endRow = formatter.interpretEndRow(endRow);
-      final boolean startInclusive = !cl.hasOption(optStartRowExclusive.getOpt());
-      final boolean endInclusive = !cl.hasOption(optEndRowExclusive.getOpt());
-      return new Range(startRow, startInclusive, endRow, endInclusive);
-    }
-  }
-  
-  protected Authorizations getAuths(final CommandLine cl, final Shell shellState) throws AccumuloSecurityException, AccumuloException {
-    final String user = shellState.getConnector().whoami();
-    Authorizations auths = shellState.getConnector().securityOperations().getUserAuthorizations(user);
-    if (cl.hasOption(scanOptAuths.getOpt())) {
-      auths = ScanCommand.parseAuthorizations(cl.getOptionValue(scanOptAuths.getOpt()));
-    }
-    return auths;
-  }
-  
-  static Authorizations parseAuthorizations(final String field) {
-    if (field == null || field.isEmpty()) {
-      return Authorizations.EMPTY;
-    }
-    return new Authorizations(field.split(","));
-  }
-  
-  @Override
-  public String description() {
-    return "scans the table, and displays the resulting records";
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-    
-    scanOptAuths = new Option("s", "scan-authorizations", true, "scan authorizations (all user auths are used if this argument is not specified)");
-    optStartRowExclusive = new Option("be", "begin-exclusive", false, "make start row exclusive (by default it's inclusive)");
-    optStartRowExclusive.setArgName("begin-exclusive");
-    optEndRowExclusive = new Option("ee", "end-exclusive", false, "make end row exclusive (by default it's inclusive)");
-    optEndRowExclusive.setArgName("end-exclusive");
-    scanOptRow = new Option("r", "row", true, "row to scan");
-    scanOptColumns = new Option("c", "columns", true, "comma-separated columns");
-    timestampOpt = new Option("st", "show-timestamps", false, "display timestamps");
-    disablePaginationOpt = new Option("np", "no-pagination", false, "disable pagination of output");
-    showFewOpt = new Option("f", "show few", true, "show only a specified number of characters");
-    formatterOpt = new Option("fm", "formatter", true, "fully qualified name of the formatter class to use");
-    interpreterOpt = new Option("i", "interpreter", true, "fully qualified name of the interpreter class to use");
-    formatterInterpeterOpt = new Option("fi", "fmt-interpreter", true, "fully qualified name of a class that is a formatter and interpreter");
-    timeoutOption = new Option(null, "timeout", true,
-        "time before scan should fail if no data is returned. If no unit is given assumes seconds.  Units d,h,m,s,and ms are supported.  e.g. 30s or 100ms");
-    outputFileOpt = new Option("o", "output", true, "local file to write the scan output to");
-    
-    scanOptAuths.setArgName("comma-separated-authorizations");
-    scanOptRow.setArgName("row");
-    scanOptColumns.setArgName("<columnfamily>[:<columnqualifier>]{,<columnfamily>[:<columnqualifier>]}");
-    showFewOpt.setRequired(false);
-    showFewOpt.setArgName("int");
-    formatterOpt.setArgName("className");
-    timeoutOption.setArgName("timeout");
-    outputFileOpt.setArgName("file");
-    
-    profileOpt = new Option("pn", "profile", true, "iterator profile name");
-    profileOpt.setArgName("profile");
-    
-    o.addOption(scanOptAuths);
-    o.addOption(scanOptRow);
-    o.addOption(OptUtil.startRowOpt());
-    o.addOption(OptUtil.endRowOpt());
-    o.addOption(optStartRowExclusive);
-    o.addOption(optEndRowExclusive);
-    o.addOption(scanOptColumns);
-    o.addOption(timestampOpt);
-    o.addOption(disablePaginationOpt);
-    o.addOption(OptUtil.tableOpt("table to be scanned"));
-    o.addOption(showFewOpt);
-    o.addOption(formatterOpt);
-    o.addOption(interpreterOpt);
-    o.addOption(formatterInterpeterOpt);
-    o.addOption(timeoutOption);
-    o.addOption(outputFileOpt);
-    o.addOption(profileOpt);
-    
-    return o;
-  }
-  
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-  
-  protected PrintFile getOutputFile(final CommandLine cl) throws FileNotFoundException {
-    final String outputFile = cl.getOptionValue(outputFileOpt.getOpt());
-    return (outputFile == null ? null : new PrintFile(outputFile));
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/ScriptCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/ScriptCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/ScriptCommand.java
deleted file mode 100644
index 9bd91cc..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/ScriptCommand.java
+++ /dev/null
@@ -1,290 +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.accumulo.shell.commands;
-
-import java.io.File;
-import java.io.FileReader;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.Reader;
-import java.io.Writer;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Set;
-import java.util.TreeSet;
-
-import javax.script.Bindings;
-import javax.script.Compilable;
-import javax.script.CompiledScript;
-import javax.script.Invocable;
-import javax.script.ScriptContext;
-import javax.script.ScriptEngine;
-import javax.script.ScriptEngineFactory;
-import javax.script.ScriptEngineManager;
-import javax.script.ScriptException;
-import javax.script.SimpleScriptContext;
-
-import org.apache.accumulo.shell.Shell;
-import org.apache.accumulo.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.OptionGroup;
-import org.apache.commons.cli.Options;
-
-public class ScriptCommand extends Command {
-  
-  // Command to allow user to run scripts, see JSR-223
-  // http://www.oracle.com/technetwork/articles/javase/scripting-140262.html
-  
-  protected Option list, engine, script, file, args, out, function, object;
-  private static final String DEFAULT_ENGINE = "rhino";
-  
-  public int execute(String fullCommand, CommandLine cl, Shell shellState) throws Exception {
-
-    boolean invoke = false;
-    ScriptEngineManager mgr = new ScriptEngineManager();
-    
-    if (cl.hasOption(list.getOpt())) {
-      listJSREngineInfo(mgr, shellState);
-    } else if (cl.hasOption(file.getOpt()) || cl.hasOption(script.getOpt())) {
-      String engineName = DEFAULT_ENGINE;
-      if (cl.hasOption(engine.getOpt())) {
-        engineName = cl.getOptionValue(engine.getOpt());
-      }
-      ScriptEngine engine = mgr.getEngineByName(engineName);
-      if (null == engine) {
-        shellState.printException(new Exception(engineName + " not found"));
-        return 1;
-      }
-      
-      if (cl.hasOption(object.getOpt()) || cl.hasOption(function.getOpt())) {
-        if (!(engine instanceof Invocable)) {
-          shellState.printException(new Exception(engineName + " does not support invoking functions or methods"));
-          return 1;
-        }
-        invoke = true;
-      }
-      
-      ScriptContext ctx = new SimpleScriptContext();
-      
-      // Put the following objects into the context so that they
-      // are available to the scripts
-      // TODO: What else should go in here?
-      Bindings b = engine.getBindings(ScriptContext.ENGINE_SCOPE);
-      b.put("connection", shellState.getConnector());
-      
-      List<Object> argValues = new ArrayList<Object>();
-      if (cl.hasOption(args.getOpt())) {
-        String[] argList = cl.getOptionValue(args.getOpt()).split(",");
-        for (String arg : argList) {
-          String[] parts = arg.split("=");
-          if (parts.length == 0) {
-            continue;
-          } else if (parts.length == 1) {
-            b.put(parts[0], null);
-            argValues.add(null);
-          } else if (parts.length == 2) {
-            b.put(parts[0], parts[1]);
-            argValues.add(parts[1]);
-          }
-        }
-      }
-      ctx.setBindings(b, ScriptContext.ENGINE_SCOPE);
-      Object[] argArray = argValues.toArray(new Object[argValues.size()]);
-      
-      Writer writer = null;
-      if (cl.hasOption(out.getOpt())) {
-        File f = new File(cl.getOptionValue(out.getOpt()));
-        writer = new FileWriter(f);
-        ctx.setWriter(writer);
-      }
-      
-      if (cl.hasOption(file.getOpt())) {
-        File f = new File(cl.getOptionValue(file.getOpt()));
-        if (!f.exists()) {
-          if (null != writer) {
-            writer.close();
-          }
-          shellState.printException(new Exception(f.getAbsolutePath() + " not found"));
-          return 1;
-        }
-        Reader reader = new FileReader(f);
-        try {
-          engine.eval(reader, ctx);
-          if (invoke) {
-            this.invokeFunctionOrMethod(shellState, engine, cl, argArray);
-          }
-        } catch (ScriptException ex) {
-          shellState.printException(ex);
-          return 1;
-        } finally {
-          reader.close();
-          if (null != writer) {
-            writer.close();
-          }
-        }
-      } else if (cl.hasOption(script.getOpt())) {
-        String inlineScript = cl.getOptionValue(script.getOpt());
-        try {
-          if (engine instanceof Compilable) {
-            Compilable compiledEng = (Compilable) engine;
-            CompiledScript script = compiledEng.compile(inlineScript);
-            script.eval(ctx);
-            if (invoke) {
-              this.invokeFunctionOrMethod(shellState, engine, cl, argArray);
-            }
-          } else {
-            engine.eval(inlineScript, ctx);
-            if (invoke) {
-              this.invokeFunctionOrMethod(shellState, engine, cl, argArray);
-            }
-          }
-        } catch (ScriptException ex) {
-          shellState.printException(ex);
-          return 1;
-        } finally {
-          if (null != writer) {
-            writer.close();
-          }
-        }
-      }
-      if (null != writer) {
-        writer.close();
-      }
-      
-    } else {
-      printHelp(shellState);
-    }
-    return 0;
-  }
-  
-  public String description() {
-    return "execute JSR-223 scripts";
-  }
-  
-  public int numArgs() {
-    return 0;
-  }
-  
-  @Override
-  public String getName() {
-    return "script";
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-    
-    engine = new Option("e", "engine", false, "engine name, defaults to JDK default (Rhino)");
-    engine.setArgName("engineName");
-    engine.setArgs(1);
-    engine.setRequired(false);
-    o.addOption(engine);
-    
-    OptionGroup inputGroup = new OptionGroup();
-    list = new Option("l", "list", false, "list available script engines");
-    inputGroup.addOption(list);
-
-    script = new Option("s", "script", true, "use inline script");
-    script.setArgName("script text");
-    script.setArgs(1);
-    script.setRequired(false);
-    inputGroup.addOption(script);
-    
-    file = new Option("f", "file", true, "use script file");
-    file.setArgName("fileName");
-    file.setArgs(1);
-    file.setRequired(false);
-    
-    inputGroup.addOption(file);
-    inputGroup.setRequired(true);
-    o.addOptionGroup(inputGroup);
-    
-    OptionGroup invokeGroup = new OptionGroup();
-    object = new Option("obj", "object", true, "name of object");
-    object.setArgs(1);
-    object.setArgName("objectName:methodName");
-    object.setRequired(false);
-    invokeGroup.addOption(object);
-    
-    function = new Option("fx", "function", true, "invoke a script function");
-    function.setArgName("functionName");
-    function.setArgs(1);
-    function.setRequired(false);
-    invokeGroup.addOption(function);
-    invokeGroup.setRequired(false);
-    o.addOptionGroup(invokeGroup);
-    
-    args = new Option("a", "args", true, "comma separated list of key=value arguments");
-    args.setArgName("property1=value1,propert2=value2,...");
-    args.setArgs(Option.UNLIMITED_VALUES);
-    args.setRequired(false);
-    o.addOption(args);
-    
-    out = new Option("o", "output", true, "output file");
-    out.setArgName("fileName");
-    out.setArgs(1);
-    out.setRequired(false);
-    o.addOption(out);
-    
-    return o;
-  }
-  
-  private void listJSREngineInfo(ScriptEngineManager mgr, Shell shellState) throws IOException {
-    List<ScriptEngineFactory> factories = mgr.getEngineFactories();
-    Set<String> lines = new TreeSet<String>();
-    for (ScriptEngineFactory factory : factories) {
-      lines.add("ScriptEngineFactory Info");
-      String engName = factory.getEngineName();
-      String engVersion = factory.getEngineVersion();
-      String langName = factory.getLanguageName();
-      String langVersion = factory.getLanguageVersion();
-      lines.add("\tScript Engine: " + engName + " (" + engVersion + ")");
-      List<String> engNames = factory.getNames();
-      for (String name : engNames) {
-        lines.add("\tEngine Alias: " + name);
-      }
-      lines.add("\tLanguage: " + langName + " (" + langVersion + ")");
-    }
-    shellState.printLines(lines.iterator(), true);
-    
-  }
-  
-  private void invokeFunctionOrMethod(Shell shellState, ScriptEngine engine, CommandLine cl, Object[] args) {
-    try {
-      Invocable inv = (Invocable) engine;
-      if (cl.hasOption(function.getOpt())) {
-        inv.invokeFunction(cl.getOptionValue(function.getOpt()), args);
-      } else if (cl.hasOption(object.getOpt())) {
-        String objectMethod = cl.getOptionValue(object.getOpt());
-        String[] parts = objectMethod.split(":");
-        if (!(parts.length == 2)) {
-          shellState.printException(new Exception("Object and Method must be supplied"));
-          return;
-        }
-        String objectName = parts[0];
-        String methodName = parts[1];
-        Object obj = engine.get(objectName);
-        inv.invokeMethod(obj, methodName, args);
-        
-      }
-    } catch (Exception e) {
-      shellState.printException(e);
-    }
-  }
-  
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/SetAuthsCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/SetAuthsCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/SetAuthsCommand.java
deleted file mode 100644
index cc99cbb..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/SetAuthsCommand.java
+++ /dev/null
@@ -1,77 +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.accumulo.shell.commands;
-
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.shell.Shell;
-import org.apache.accumulo.shell.Token;
-import org.apache.accumulo.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.OptionGroup;
-import org.apache.commons.cli.Options;
-
-public class SetAuthsCommand extends Command {
-  private Option userOpt;
-  private Option scanOptAuths;
-  private Option clearOptAuths;
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException {
-    final String user = cl.getOptionValue(userOpt.getOpt(), shellState.getConnector().whoami());
-    final String scanOpts = cl.hasOption(clearOptAuths.getOpt()) ? null : cl.getOptionValue(scanOptAuths.getOpt());
-    shellState.getConnector().securityOperations().changeUserAuthorizations(user, ScanCommand.parseAuthorizations(scanOpts));
-    Shell.log.debug("Changed record-level authorizations for user " + user);
-    return 0;
-  }
-  
-  @Override
-  public String description() {
-    return "sets the maximum scan authorizations for a user";
-  }
-  
-  @Override
-  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> completionSet) {
-    registerCompletionForUsers(root, completionSet);
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-    final OptionGroup setOrClear = new OptionGroup();
-    scanOptAuths = new Option("s", "scan-authorizations", true, "scan authorizations to set");
-    scanOptAuths.setArgName("comma-separated-authorizations");
-    setOrClear.addOption(scanOptAuths);
-    clearOptAuths = new Option("c", "clear-authorizations", false, "clear the scan authorizations");
-    setOrClear.addOption(clearOptAuths);
-    setOrClear.setRequired(true);
-    o.addOptionGroup(setOrClear);
-    userOpt = new Option(Shell.userOption, "user", true, "user to operate on");
-    userOpt.setArgName("user");
-    o.addOption(userOpt);
-    return o;
-  }
-  
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/SetGroupsCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/SetGroupsCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/SetGroupsCommand.java
deleted file mode 100644
index fc8b06e..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/SetGroupsCommand.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.accumulo.shell.commands;
-
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Set;
-
-import org.apache.accumulo.shell.Shell;
-import org.apache.accumulo.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Options;
-import org.apache.hadoop.io.Text;
-
-public class SetGroupsCommand extends Command {
-  @Override
-  public String description() {
-    return "sets the locality groups for a given table (for binary or commas, use Java API)";
-  }
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    final String tableName = OptUtil.getTableOpt(cl, shellState);
-    
-    final HashMap<String,Set<Text>> groups = new HashMap<String,Set<Text>>();
-    
-    for (String arg : cl.getArgs()) {
-      final String sa[] = arg.split("=", 2);
-      if (sa.length < 2) {
-        throw new IllegalArgumentException("Missing '='");
-      }
-      final String group = sa[0];
-      final HashSet<Text> colFams = new HashSet<Text>();
-      
-      for (String family : sa[1].split(",")) {
-        colFams.add(new Text(family.getBytes(Shell.CHARSET)));
-      }
-      
-      groups.put(group, colFams);
-    }
-    
-    shellState.getConnector().tableOperations().setLocalityGroups(tableName, groups);
-    
-    return 0;
-  }
-  
-  @Override
-  public int numArgs() {
-    return Shell.NO_FIXED_ARG_LENGTH_CHECK;
-  }
-  
-  @Override
-  public String usage() {
-    return getName() + " <group>=<col fam>{,<col fam>}{ <group>=<col fam>{,<col fam>}}";
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options opts = new Options();
-    opts.addOption(OptUtil.tableOpt("table to fetch locality groups for"));
-    return opts;
-  }
-  
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/SetIterCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/SetIterCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/SetIterCommand.java
deleted file mode 100644
index a398b3a..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/SetIterCommand.java
+++ /dev/null
@@ -1,453 +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.accumulo.shell.commands;
-
-import java.io.IOException;
-import java.util.EnumSet;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Map.Entry;
-
-import jline.console.ConsoleReader;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.IteratorSetting;
-import org.apache.accumulo.core.client.NamespaceNotFoundException;
-import org.apache.accumulo.core.client.TableNotFoundException;
-import org.apache.accumulo.core.conf.Property;
-import org.apache.accumulo.core.data.Key;
-import org.apache.accumulo.core.data.Value;
-import org.apache.accumulo.core.iterators.IteratorUtil.IteratorScope;
-import org.apache.accumulo.core.iterators.OptionDescriber;
-import org.apache.accumulo.core.iterators.OptionDescriber.IteratorOptions;
-import org.apache.accumulo.core.iterators.SortedKeyValueIterator;
-import org.apache.accumulo.core.iterators.user.AgeOffFilter;
-import org.apache.accumulo.core.iterators.user.RegExFilter;
-import org.apache.accumulo.core.iterators.user.ReqVisFilter;
-import org.apache.accumulo.core.iterators.user.VersioningIterator;
-import org.apache.accumulo.shell.Shell;
-import org.apache.accumulo.shell.ShellCommandException;
-import org.apache.accumulo.shell.Shell.Command;
-import org.apache.accumulo.shell.ShellCommandException.ErrorCode;
-import org.apache.accumulo.start.classloader.vfs.AccumuloVFSClassLoader;
-import org.apache.accumulo.start.classloader.vfs.ContextManager;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.OptionGroup;
-import org.apache.commons.cli.Options;
-import org.apache.commons.lang.StringUtils;
-import org.apache.commons.vfs2.FileSystemException;
-
-public class SetIterCommand extends Command {
-
-  private Option allScopeOpt, mincScopeOpt, majcScopeOpt, scanScopeOpt, nameOpt, priorityOpt;
-  private Option aggTypeOpt, ageoffTypeOpt, regexTypeOpt, versionTypeOpt, reqvisTypeOpt, classnameTypeOpt;
-
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException,
-      TableNotFoundException, IOException, ShellCommandException {
-
-    boolean tables = cl.hasOption(OptUtil.tableOpt().getOpt()) || !shellState.getTableName().isEmpty();
-    boolean namespaces = cl.hasOption(OptUtil.namespaceOpt().getOpt());
-
-    final int priority = Integer.parseInt(cl.getOptionValue(priorityOpt.getOpt()));
-
-    final Map<String,String> options = new HashMap<String,String>();
-    String classname = cl.getOptionValue(classnameTypeOpt.getOpt());
-    if (cl.hasOption(aggTypeOpt.getOpt())) {
-      Shell.log.warn("aggregators are deprecated");
-      @SuppressWarnings("deprecation")
-      String deprecatedClassName = org.apache.accumulo.core.iterators.AggregatingIterator.class.getName();
-      classname = deprecatedClassName;
-    } else if (cl.hasOption(regexTypeOpt.getOpt())) {
-      classname = RegExFilter.class.getName();
-    } else if (cl.hasOption(ageoffTypeOpt.getOpt())) {
-      classname = AgeOffFilter.class.getName();
-    } else if (cl.hasOption(versionTypeOpt.getOpt())) {
-      classname = VersioningIterator.class.getName();
-    } else if (cl.hasOption(reqvisTypeOpt.getOpt())) {
-      classname = ReqVisFilter.class.getName();
-    }
-
-    ClassLoader classloader = getClassLoader(cl, shellState);
-
-    // Get the iterator options, with potentially a name provided by the OptionDescriber impl or through user input
-    String configuredName = setUpOptions(classloader, shellState.getReader(), classname, options);
-
-    // Try to get the name provided by the setiter command
-    String name = cl.getOptionValue(nameOpt.getOpt(), null);
-    
-    // Cannot continue if no name is provided
-    if (null == name && null == configuredName) {
-      throw new IllegalArgumentException("No provided or default name for iterator");
-    } else if (null == name) {
-      // Fall back to the name from OptionDescriber or user input if none is provided on setiter option
-      name = configuredName;
-    }
-
-    if (namespaces) {
-      try {
-        setNamespaceProperties(cl, shellState, priority, options, classname, name);
-      } catch (NamespaceNotFoundException e) {
-        throw new IllegalArgumentException(e);
-      }
-    } else if (tables) {
-      setTableProperties(cl, shellState, priority, options, classname, name);
-    } else {
-      throw new IllegalArgumentException("No table or namespace specified");
-    }
-    return 0;
-  }
-
-  private ClassLoader getClassLoader(final CommandLine cl, final Shell shellState) throws AccumuloException, TableNotFoundException, AccumuloSecurityException,
-      IOException, FileSystemException {
-
-    boolean tables = cl.hasOption(OptUtil.tableOpt().getOpt()) || !shellState.getTableName().isEmpty();
-    boolean namespaces = cl.hasOption(OptUtil.namespaceOpt().getOpt());
-
-    String classpath = null;
-    Iterable<Entry<String,String>> tableProps;
-
-    if (namespaces) {
-      try {
-        tableProps = shellState.getConnector().namespaceOperations().getProperties(OptUtil.getNamespaceOpt(cl, shellState));
-      } catch (NamespaceNotFoundException e) {
-        throw new IllegalArgumentException(e);
-      }
-    } else if (tables) {
-      tableProps = shellState.getConnector().tableOperations().getProperties(OptUtil.getTableOpt(cl, shellState));
-    } else {
-      throw new IllegalArgumentException("No table or namespace specified");
-    }
-    for (Entry<String,String> entry : tableProps) {
-      if (entry.getKey().equals(Property.TABLE_CLASSPATH.getKey())) {
-        classpath = entry.getValue();
-      }
-    }
-
-    ClassLoader classloader;
-
-    if (classpath != null && !classpath.equals("")) {
-      shellState.getConnector().instanceOperations().getSystemConfiguration().get(Property.VFS_CONTEXT_CLASSPATH_PROPERTY.getKey() + classpath);
-
-      try {
-        AccumuloVFSClassLoader.getContextManager().setContextConfig(new ContextManager.DefaultContextsConfig(new Iterable<Map.Entry<String,String>>() {
-          @Override
-          public Iterator<Entry<String,String>> iterator() {
-            try {
-              return shellState.getConnector().instanceOperations().getSystemConfiguration().entrySet().iterator();
-            } catch (AccumuloException e) {
-              throw new RuntimeException(e);
-            } catch (AccumuloSecurityException e) {
-              throw new RuntimeException(e);
-            }
-          }
-        }));
-      } catch (IllegalStateException ise) {}
-
-      classloader = AccumuloVFSClassLoader.getContextManager().getClassLoader(classpath);
-    } else {
-      classloader = AccumuloVFSClassLoader.getClassLoader();
-    }
-    return classloader;
-  }
-
-  protected void setTableProperties(final CommandLine cl, final Shell shellState, final int priority, final Map<String,String> options, final String classname,
-      final String name) throws AccumuloException, AccumuloSecurityException, ShellCommandException, TableNotFoundException {
-    // remove empty values
-
-    final String tableName = OptUtil.getTableOpt(cl, shellState);
-
-    if (!shellState.getConnector().tableOperations().testClassLoad(tableName, classname, SortedKeyValueIterator.class.getName())) {
-      throw new ShellCommandException(ErrorCode.INITIALIZATION_FAILURE, "Servers are unable to load " + classname + " as type "
-          + SortedKeyValueIterator.class.getName());
-    }
-
-    final String aggregatorClass = options.get("aggregatorClass");
-    @SuppressWarnings("deprecation")
-    String deprecatedAggregatorClassName = org.apache.accumulo.core.iterators.aggregation.Aggregator.class.getName();
-    if (aggregatorClass != null && !shellState.getConnector().tableOperations().testClassLoad(tableName, aggregatorClass, deprecatedAggregatorClassName)) {
-      throw new ShellCommandException(ErrorCode.INITIALIZATION_FAILURE, "Servers are unable to load " + aggregatorClass + " as type "
-          + deprecatedAggregatorClassName);
-    }
-
-    for (Iterator<Entry<String,String>> i = options.entrySet().iterator(); i.hasNext();) {
-      final Entry<String,String> entry = i.next();
-      if (entry.getValue() == null || entry.getValue().isEmpty()) {
-        i.remove();
-      }
-    }
-    final EnumSet<IteratorScope> scopes = EnumSet.noneOf(IteratorScope.class);
-    if (cl.hasOption(allScopeOpt.getOpt()) || cl.hasOption(mincScopeOpt.getOpt())) {
-      scopes.add(IteratorScope.minc);
-    }
-    if (cl.hasOption(allScopeOpt.getOpt()) || cl.hasOption(majcScopeOpt.getOpt())) {
-      scopes.add(IteratorScope.majc);
-    }
-    if (cl.hasOption(allScopeOpt.getOpt()) || cl.hasOption(scanScopeOpt.getOpt())) {
-      scopes.add(IteratorScope.scan);
-    }
-    if (scopes.isEmpty()) {
-      throw new IllegalArgumentException("You must select at least one scope to configure");
-    }
-    final IteratorSetting setting = new IteratorSetting(priority, name, classname, options);
-    shellState.getConnector().tableOperations().attachIterator(tableName, setting, scopes);
-  }
-
-  protected void setNamespaceProperties(final CommandLine cl, final Shell shellState, final int priority, final Map<String,String> options,
-      final String classname, final String name) throws AccumuloException, AccumuloSecurityException, ShellCommandException, NamespaceNotFoundException {
-    // remove empty values
-
-    final String namespace = OptUtil.getNamespaceOpt(cl, shellState);
-
-    if (!shellState.getConnector().namespaceOperations().testClassLoad(namespace, classname, SortedKeyValueIterator.class.getName())) {
-      throw new ShellCommandException(ErrorCode.INITIALIZATION_FAILURE, "Servers are unable to load " + classname + " as type "
-          + SortedKeyValueIterator.class.getName());
-    }
-
-    final String aggregatorClass = options.get("aggregatorClass");
-    @SuppressWarnings("deprecation")
-    String deprecatedAggregatorClassName = org.apache.accumulo.core.iterators.aggregation.Aggregator.class.getName();
-    if (aggregatorClass != null && !shellState.getConnector().namespaceOperations().testClassLoad(namespace, aggregatorClass, deprecatedAggregatorClassName)) {
-      throw new ShellCommandException(ErrorCode.INITIALIZATION_FAILURE, "Servers are unable to load " + aggregatorClass + " as type "
-          + deprecatedAggregatorClassName);
-    }
-
-    for (Iterator<Entry<String,String>> i = options.entrySet().iterator(); i.hasNext();) {
-      final Entry<String,String> entry = i.next();
-      if (entry.getValue() == null || entry.getValue().isEmpty()) {
-        i.remove();
-      }
-    }
-    final EnumSet<IteratorScope> scopes = EnumSet.noneOf(IteratorScope.class);
-    if (cl.hasOption(allScopeOpt.getOpt()) || cl.hasOption(mincScopeOpt.getOpt())) {
-      scopes.add(IteratorScope.minc);
-    }
-    if (cl.hasOption(allScopeOpt.getOpt()) || cl.hasOption(majcScopeOpt.getOpt())) {
-      scopes.add(IteratorScope.majc);
-    }
-    if (cl.hasOption(allScopeOpt.getOpt()) || cl.hasOption(scanScopeOpt.getOpt())) {
-      scopes.add(IteratorScope.scan);
-    }
-    if (scopes.isEmpty()) {
-      throw new IllegalArgumentException("You must select at least one scope to configure");
-    }
-    final IteratorSetting setting = new IteratorSetting(priority, name, classname, options);
-    shellState.getConnector().namespaceOperations().attachIterator(namespace, setting, scopes);
-  }
-
-  private static String setUpOptions(ClassLoader classloader, final ConsoleReader reader, final String className, final Map<String,String> options)
-      throws IOException, ShellCommandException {
-    String input;
-    @SuppressWarnings("rawtypes")
-    SortedKeyValueIterator untypedInstance;
-    @SuppressWarnings("rawtypes")
-    Class<? extends SortedKeyValueIterator> clazz;
-    try {
-      clazz = classloader.loadClass(className).asSubclass(SortedKeyValueIterator.class);
-      untypedInstance = clazz.newInstance();
-    } catch (ClassNotFoundException e) {
-      StringBuilder msg = new StringBuilder("Unable to load ").append(className);
-      if (className.indexOf('.') < 0) {
-        msg.append("; did you use a fully qualified package name?");
-      } else {
-        msg.append("; class not found.");
-      }
-      throw new ShellCommandException(ErrorCode.INITIALIZATION_FAILURE, msg.toString());
-    } catch (InstantiationException e) {
-      throw new IllegalArgumentException(e.getMessage());
-    } catch (IllegalAccessException e) {
-      throw new IllegalArgumentException(e.getMessage());
-    } catch (ClassCastException e) {
-      StringBuilder msg = new StringBuilder(50);
-      msg.append(className).append(" loaded successfully but does not implement SortedKeyValueIterator.");
-      msg.append(" This class cannot be used with this command.");
-      throw new ShellCommandException(ErrorCode.INITIALIZATION_FAILURE, msg.toString());
-    }
-
-    @SuppressWarnings("unchecked")
-    SortedKeyValueIterator<Key,Value> skvi = (SortedKeyValueIterator<Key,Value>) untypedInstance;
-    OptionDescriber iterOptions = null;
-    if (OptionDescriber.class.isAssignableFrom(skvi.getClass())) {
-      iterOptions = (OptionDescriber) skvi;
-    }
-
-    String iteratorName;
-    if (null != iterOptions) {
-      final IteratorOptions itopts = iterOptions.describeOptions();
-      iteratorName = itopts.getName();
-      
-      if (iteratorName == null) {
-        throw new IllegalArgumentException(className + " described its default distinguishing name as null");
-      }
-      String shortClassName = className;
-      if (className.contains(".")) {
-        shortClassName = className.substring(className.lastIndexOf('.') + 1);
-      }
-      final Map<String,String> localOptions = new HashMap<String,String>();
-      do {
-        // clean up the overall options that caused things to fail
-        for (String key : localOptions.keySet()) {
-          options.remove(key);
-        }
-        localOptions.clear();
-  
-        reader.println(itopts.getDescription());
-  
-        String prompt;
-        if (itopts.getNamedOptions() != null) {
-          for (Entry<String,String> e : itopts.getNamedOptions().entrySet()) {
-            prompt = Shell.repeat("-", 10) + "> set " + shortClassName + " parameter " + e.getKey() + ", " + e.getValue() + ": ";
-            reader.flush();
-            input = reader.readLine(prompt);
-            if (input == null) {
-              reader.println();
-              throw new IOException("Input stream closed");
-            }
-            // Places all Parameters and Values into the LocalOptions, even if the value is "".
-            // This allows us to check for "" values when setting the iterators and allows us to remove
-            // the parameter and value from the table property.
-            localOptions.put(e.getKey(), input);
-          }
-        }
-  
-        if (itopts.getUnnamedOptionDescriptions() != null) {
-          for (String desc : itopts.getUnnamedOptionDescriptions()) {
-            reader.println(Shell.repeat("-", 10) + "> entering options: " + desc);
-            input = "start";
-            prompt = Shell.repeat("-", 10) + "> set " + shortClassName + " option (<name> <value>, hit enter to skip): ";
-            while (true) {
-              reader.flush();
-              input = reader.readLine(prompt);
-              if (input == null) {
-                reader.println();
-                throw new IOException("Input stream closed");
-              } else {
-                input = new String(input);
-              }
-  
-              if (input.length() == 0)
-                break;
-  
-              String[] sa = input.split(" ", 2);
-              localOptions.put(sa[0], sa[1]);
-            }
-          }
-        }
-  
-        options.putAll(localOptions);
-        if (!iterOptions.validateOptions(options))
-          reader.println("invalid options for " + clazz.getName());
-  
-      } while (!iterOptions.validateOptions(options));
-    } else {
-      reader.flush();
-      reader.println("The iterator class does not implement OptionDescriber. Consider this for better iterator configuration using this setiter command.");
-      iteratorName = reader.readLine("Name for iterator (enter to skip): ");
-      if (null == iteratorName) {
-        reader.println();
-        throw new IOException("Input stream closed");
-      } else if (StringUtils.isWhitespace(iteratorName)) {
-        // Treat whitespace or empty string as no name provided
-        iteratorName = null;
-      }
-      
-      reader.flush();
-      reader.println("Optional, configure name-value options for iterator:");
-      String prompt = Shell.repeat("-", 10) + "> set option (<name> <value>, hit enter to skip): ";
-      final HashMap<String,String> localOptions = new HashMap<String,String>();
-      
-      while (true) {
-        reader.flush();
-        input = reader.readLine(prompt);
-        if (input == null) {
-          reader.println();
-          throw new IOException("Input stream closed");
-        } else if (StringUtils.isWhitespace(input)) {
-          break;
-        } 
-
-        String[] sa = input.split(" ", 2);
-        localOptions.put(sa[0], sa[1]);
-      }
-      
-      options.putAll(localOptions);
-    }
-    
-    return iteratorName;
-  }
-
-  @Override
-  public String description() {
-    return "sets a table-specific or namespace-specific iterator";
-  }
-
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-
-    priorityOpt = new Option("p", "priority", true, "the order in which the iterator is applied");
-    priorityOpt.setArgName("pri");
-    priorityOpt.setRequired(true);
-
-    nameOpt = new Option("n", "name", true, "iterator to set");
-    nameOpt.setArgName("itername");
-
-    allScopeOpt = new Option("all", "all-scopes", false, "applied at scan time, minor and major compactions");
-    mincScopeOpt = new Option(IteratorScope.minc.name(), "minor-compaction", false, "applied at minor compaction");
-    majcScopeOpt = new Option(IteratorScope.majc.name(), "major-compaction", false, "applied at major compaction");
-    scanScopeOpt = new Option(IteratorScope.scan.name(), "scan-time", false, "applied at scan time");
-
-    final OptionGroup typeGroup = new OptionGroup();
-    classnameTypeOpt = new Option("class", "class-name", true, "a java class that implements SortedKeyValueIterator");
-    classnameTypeOpt.setArgName("name");
-    aggTypeOpt = new Option("agg", "aggregator", false, "an aggregating type");
-    regexTypeOpt = new Option("regex", "regular-expression", false, "a regex matching iterator");
-    versionTypeOpt = new Option("vers", "version", false, "a versioning iterator");
-    reqvisTypeOpt = new Option("reqvis", "require-visibility", false, "an iterator that omits entries with empty visibilities");
-    ageoffTypeOpt = new Option("ageoff", "ageoff", false, "an aging off iterator");
-
-    typeGroup.addOption(classnameTypeOpt);
-    typeGroup.addOption(aggTypeOpt);
-    typeGroup.addOption(regexTypeOpt);
-    typeGroup.addOption(versionTypeOpt);
-    typeGroup.addOption(reqvisTypeOpt);
-    typeGroup.addOption(ageoffTypeOpt);
-    typeGroup.setRequired(true);
-
-    final OptionGroup tableGroup = new OptionGroup();
-    tableGroup.addOption(OptUtil.tableOpt("table to configure iterators on"));
-    tableGroup.addOption(OptUtil.namespaceOpt("namespace to configure iterators on"));
-
-    o.addOption(priorityOpt);
-    o.addOption(nameOpt);
-    o.addOption(allScopeOpt);
-    o.addOption(mincScopeOpt);
-    o.addOption(majcScopeOpt);
-    o.addOption(scanScopeOpt);
-    o.addOptionGroup(typeGroup);
-    o.addOptionGroup(tableGroup);
-    return o;
-  }
-
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/SetScanIterCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/SetScanIterCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/SetScanIterCommand.java
deleted file mode 100644
index 3ae42dd..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/SetScanIterCommand.java
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.accumulo.shell.commands;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.IteratorSetting;
-import org.apache.accumulo.core.client.Scanner;
-import org.apache.accumulo.core.client.TableNotFoundException;
-import org.apache.accumulo.core.iterators.IteratorUtil.IteratorScope;
-import org.apache.accumulo.core.iterators.SortedKeyValueIterator;
-import org.apache.accumulo.core.security.Authorizations;
-import org.apache.accumulo.shell.Shell;
-import org.apache.accumulo.shell.ShellCommandException;
-import org.apache.accumulo.shell.ShellCommandException.ErrorCode;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.OptionGroup;
-import org.apache.commons.cli.Options;
-
-public class SetScanIterCommand extends SetIterCommand {
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException, TableNotFoundException,
-      IOException, ShellCommandException {
-    Shell.log.warn("Deprecated, use " + new SetShellIterCommand().getName());
-    return super.execute(fullCommand, cl, shellState);
-  }
-  
-  @Override
-  protected void setTableProperties(final CommandLine cl, final Shell shellState, final int priority, final Map<String,String> options, final String classname,
-      final String name) throws AccumuloException, AccumuloSecurityException, ShellCommandException, TableNotFoundException {
-    
-    final String tableName = OptUtil.getTableOpt(cl, shellState);
-
-    // instead of setting table properties, just put the options in a list to use at scan time
-    Class<?> loadClass;
-    try {
-      loadClass = getClass().getClassLoader().loadClass(classname);
-    } catch (ClassNotFoundException e) {
-      throw new ShellCommandException(ErrorCode.INITIALIZATION_FAILURE, "Unable to load " + classname);
-    }
-    try {
-      loadClass.asSubclass(SortedKeyValueIterator.class);
-    } catch (ClassCastException ex) {
-      throw new ShellCommandException(ErrorCode.INITIALIZATION_FAILURE, "Unable to load " + classname  + " as type "
-          + SortedKeyValueIterator.class.getName());
-    }
-    
-    for (Iterator<Entry<String,String>> i = options.entrySet().iterator(); i.hasNext();) {
-      final Entry<String,String> entry = i.next();
-      if (entry.getValue() == null || entry.getValue().isEmpty()) {
-        i.remove();
-      }
-    }
-
-    List<IteratorSetting> tableScanIterators = shellState.scanIteratorOptions.get(tableName);
-    if (tableScanIterators == null) {
-      tableScanIterators = new ArrayList<IteratorSetting>();
-      shellState.scanIteratorOptions.put(tableName, tableScanIterators);
-    }
-    final IteratorSetting setting = new IteratorSetting(priority, name, classname);
-    setting.addOptions(options);
-    
-    // initialize a scanner to ensure the new setting does not conflict with existing settings
-    final String user = shellState.getConnector().whoami();
-    final Authorizations auths = shellState.getConnector().securityOperations().getUserAuthorizations(user);
-    final Scanner scanner = shellState.getConnector().createScanner(tableName, auths);
-    for (IteratorSetting s : tableScanIterators) {
-      scanner.addScanIterator(s);
-    }
-    scanner.addScanIterator(setting);
-    
-    // if no exception has been thrown, it's safe to add it to the list
-    tableScanIterators.add(setting);
-    Shell.log.debug("Scan iterators :" + shellState.scanIteratorOptions.get(tableName));
-  }
-  
-  @Override
-  public String description() {
-    return "sets a table-specific scan iterator for this shell session";
-  }
-  
-  @Override
-  public Options getOptions() {
-    // Remove the options that specify which type of iterator this is, since
-    // they are all scan iterators with this command.
-    final HashSet<OptionGroup> groups = new HashSet<OptionGroup>();
-    final Options parentOptions = super.getOptions();
-    final Options modifiedOptions = new Options();
-    for (Iterator<?> it = parentOptions.getOptions().iterator(); it.hasNext();) {
-      Option o = (Option) it.next();
-      if (!IteratorScope.majc.name().equals(o.getOpt()) && !IteratorScope.minc.name().equals(o.getOpt()) && !IteratorScope.scan.name().equals(o.getOpt())) {
-        modifiedOptions.addOption(o);
-        OptionGroup group = parentOptions.getOptionGroup(o);
-        if (group != null)
-          groups.add(group);
-      }
-    }
-    for (OptionGroup group : groups) {
-      modifiedOptions.addOptionGroup(group);
-    }
-    return modifiedOptions;
-  }
-  
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/SetShellIterCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/SetShellIterCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/SetShellIterCommand.java
deleted file mode 100644
index c7fea56..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/SetShellIterCommand.java
+++ /dev/null
@@ -1,131 +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.accumulo.shell.commands;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.IteratorSetting;
-import org.apache.accumulo.core.client.TableNotFoundException;
-import org.apache.accumulo.core.iterators.IteratorUtil.IteratorScope;
-import org.apache.accumulo.core.iterators.SortedKeyValueIterator;
-import org.apache.accumulo.shell.Shell;
-import org.apache.accumulo.shell.ShellCommandException;
-import org.apache.accumulo.shell.ShellCommandException.ErrorCode;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.OptionGroup;
-import org.apache.commons.cli.Options;
-
-public class SetShellIterCommand extends SetIterCommand {
-  private Option profileOpt;
-
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException,
-      TableNotFoundException, IOException, ShellCommandException {
-    return super.execute(fullCommand, cl, shellState);
-  }
-  
-  @Override
-  protected void setTableProperties(final CommandLine cl, final Shell shellState, final int priority, final Map<String,String> options, final String classname,
-      final String name) throws AccumuloException, AccumuloSecurityException, ShellCommandException, TableNotFoundException {
-    // instead of setting table properties, just put the options in a list to use at scan time
-    
-    String profile = cl.getOptionValue(profileOpt.getOpt());
-
-    // instead of setting table properties, just put the options in a list to use at scan time
-    Class<?> loadClass;
-    try {
-      loadClass = getClass().getClassLoader().loadClass(classname);
-    } catch (ClassNotFoundException e) {
-      throw new ShellCommandException(ErrorCode.INITIALIZATION_FAILURE, "Unable to load " + classname);
-    }
-    try {
-      loadClass.asSubclass(SortedKeyValueIterator.class);
-    } catch (ClassCastException ex) {
-      throw new ShellCommandException(ErrorCode.INITIALIZATION_FAILURE, "xUnable to load " + classname  + " as type "
-          + SortedKeyValueIterator.class.getName());
-    }
-    
-    for (Iterator<Entry<String,String>> i = options.entrySet().iterator(); i.hasNext();) {
-      final Entry<String,String> entry = i.next();
-      if (entry.getValue() == null || entry.getValue().isEmpty()) {
-        i.remove();
-      }
-    }
-
-    List<IteratorSetting> tableScanIterators = shellState.iteratorProfiles.get(profile);
-    if (tableScanIterators == null) {
-      tableScanIterators = new ArrayList<IteratorSetting>();
-      shellState.iteratorProfiles.put(profile, tableScanIterators);
-    }
-    final IteratorSetting setting = new IteratorSetting(priority, name, classname);
-    setting.addOptions(options);
-
-    Iterator<IteratorSetting> iter = tableScanIterators.iterator();
-    while (iter.hasNext()) {
-      if (iter.next().getName().equals(name)) {
-        iter.remove();
-      }
-    }
-
-    tableScanIterators.add(setting);
-  }
-  
-  @Override
-  public String description() {
-    return "adds an iterator to a profile for this shell session";
-  }
-  
-  @Override
-  public Options getOptions() {
-    // Remove the options that specify which type of iterator this is, since
-    // they are all scan iterators with this command.
-    final HashSet<OptionGroup> groups = new HashSet<OptionGroup>();
-    final Options parentOptions = super.getOptions();
-    final Options modifiedOptions = new Options();
-    for (Iterator<?> it = parentOptions.getOptions().iterator(); it.hasNext();) {
-      Option o = (Option) it.next();
-      if (!IteratorScope.majc.name().equals(o.getOpt()) && !IteratorScope.minc.name().equals(o.getOpt()) && !IteratorScope.scan.name().equals(o.getOpt())
-          && !"table".equals(o.getLongOpt())) {
-        modifiedOptions.addOption(o);
-        OptionGroup group = parentOptions.getOptionGroup(o);
-        if (group != null)
-          groups.add(group);
-      }
-    }
-    for (OptionGroup group : groups) {
-      modifiedOptions.addOptionGroup(group);
-    }
-    
-    profileOpt = new Option("pn", "profile", true, "iterator profile name");
-    profileOpt.setRequired(true);
-    profileOpt.setArgName("profile");
-    
-    modifiedOptions.addOption(profileOpt);
-
-    return modifiedOptions;
-  }
-  
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/ShellPluginConfigurationCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/ShellPluginConfigurationCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/ShellPluginConfigurationCommand.java
deleted file mode 100644
index 45d48e7..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/ShellPluginConfigurationCommand.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.accumulo.shell.commands;
-
-import java.util.Iterator;
-import java.util.Map.Entry;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.TableNotFoundException;
-import org.apache.accumulo.core.conf.Property;
-import org.apache.accumulo.shell.Shell;
-import org.apache.accumulo.shell.Shell.Command;
-import org.apache.accumulo.start.classloader.vfs.AccumuloVFSClassLoader;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.OptionGroup;
-import org.apache.commons.cli.Options;
-import org.apache.log4j.Logger;
-
-public abstract class ShellPluginConfigurationCommand extends Command {
-  private Option removePluginOption, pluginClassOption, listPluginOption;
-  
-  private String pluginType;
-  
-  private Property tableProp;
-  
-  private String classOpt;
-  
-  ShellPluginConfigurationCommand(final String typeName, final Property tableProp, final String classOpt) {
-    this.pluginType = typeName;
-    this.tableProp = tableProp;
-    this.classOpt = classOpt;
-  }
-
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    final String tableName = OptUtil.getTableOpt(cl, shellState);
-    
-    if (cl.hasOption(removePluginOption.getOpt())) {
-      // Remove the property
-      removePlugin(cl, shellState, tableName);
-      
-      shellState.getReader().println("Removed "+pluginType+" on " + tableName);
-    } else if (cl.hasOption(listPluginOption.getOpt())) {
-      // Get the options for this table
-      final Iterator<Entry<String,String>> iter = shellState.getConnector().tableOperations().getProperties(tableName).iterator();
-      
-      while (iter.hasNext()) {
-        Entry<String,String> ent = iter.next();
-        
-        // List all parameters with the property name
-        if (ent.getKey().startsWith(tableProp.toString())) {
-          shellState.getReader().println(ent.getKey() + ": " + ent.getValue());
-        }
-      }
-    } else {
-      // Set the plugin with the provided options
-      String className = cl.getOptionValue(pluginClassOption.getOpt());
-      
-      // Set the plugin property on the table
-      setPlugin(cl, shellState, tableName, className);
-    }
-    
-    return 0;
-  }
-
-  protected void setPlugin(final CommandLine cl, final Shell shellState, final String tableName, final String className) throws AccumuloException, AccumuloSecurityException {
-    shellState.getConnector().tableOperations().setProperty(tableName, tableProp.toString(), className);
-  }
-  
-  protected void removePlugin(final CommandLine cl, final Shell shellState, final String tableName) throws AccumuloException, AccumuloSecurityException {
-    shellState.getConnector().tableOperations().removeProperty(tableName, tableProp.toString());
-  }
-  
-  public static <T> Class<? extends T> getPluginClass(final String tableName, final Shell shellState, final Class<T> clazz, final Property pluginProp) {
-    Iterator<Entry<String,String>> props;
-    try {
-      props = shellState.getConnector().tableOperations().getProperties(tableName).iterator();
-    } catch (AccumuloException e) {
-      return null;
-    } catch (TableNotFoundException e) {
-      return null;
-    }
-    
-    while (props.hasNext()) {
-      final Entry<String,String> ent = props.next();
-      if (ent.getKey().equals(pluginProp.toString())) {
-        Class<? extends T> pluginClazz;
-        try {
-          pluginClazz = AccumuloVFSClassLoader.loadClass(ent.getValue(), clazz);
-        } catch (ClassNotFoundException e) {
-          Logger.getLogger(ShellPluginConfigurationCommand.class).warn("Class not found" + e.getMessage());
-          return null;
-        }
-        
-        return pluginClazz;
-      }
-    }
-    
-    return null;
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-    final OptionGroup actionGroup = new OptionGroup();
-    
-    pluginClassOption = new Option(classOpt, pluginType, true, "fully qualified name of the " + pluginType + " class to use");
-    pluginClassOption.setArgName("className");
-    
-    // Action to take: apply (default), remove, list
-    removePluginOption = new Option("r", "remove", false, "remove the current "+pluginType+"");
-    listPluginOption = new Option("l", "list", false, "display the current "+pluginType+"");
-    
-    actionGroup.addOption(pluginClassOption);
-    actionGroup.addOption(removePluginOption);
-    actionGroup.addOption(listPluginOption);
-    actionGroup.setRequired(true);
-    
-    o.addOptionGroup(actionGroup);
-    o.addOption(OptUtil.tableOpt("table to set the "+pluginType+" on"));
-    
-    return o;
-  }
-  
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-  
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/SleepCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/SleepCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/SleepCommand.java
deleted file mode 100644
index 1f7ed5d..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/SleepCommand.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.accumulo.shell.commands;
-
-import org.apache.accumulo.shell.Shell;
-import org.apache.accumulo.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-
-public class SleepCommand extends Command {
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    final double secs = Double.parseDouble(cl.getArgs()[0]);
-    Thread.sleep((long) (secs * 1000));
-    return 0;
-  }
-  
-  @Override
-  public String description() {
-    return "sleeps for the given number of seconds";
-  }
-  
-  @Override
-  public int numArgs() {
-    return 1;
-  }
-  
-  @Override
-  public String usage() {
-    return getName() + " <seconds>";
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/SystemPermissionsCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/SystemPermissionsCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/SystemPermissionsCommand.java
deleted file mode 100644
index 7cf4584..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/SystemPermissionsCommand.java
+++ /dev/null
@@ -1,44 +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.accumulo.shell.commands;
-
-import java.io.IOException;
-
-import org.apache.accumulo.core.security.SystemPermission;
-import org.apache.accumulo.shell.Shell;
-import org.apache.accumulo.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-
-public class SystemPermissionsCommand extends Command {
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws IOException {
-    for (String p : SystemPermission.printableValues()) {
-      shellState.getReader().println(p);
-    }
-    return 0;
-  }
-  
-  @Override
-  public String description() {
-    return "displays a list of valid system permissions";
-  }
-  
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/shell/src/main/java/org/apache/accumulo/shell/commands/TableCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/TableCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/TableCommand.java
deleted file mode 100644
index 6a563ab..0000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/TableCommand.java
+++ /dev/null
@@ -1,60 +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.accumulo.shell.commands;
-
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.TableNotFoundException;
-import org.apache.accumulo.shell.Shell;
-import org.apache.accumulo.shell.Token;
-import org.apache.accumulo.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-
-public class TableCommand extends Command {
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException, TableNotFoundException {
-    final String tableName = cl.getArgs()[0];
-    if (!shellState.getConnector().tableOperations().exists(tableName)) {
-      throw new TableNotFoundException(null, tableName, null);
-    }
-    shellState.setTableName(tableName);
-    return 0;
-  }
-  
-  @Override
-  public String description() {
-    return "switches to the specified table";
-  }
-  
-  @Override
-  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> special) {
-    registerCompletionForTables(root, special);
-  }
-  
-  @Override
-  public String usage() {
-    return getName() + " <tableName>";
-  }
-  
-  @Override
-  public int numArgs() {
-    return 1;
-  }
-}


[35/53] [abbrv] ACCUMULO-1879 Move shell into new package and module

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/RevokeCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/RevokeCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/RevokeCommand.java
new file mode 100644
index 0000000..373c0b0
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/RevokeCommand.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.accumulo.shell.commands;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.accumulo.core.security.NamespacePermission;
+import org.apache.accumulo.core.security.SystemPermission;
+import org.apache.accumulo.core.security.TablePermission;
+import org.apache.accumulo.core.util.BadArgumentException;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Token;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.OptionGroup;
+import org.apache.commons.cli.Options;
+
+public class RevokeCommand extends TableOperation {
+  {
+    disableUnflaggedTableOptions();
+  }
+
+  private Option systemOpt, userOpt;
+  private String user;
+  private String[] permission;
+
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    user = cl.hasOption(userOpt.getOpt()) ? cl.getOptionValue(userOpt.getOpt()) : shellState.getConnector().whoami();
+
+    permission = cl.getArgs()[0].split("\\.", 2);
+    if (cl.hasOption(systemOpt.getOpt()) && permission[0].equalsIgnoreCase("System")) {
+      try {
+        shellState.getConnector().securityOperations().revokeSystemPermission(user, SystemPermission.valueOf(permission[1]));
+        Shell.log.debug("Revoked from " + user + " the " + permission[1] + " permission");
+      } catch (IllegalArgumentException e) {
+        throw new BadArgumentException("No such system permission", fullCommand, fullCommand.indexOf(cl.getArgs()[0]));
+      }
+    } else if (permission[0].equalsIgnoreCase("Table")) {
+      super.execute(fullCommand, cl, shellState);
+    } else if (permission[0].equalsIgnoreCase("Namespace")) {
+      if (cl.hasOption(optNamespace.getOpt())) {
+        try {
+          shellState.getConnector().securityOperations()
+              .revokeNamespacePermission(user, cl.getOptionValue(optNamespace.getOpt()), NamespacePermission.valueOf(permission[1]));
+        } catch (IllegalArgumentException e) {
+          throw new BadArgumentException("No such namespace permission", fullCommand, fullCommand.indexOf(cl.getArgs()[0]));
+        }
+      } else {
+        throw new BadArgumentException("No namespace specified to apply permission to", fullCommand, fullCommand.indexOf(cl.getArgs()[0]));
+      }
+    } else {
+      throw new BadArgumentException("Unrecognized permission", fullCommand, fullCommand.indexOf(cl.getArgs()[0]));
+    }
+    return 0;
+  }
+
+  @Override
+  protected void doTableOp(final Shell shellState, final String tableName) throws Exception {
+    try {
+      shellState.getConnector().securityOperations().revokeTablePermission(user, tableName, TablePermission.valueOf(permission[1]));
+      Shell.log.debug("Revoked from " + user + " the " + permission[1] + " permission on table " + tableName);
+    } catch (IllegalArgumentException e) {
+      throw new IllegalArgumentException("No such table permission", e);
+    }
+  }
+
+  @Override
+  public String description() {
+    return "revokes system or table permissions from a user";
+  }
+
+  @Override
+  public String usage() {
+    return getName() + " <permission>";
+  }
+
+  @Override
+  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> completionSet) {
+    final Token cmd = new Token(getName());
+    cmd.addSubcommand(new Token(TablePermission.printableValues()));
+    cmd.addSubcommand(new Token(SystemPermission.printableValues()));
+    cmd.addSubcommand(new Token(NamespacePermission.printableValues()));
+    root.addSubcommand(cmd);
+  }
+
+  @Override
+  public Options getOptions() {
+    super.getOptions();
+    final Options o = new Options();
+
+    final OptionGroup group = new OptionGroup();
+
+    systemOpt = new Option("s", "system", false, "revoke a system permission");
+
+    optNamespace = new Option(Shell.namespaceOption, "namespace", true, "name of a namespace to operate on");
+    optNamespace.setArgName("namespace");
+
+    group.addOption(systemOpt);
+    group.addOption(optTableName);
+    group.addOption(optTablePattern);
+    group.addOption(optNamespace);
+
+    o.addOptionGroup(group);
+    userOpt = new Option(Shell.userOption, "user", true, "user to operate on");
+    userOpt.setArgName("username");
+    userOpt.setRequired(true);
+    o.addOption(userOpt);
+
+    return o;
+  }
+
+  @Override
+  public int numArgs() {
+    return 1;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/ScanCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/ScanCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/ScanCommand.java
new file mode 100644
index 0000000..37a33a4
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/ScanCommand.java
@@ -0,0 +1,334 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.util.List;
+import java.util.Map.Entry;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.IteratorSetting;
+import org.apache.accumulo.core.client.Scanner;
+import org.apache.accumulo.core.client.ScannerBase;
+import org.apache.accumulo.core.conf.AccumuloConfiguration;
+import org.apache.accumulo.core.data.Key;
+import org.apache.accumulo.core.data.Range;
+import org.apache.accumulo.core.data.Value;
+import org.apache.accumulo.core.security.Authorizations;
+import org.apache.accumulo.core.util.format.BinaryFormatter;
+import org.apache.accumulo.core.util.format.Formatter;
+import org.apache.accumulo.core.util.interpret.DefaultScanInterpreter;
+import org.apache.accumulo.core.util.interpret.ScanInterpreter;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.accumulo.shell.Shell.PrintFile;
+import org.apache.accumulo.start.classloader.vfs.AccumuloVFSClassLoader;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+import org.apache.hadoop.io.Text;
+
+public class ScanCommand extends Command {
+  
+  private Option scanOptAuths, scanOptRow, scanOptColumns, disablePaginationOpt, showFewOpt, formatterOpt, interpreterOpt, formatterInterpeterOpt,
+      outputFileOpt;
+  
+  protected Option timestampOpt;
+  private Option optStartRowExclusive;
+  private Option optEndRowExclusive;
+  private Option timeoutOption;
+  private Option profileOpt;
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    final PrintFile printFile = getOutputFile(cl);
+    final String tableName = OptUtil.getTableOpt(cl, shellState);
+    
+    final Class<? extends Formatter> formatter = getFormatter(cl, tableName, shellState);
+    final ScanInterpreter interpeter = getInterpreter(cl, tableName, shellState);
+    
+    // handle first argument, if present, the authorizations list to
+    // scan with
+    final Authorizations auths = getAuths(cl, shellState);
+    final Scanner scanner = shellState.getConnector().createScanner(tableName, auths);
+    
+    // handle session-specific scan iterators
+    addScanIterators(shellState, cl, scanner, tableName);
+    
+    // handle remaining optional arguments
+    scanner.setRange(getRange(cl, interpeter));
+    
+    // handle columns
+    fetchColumns(cl, scanner, interpeter);
+    
+    // set timeout
+    scanner.setTimeout(getTimeout(cl), TimeUnit.MILLISECONDS);
+    
+    // output the records
+    if (cl.hasOption(showFewOpt.getOpt())) {
+      final String showLength = cl.getOptionValue(showFewOpt.getOpt());
+      try {
+        final int length = Integer.parseInt(showLength);
+        if (length < 1) {
+          throw new IllegalArgumentException();
+        }
+        BinaryFormatter.getlength(length);
+        printBinaryRecords(cl, shellState, scanner, printFile);
+      } catch (NumberFormatException nfe) {
+        shellState.getReader().println("Arg must be an integer.");
+      } catch (IllegalArgumentException iae) {
+        shellState.getReader().println("Arg must be greater than one.");
+      }
+      
+    } else {
+      printRecords(cl, shellState, scanner, formatter, printFile);
+    }
+    if (printFile != null) {
+      printFile.close();
+    }
+    
+    return 0;
+  }
+  
+  protected long getTimeout(final CommandLine cl) {
+    if (cl.hasOption(timeoutOption.getLongOpt())) {
+      return AccumuloConfiguration.getTimeInMillis(cl.getOptionValue(timeoutOption.getLongOpt()));
+    }
+    
+    return Long.MAX_VALUE;
+  }
+  
+  protected void addScanIterators(final Shell shellState, CommandLine cl, final Scanner scanner, final String tableName) {
+    
+    List<IteratorSetting> tableScanIterators;
+    if (cl.hasOption(profileOpt.getOpt())) {
+      String profile = cl.getOptionValue(profileOpt.getOpt());
+      tableScanIterators = shellState.iteratorProfiles.get(profile);
+      
+      if (tableScanIterators == null) {
+        throw new IllegalArgumentException("Profile " + profile + " does not exist");
+      }
+    } else {
+      tableScanIterators = shellState.scanIteratorOptions.get(tableName);
+      if (tableScanIterators == null) {
+        Shell.log.debug("Found no scan iterators to set");
+        return;
+      }
+    }
+    
+    Shell.log.debug("Found " + tableScanIterators.size() + " scan iterators to set");
+    
+    for (IteratorSetting setting : tableScanIterators) {
+      Shell.log.debug("Setting scan iterator " + setting.getName() + " at priority " + setting.getPriority() + " using class name "
+          + setting.getIteratorClass());
+      for (Entry<String,String> option : setting.getOptions().entrySet()) {
+        Shell.log.debug("Setting option for " + setting.getName() + ": " + option.getKey() + "=" + option.getValue());
+      }
+      scanner.addScanIterator(setting);
+    }
+  }
+  
+  protected void printRecords(final CommandLine cl, final Shell shellState, final Iterable<Entry<Key,Value>> scanner, final Class<? extends Formatter> formatter)
+      throws IOException {
+    printRecords(cl, shellState, scanner, formatter, null);
+  }
+  
+  protected void printRecords(final CommandLine cl, final Shell shellState, final Iterable<Entry<Key,Value>> scanner,
+      final Class<? extends Formatter> formatter, PrintFile outFile) throws IOException {
+    if (outFile == null) {
+      shellState.printRecords(scanner, cl.hasOption(timestampOpt.getOpt()), !cl.hasOption(disablePaginationOpt.getOpt()), formatter);
+    } else {
+      shellState.printRecords(scanner, cl.hasOption(timestampOpt.getOpt()), !cl.hasOption(disablePaginationOpt.getOpt()), formatter, outFile);
+    }
+  }
+  
+  protected void printBinaryRecords(final CommandLine cl, final Shell shellState, final Iterable<Entry<Key,Value>> scanner) throws IOException {
+    printBinaryRecords(cl, shellState, scanner, null);
+  }
+  
+  protected void printBinaryRecords(final CommandLine cl, final Shell shellState, final Iterable<Entry<Key,Value>> scanner, PrintFile outFile)
+      throws IOException {
+    if (outFile == null) {
+      shellState.printBinaryRecords(scanner, cl.hasOption(timestampOpt.getOpt()), !cl.hasOption(disablePaginationOpt.getOpt()));
+    } else {
+      shellState.printBinaryRecords(scanner, cl.hasOption(timestampOpt.getOpt()), !cl.hasOption(disablePaginationOpt.getOpt()), outFile);
+    }
+  }
+  
+  protected ScanInterpreter getInterpreter(final CommandLine cl, final String tableName, final Shell shellState) throws Exception {
+    
+    Class<? extends ScanInterpreter> clazz = null;
+    try {
+      if (cl.hasOption(interpreterOpt.getOpt())) {
+        clazz = AccumuloVFSClassLoader.loadClass(cl.getOptionValue(interpreterOpt.getOpt()), ScanInterpreter.class);
+      } else if (cl.hasOption(formatterInterpeterOpt.getOpt())) {
+        clazz = AccumuloVFSClassLoader.loadClass(cl.getOptionValue(formatterInterpeterOpt.getOpt()), ScanInterpreter.class);
+      }
+    } catch (ClassNotFoundException e) {
+      shellState.getReader().println("Interpreter class could not be loaded.\n" + e.getMessage());
+    }
+    
+    if (clazz == null)
+      clazz = InterpreterCommand.getCurrentInterpreter(tableName, shellState);
+    
+    if (clazz == null)
+      clazz = DefaultScanInterpreter.class;
+    
+    return clazz.newInstance();
+  }
+  
+  protected Class<? extends Formatter> getFormatter(final CommandLine cl, final String tableName, final Shell shellState) throws IOException {
+    
+    try {
+      if (cl.hasOption(formatterOpt.getOpt())) {
+        return AccumuloVFSClassLoader.loadClass(cl.getOptionValue(formatterOpt.getOpt()), Formatter.class);
+        
+      } else if (cl.hasOption(formatterInterpeterOpt.getOpt())) {
+        return AccumuloVFSClassLoader.loadClass(cl.getOptionValue(formatterInterpeterOpt.getOpt()), Formatter.class);
+      }
+    } catch (ClassNotFoundException e) {
+      shellState.getReader().println("Formatter class could not be loaded.\n" + e.getMessage());
+    }
+    
+    return shellState.getFormatter(tableName);
+  }
+  
+  protected void fetchColumns(final CommandLine cl, final ScannerBase scanner, final ScanInterpreter formatter) throws UnsupportedEncodingException {
+    if (cl.hasOption(scanOptColumns.getOpt())) {
+      for (String a : cl.getOptionValue(scanOptColumns.getOpt()).split(",")) {
+        final String sa[] = a.split(":", 2);
+        if (sa.length == 1) {
+          scanner.fetchColumnFamily(formatter.interpretColumnFamily(new Text(a.getBytes(Shell.CHARSET))));
+        } else {
+          scanner.fetchColumn(formatter.interpretColumnFamily(new Text(sa[0].getBytes(Shell.CHARSET))),
+              formatter.interpretColumnQualifier(new Text(sa[1].getBytes(Shell.CHARSET))));
+        }
+      }
+    }
+  }
+  
+  protected Range getRange(final CommandLine cl, final ScanInterpreter formatter) throws UnsupportedEncodingException {
+    if ((cl.hasOption(OptUtil.START_ROW_OPT) || cl.hasOption(OptUtil.END_ROW_OPT)) && cl.hasOption(scanOptRow.getOpt())) {
+      // did not see a way to make commons cli do this check... it has mutually exclusive options but does not support the or
+      throw new IllegalArgumentException("Options -" + scanOptRow.getOpt() + " AND (-" + OptUtil.START_ROW_OPT + " OR -" + OptUtil.END_ROW_OPT
+          + ") are mutally exclusive ");
+    }
+    
+    if (cl.hasOption(scanOptRow.getOpt())) {
+      return new Range(formatter.interpretRow(new Text(cl.getOptionValue(scanOptRow.getOpt()).getBytes(Shell.CHARSET))));
+    } else {
+      Text startRow = OptUtil.getStartRow(cl);
+      if (startRow != null)
+        startRow = formatter.interpretBeginRow(startRow);
+      Text endRow = OptUtil.getEndRow(cl);
+      if (endRow != null)
+        endRow = formatter.interpretEndRow(endRow);
+      final boolean startInclusive = !cl.hasOption(optStartRowExclusive.getOpt());
+      final boolean endInclusive = !cl.hasOption(optEndRowExclusive.getOpt());
+      return new Range(startRow, startInclusive, endRow, endInclusive);
+    }
+  }
+  
+  protected Authorizations getAuths(final CommandLine cl, final Shell shellState) throws AccumuloSecurityException, AccumuloException {
+    final String user = shellState.getConnector().whoami();
+    Authorizations auths = shellState.getConnector().securityOperations().getUserAuthorizations(user);
+    if (cl.hasOption(scanOptAuths.getOpt())) {
+      auths = ScanCommand.parseAuthorizations(cl.getOptionValue(scanOptAuths.getOpt()));
+    }
+    return auths;
+  }
+  
+  static Authorizations parseAuthorizations(final String field) {
+    if (field == null || field.isEmpty()) {
+      return Authorizations.EMPTY;
+    }
+    return new Authorizations(field.split(","));
+  }
+  
+  @Override
+  public String description() {
+    return "scans the table, and displays the resulting records";
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+    
+    scanOptAuths = new Option("s", "scan-authorizations", true, "scan authorizations (all user auths are used if this argument is not specified)");
+    optStartRowExclusive = new Option("be", "begin-exclusive", false, "make start row exclusive (by default it's inclusive)");
+    optStartRowExclusive.setArgName("begin-exclusive");
+    optEndRowExclusive = new Option("ee", "end-exclusive", false, "make end row exclusive (by default it's inclusive)");
+    optEndRowExclusive.setArgName("end-exclusive");
+    scanOptRow = new Option("r", "row", true, "row to scan");
+    scanOptColumns = new Option("c", "columns", true, "comma-separated columns");
+    timestampOpt = new Option("st", "show-timestamps", false, "display timestamps");
+    disablePaginationOpt = new Option("np", "no-pagination", false, "disable pagination of output");
+    showFewOpt = new Option("f", "show few", true, "show only a specified number of characters");
+    formatterOpt = new Option("fm", "formatter", true, "fully qualified name of the formatter class to use");
+    interpreterOpt = new Option("i", "interpreter", true, "fully qualified name of the interpreter class to use");
+    formatterInterpeterOpt = new Option("fi", "fmt-interpreter", true, "fully qualified name of a class that is a formatter and interpreter");
+    timeoutOption = new Option(null, "timeout", true,
+        "time before scan should fail if no data is returned. If no unit is given assumes seconds.  Units d,h,m,s,and ms are supported.  e.g. 30s or 100ms");
+    outputFileOpt = new Option("o", "output", true, "local file to write the scan output to");
+    
+    scanOptAuths.setArgName("comma-separated-authorizations");
+    scanOptRow.setArgName("row");
+    scanOptColumns.setArgName("<columnfamily>[:<columnqualifier>]{,<columnfamily>[:<columnqualifier>]}");
+    showFewOpt.setRequired(false);
+    showFewOpt.setArgName("int");
+    formatterOpt.setArgName("className");
+    timeoutOption.setArgName("timeout");
+    outputFileOpt.setArgName("file");
+    
+    profileOpt = new Option("pn", "profile", true, "iterator profile name");
+    profileOpt.setArgName("profile");
+    
+    o.addOption(scanOptAuths);
+    o.addOption(scanOptRow);
+    o.addOption(OptUtil.startRowOpt());
+    o.addOption(OptUtil.endRowOpt());
+    o.addOption(optStartRowExclusive);
+    o.addOption(optEndRowExclusive);
+    o.addOption(scanOptColumns);
+    o.addOption(timestampOpt);
+    o.addOption(disablePaginationOpt);
+    o.addOption(OptUtil.tableOpt("table to be scanned"));
+    o.addOption(showFewOpt);
+    o.addOption(formatterOpt);
+    o.addOption(interpreterOpt);
+    o.addOption(formatterInterpeterOpt);
+    o.addOption(timeoutOption);
+    o.addOption(outputFileOpt);
+    o.addOption(profileOpt);
+    
+    return o;
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+  
+  protected PrintFile getOutputFile(final CommandLine cl) throws FileNotFoundException {
+    final String outputFile = cl.getOptionValue(outputFileOpt.getOpt());
+    return (outputFile == null ? null : new PrintFile(outputFile));
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/ScriptCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/ScriptCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/ScriptCommand.java
new file mode 100644
index 0000000..9bd91cc
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/ScriptCommand.java
@@ -0,0 +1,290 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.io.File;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.Reader;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+
+import javax.script.Bindings;
+import javax.script.Compilable;
+import javax.script.CompiledScript;
+import javax.script.Invocable;
+import javax.script.ScriptContext;
+import javax.script.ScriptEngine;
+import javax.script.ScriptEngineFactory;
+import javax.script.ScriptEngineManager;
+import javax.script.ScriptException;
+import javax.script.SimpleScriptContext;
+
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.OptionGroup;
+import org.apache.commons.cli.Options;
+
+public class ScriptCommand extends Command {
+  
+  // Command to allow user to run scripts, see JSR-223
+  // http://www.oracle.com/technetwork/articles/javase/scripting-140262.html
+  
+  protected Option list, engine, script, file, args, out, function, object;
+  private static final String DEFAULT_ENGINE = "rhino";
+  
+  public int execute(String fullCommand, CommandLine cl, Shell shellState) throws Exception {
+
+    boolean invoke = false;
+    ScriptEngineManager mgr = new ScriptEngineManager();
+    
+    if (cl.hasOption(list.getOpt())) {
+      listJSREngineInfo(mgr, shellState);
+    } else if (cl.hasOption(file.getOpt()) || cl.hasOption(script.getOpt())) {
+      String engineName = DEFAULT_ENGINE;
+      if (cl.hasOption(engine.getOpt())) {
+        engineName = cl.getOptionValue(engine.getOpt());
+      }
+      ScriptEngine engine = mgr.getEngineByName(engineName);
+      if (null == engine) {
+        shellState.printException(new Exception(engineName + " not found"));
+        return 1;
+      }
+      
+      if (cl.hasOption(object.getOpt()) || cl.hasOption(function.getOpt())) {
+        if (!(engine instanceof Invocable)) {
+          shellState.printException(new Exception(engineName + " does not support invoking functions or methods"));
+          return 1;
+        }
+        invoke = true;
+      }
+      
+      ScriptContext ctx = new SimpleScriptContext();
+      
+      // Put the following objects into the context so that they
+      // are available to the scripts
+      // TODO: What else should go in here?
+      Bindings b = engine.getBindings(ScriptContext.ENGINE_SCOPE);
+      b.put("connection", shellState.getConnector());
+      
+      List<Object> argValues = new ArrayList<Object>();
+      if (cl.hasOption(args.getOpt())) {
+        String[] argList = cl.getOptionValue(args.getOpt()).split(",");
+        for (String arg : argList) {
+          String[] parts = arg.split("=");
+          if (parts.length == 0) {
+            continue;
+          } else if (parts.length == 1) {
+            b.put(parts[0], null);
+            argValues.add(null);
+          } else if (parts.length == 2) {
+            b.put(parts[0], parts[1]);
+            argValues.add(parts[1]);
+          }
+        }
+      }
+      ctx.setBindings(b, ScriptContext.ENGINE_SCOPE);
+      Object[] argArray = argValues.toArray(new Object[argValues.size()]);
+      
+      Writer writer = null;
+      if (cl.hasOption(out.getOpt())) {
+        File f = new File(cl.getOptionValue(out.getOpt()));
+        writer = new FileWriter(f);
+        ctx.setWriter(writer);
+      }
+      
+      if (cl.hasOption(file.getOpt())) {
+        File f = new File(cl.getOptionValue(file.getOpt()));
+        if (!f.exists()) {
+          if (null != writer) {
+            writer.close();
+          }
+          shellState.printException(new Exception(f.getAbsolutePath() + " not found"));
+          return 1;
+        }
+        Reader reader = new FileReader(f);
+        try {
+          engine.eval(reader, ctx);
+          if (invoke) {
+            this.invokeFunctionOrMethod(shellState, engine, cl, argArray);
+          }
+        } catch (ScriptException ex) {
+          shellState.printException(ex);
+          return 1;
+        } finally {
+          reader.close();
+          if (null != writer) {
+            writer.close();
+          }
+        }
+      } else if (cl.hasOption(script.getOpt())) {
+        String inlineScript = cl.getOptionValue(script.getOpt());
+        try {
+          if (engine instanceof Compilable) {
+            Compilable compiledEng = (Compilable) engine;
+            CompiledScript script = compiledEng.compile(inlineScript);
+            script.eval(ctx);
+            if (invoke) {
+              this.invokeFunctionOrMethod(shellState, engine, cl, argArray);
+            }
+          } else {
+            engine.eval(inlineScript, ctx);
+            if (invoke) {
+              this.invokeFunctionOrMethod(shellState, engine, cl, argArray);
+            }
+          }
+        } catch (ScriptException ex) {
+          shellState.printException(ex);
+          return 1;
+        } finally {
+          if (null != writer) {
+            writer.close();
+          }
+        }
+      }
+      if (null != writer) {
+        writer.close();
+      }
+      
+    } else {
+      printHelp(shellState);
+    }
+    return 0;
+  }
+  
+  public String description() {
+    return "execute JSR-223 scripts";
+  }
+  
+  public int numArgs() {
+    return 0;
+  }
+  
+  @Override
+  public String getName() {
+    return "script";
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+    
+    engine = new Option("e", "engine", false, "engine name, defaults to JDK default (Rhino)");
+    engine.setArgName("engineName");
+    engine.setArgs(1);
+    engine.setRequired(false);
+    o.addOption(engine);
+    
+    OptionGroup inputGroup = new OptionGroup();
+    list = new Option("l", "list", false, "list available script engines");
+    inputGroup.addOption(list);
+
+    script = new Option("s", "script", true, "use inline script");
+    script.setArgName("script text");
+    script.setArgs(1);
+    script.setRequired(false);
+    inputGroup.addOption(script);
+    
+    file = new Option("f", "file", true, "use script file");
+    file.setArgName("fileName");
+    file.setArgs(1);
+    file.setRequired(false);
+    
+    inputGroup.addOption(file);
+    inputGroup.setRequired(true);
+    o.addOptionGroup(inputGroup);
+    
+    OptionGroup invokeGroup = new OptionGroup();
+    object = new Option("obj", "object", true, "name of object");
+    object.setArgs(1);
+    object.setArgName("objectName:methodName");
+    object.setRequired(false);
+    invokeGroup.addOption(object);
+    
+    function = new Option("fx", "function", true, "invoke a script function");
+    function.setArgName("functionName");
+    function.setArgs(1);
+    function.setRequired(false);
+    invokeGroup.addOption(function);
+    invokeGroup.setRequired(false);
+    o.addOptionGroup(invokeGroup);
+    
+    args = new Option("a", "args", true, "comma separated list of key=value arguments");
+    args.setArgName("property1=value1,propert2=value2,...");
+    args.setArgs(Option.UNLIMITED_VALUES);
+    args.setRequired(false);
+    o.addOption(args);
+    
+    out = new Option("o", "output", true, "output file");
+    out.setArgName("fileName");
+    out.setArgs(1);
+    out.setRequired(false);
+    o.addOption(out);
+    
+    return o;
+  }
+  
+  private void listJSREngineInfo(ScriptEngineManager mgr, Shell shellState) throws IOException {
+    List<ScriptEngineFactory> factories = mgr.getEngineFactories();
+    Set<String> lines = new TreeSet<String>();
+    for (ScriptEngineFactory factory : factories) {
+      lines.add("ScriptEngineFactory Info");
+      String engName = factory.getEngineName();
+      String engVersion = factory.getEngineVersion();
+      String langName = factory.getLanguageName();
+      String langVersion = factory.getLanguageVersion();
+      lines.add("\tScript Engine: " + engName + " (" + engVersion + ")");
+      List<String> engNames = factory.getNames();
+      for (String name : engNames) {
+        lines.add("\tEngine Alias: " + name);
+      }
+      lines.add("\tLanguage: " + langName + " (" + langVersion + ")");
+    }
+    shellState.printLines(lines.iterator(), true);
+    
+  }
+  
+  private void invokeFunctionOrMethod(Shell shellState, ScriptEngine engine, CommandLine cl, Object[] args) {
+    try {
+      Invocable inv = (Invocable) engine;
+      if (cl.hasOption(function.getOpt())) {
+        inv.invokeFunction(cl.getOptionValue(function.getOpt()), args);
+      } else if (cl.hasOption(object.getOpt())) {
+        String objectMethod = cl.getOptionValue(object.getOpt());
+        String[] parts = objectMethod.split(":");
+        if (!(parts.length == 2)) {
+          shellState.printException(new Exception("Object and Method must be supplied"));
+          return;
+        }
+        String objectName = parts[0];
+        String methodName = parts[1];
+        Object obj = engine.get(objectName);
+        inv.invokeMethod(obj, methodName, args);
+        
+      }
+    } catch (Exception e) {
+      shellState.printException(e);
+    }
+  }
+  
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/SetAuthsCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/SetAuthsCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/SetAuthsCommand.java
new file mode 100644
index 0000000..cc99cbb
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/SetAuthsCommand.java
@@ -0,0 +1,77 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Token;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.OptionGroup;
+import org.apache.commons.cli.Options;
+
+public class SetAuthsCommand extends Command {
+  private Option userOpt;
+  private Option scanOptAuths;
+  private Option clearOptAuths;
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException {
+    final String user = cl.getOptionValue(userOpt.getOpt(), shellState.getConnector().whoami());
+    final String scanOpts = cl.hasOption(clearOptAuths.getOpt()) ? null : cl.getOptionValue(scanOptAuths.getOpt());
+    shellState.getConnector().securityOperations().changeUserAuthorizations(user, ScanCommand.parseAuthorizations(scanOpts));
+    Shell.log.debug("Changed record-level authorizations for user " + user);
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "sets the maximum scan authorizations for a user";
+  }
+  
+  @Override
+  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> completionSet) {
+    registerCompletionForUsers(root, completionSet);
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+    final OptionGroup setOrClear = new OptionGroup();
+    scanOptAuths = new Option("s", "scan-authorizations", true, "scan authorizations to set");
+    scanOptAuths.setArgName("comma-separated-authorizations");
+    setOrClear.addOption(scanOptAuths);
+    clearOptAuths = new Option("c", "clear-authorizations", false, "clear the scan authorizations");
+    setOrClear.addOption(clearOptAuths);
+    setOrClear.setRequired(true);
+    o.addOptionGroup(setOrClear);
+    userOpt = new Option(Shell.userOption, "user", true, "user to operate on");
+    userOpt.setArgName("user");
+    o.addOption(userOpt);
+    return o;
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/SetGroupsCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/SetGroupsCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/SetGroupsCommand.java
new file mode 100644
index 0000000..fc8b06e
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/SetGroupsCommand.java
@@ -0,0 +1,78 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Options;
+import org.apache.hadoop.io.Text;
+
+public class SetGroupsCommand extends Command {
+  @Override
+  public String description() {
+    return "sets the locality groups for a given table (for binary or commas, use Java API)";
+  }
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    final String tableName = OptUtil.getTableOpt(cl, shellState);
+    
+    final HashMap<String,Set<Text>> groups = new HashMap<String,Set<Text>>();
+    
+    for (String arg : cl.getArgs()) {
+      final String sa[] = arg.split("=", 2);
+      if (sa.length < 2) {
+        throw new IllegalArgumentException("Missing '='");
+      }
+      final String group = sa[0];
+      final HashSet<Text> colFams = new HashSet<Text>();
+      
+      for (String family : sa[1].split(",")) {
+        colFams.add(new Text(family.getBytes(Shell.CHARSET)));
+      }
+      
+      groups.put(group, colFams);
+    }
+    
+    shellState.getConnector().tableOperations().setLocalityGroups(tableName, groups);
+    
+    return 0;
+  }
+  
+  @Override
+  public int numArgs() {
+    return Shell.NO_FIXED_ARG_LENGTH_CHECK;
+  }
+  
+  @Override
+  public String usage() {
+    return getName() + " <group>=<col fam>{,<col fam>}{ <group>=<col fam>{,<col fam>}}";
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options opts = new Options();
+    opts.addOption(OptUtil.tableOpt("table to fetch locality groups for"));
+    return opts;
+  }
+  
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/SetIterCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/SetIterCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/SetIterCommand.java
new file mode 100644
index 0000000..a398b3a
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/SetIterCommand.java
@@ -0,0 +1,453 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.io.IOException;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import jline.console.ConsoleReader;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.IteratorSetting;
+import org.apache.accumulo.core.client.NamespaceNotFoundException;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.core.conf.Property;
+import org.apache.accumulo.core.data.Key;
+import org.apache.accumulo.core.data.Value;
+import org.apache.accumulo.core.iterators.IteratorUtil.IteratorScope;
+import org.apache.accumulo.core.iterators.OptionDescriber;
+import org.apache.accumulo.core.iterators.OptionDescriber.IteratorOptions;
+import org.apache.accumulo.core.iterators.SortedKeyValueIterator;
+import org.apache.accumulo.core.iterators.user.AgeOffFilter;
+import org.apache.accumulo.core.iterators.user.RegExFilter;
+import org.apache.accumulo.core.iterators.user.ReqVisFilter;
+import org.apache.accumulo.core.iterators.user.VersioningIterator;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.ShellCommandException;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.accumulo.shell.ShellCommandException.ErrorCode;
+import org.apache.accumulo.start.classloader.vfs.AccumuloVFSClassLoader;
+import org.apache.accumulo.start.classloader.vfs.ContextManager;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.OptionGroup;
+import org.apache.commons.cli.Options;
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.vfs2.FileSystemException;
+
+public class SetIterCommand extends Command {
+
+  private Option allScopeOpt, mincScopeOpt, majcScopeOpt, scanScopeOpt, nameOpt, priorityOpt;
+  private Option aggTypeOpt, ageoffTypeOpt, regexTypeOpt, versionTypeOpt, reqvisTypeOpt, classnameTypeOpt;
+
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException,
+      TableNotFoundException, IOException, ShellCommandException {
+
+    boolean tables = cl.hasOption(OptUtil.tableOpt().getOpt()) || !shellState.getTableName().isEmpty();
+    boolean namespaces = cl.hasOption(OptUtil.namespaceOpt().getOpt());
+
+    final int priority = Integer.parseInt(cl.getOptionValue(priorityOpt.getOpt()));
+
+    final Map<String,String> options = new HashMap<String,String>();
+    String classname = cl.getOptionValue(classnameTypeOpt.getOpt());
+    if (cl.hasOption(aggTypeOpt.getOpt())) {
+      Shell.log.warn("aggregators are deprecated");
+      @SuppressWarnings("deprecation")
+      String deprecatedClassName = org.apache.accumulo.core.iterators.AggregatingIterator.class.getName();
+      classname = deprecatedClassName;
+    } else if (cl.hasOption(regexTypeOpt.getOpt())) {
+      classname = RegExFilter.class.getName();
+    } else if (cl.hasOption(ageoffTypeOpt.getOpt())) {
+      classname = AgeOffFilter.class.getName();
+    } else if (cl.hasOption(versionTypeOpt.getOpt())) {
+      classname = VersioningIterator.class.getName();
+    } else if (cl.hasOption(reqvisTypeOpt.getOpt())) {
+      classname = ReqVisFilter.class.getName();
+    }
+
+    ClassLoader classloader = getClassLoader(cl, shellState);
+
+    // Get the iterator options, with potentially a name provided by the OptionDescriber impl or through user input
+    String configuredName = setUpOptions(classloader, shellState.getReader(), classname, options);
+
+    // Try to get the name provided by the setiter command
+    String name = cl.getOptionValue(nameOpt.getOpt(), null);
+    
+    // Cannot continue if no name is provided
+    if (null == name && null == configuredName) {
+      throw new IllegalArgumentException("No provided or default name for iterator");
+    } else if (null == name) {
+      // Fall back to the name from OptionDescriber or user input if none is provided on setiter option
+      name = configuredName;
+    }
+
+    if (namespaces) {
+      try {
+        setNamespaceProperties(cl, shellState, priority, options, classname, name);
+      } catch (NamespaceNotFoundException e) {
+        throw new IllegalArgumentException(e);
+      }
+    } else if (tables) {
+      setTableProperties(cl, shellState, priority, options, classname, name);
+    } else {
+      throw new IllegalArgumentException("No table or namespace specified");
+    }
+    return 0;
+  }
+
+  private ClassLoader getClassLoader(final CommandLine cl, final Shell shellState) throws AccumuloException, TableNotFoundException, AccumuloSecurityException,
+      IOException, FileSystemException {
+
+    boolean tables = cl.hasOption(OptUtil.tableOpt().getOpt()) || !shellState.getTableName().isEmpty();
+    boolean namespaces = cl.hasOption(OptUtil.namespaceOpt().getOpt());
+
+    String classpath = null;
+    Iterable<Entry<String,String>> tableProps;
+
+    if (namespaces) {
+      try {
+        tableProps = shellState.getConnector().namespaceOperations().getProperties(OptUtil.getNamespaceOpt(cl, shellState));
+      } catch (NamespaceNotFoundException e) {
+        throw new IllegalArgumentException(e);
+      }
+    } else if (tables) {
+      tableProps = shellState.getConnector().tableOperations().getProperties(OptUtil.getTableOpt(cl, shellState));
+    } else {
+      throw new IllegalArgumentException("No table or namespace specified");
+    }
+    for (Entry<String,String> entry : tableProps) {
+      if (entry.getKey().equals(Property.TABLE_CLASSPATH.getKey())) {
+        classpath = entry.getValue();
+      }
+    }
+
+    ClassLoader classloader;
+
+    if (classpath != null && !classpath.equals("")) {
+      shellState.getConnector().instanceOperations().getSystemConfiguration().get(Property.VFS_CONTEXT_CLASSPATH_PROPERTY.getKey() + classpath);
+
+      try {
+        AccumuloVFSClassLoader.getContextManager().setContextConfig(new ContextManager.DefaultContextsConfig(new Iterable<Map.Entry<String,String>>() {
+          @Override
+          public Iterator<Entry<String,String>> iterator() {
+            try {
+              return shellState.getConnector().instanceOperations().getSystemConfiguration().entrySet().iterator();
+            } catch (AccumuloException e) {
+              throw new RuntimeException(e);
+            } catch (AccumuloSecurityException e) {
+              throw new RuntimeException(e);
+            }
+          }
+        }));
+      } catch (IllegalStateException ise) {}
+
+      classloader = AccumuloVFSClassLoader.getContextManager().getClassLoader(classpath);
+    } else {
+      classloader = AccumuloVFSClassLoader.getClassLoader();
+    }
+    return classloader;
+  }
+
+  protected void setTableProperties(final CommandLine cl, final Shell shellState, final int priority, final Map<String,String> options, final String classname,
+      final String name) throws AccumuloException, AccumuloSecurityException, ShellCommandException, TableNotFoundException {
+    // remove empty values
+
+    final String tableName = OptUtil.getTableOpt(cl, shellState);
+
+    if (!shellState.getConnector().tableOperations().testClassLoad(tableName, classname, SortedKeyValueIterator.class.getName())) {
+      throw new ShellCommandException(ErrorCode.INITIALIZATION_FAILURE, "Servers are unable to load " + classname + " as type "
+          + SortedKeyValueIterator.class.getName());
+    }
+
+    final String aggregatorClass = options.get("aggregatorClass");
+    @SuppressWarnings("deprecation")
+    String deprecatedAggregatorClassName = org.apache.accumulo.core.iterators.aggregation.Aggregator.class.getName();
+    if (aggregatorClass != null && !shellState.getConnector().tableOperations().testClassLoad(tableName, aggregatorClass, deprecatedAggregatorClassName)) {
+      throw new ShellCommandException(ErrorCode.INITIALIZATION_FAILURE, "Servers are unable to load " + aggregatorClass + " as type "
+          + deprecatedAggregatorClassName);
+    }
+
+    for (Iterator<Entry<String,String>> i = options.entrySet().iterator(); i.hasNext();) {
+      final Entry<String,String> entry = i.next();
+      if (entry.getValue() == null || entry.getValue().isEmpty()) {
+        i.remove();
+      }
+    }
+    final EnumSet<IteratorScope> scopes = EnumSet.noneOf(IteratorScope.class);
+    if (cl.hasOption(allScopeOpt.getOpt()) || cl.hasOption(mincScopeOpt.getOpt())) {
+      scopes.add(IteratorScope.minc);
+    }
+    if (cl.hasOption(allScopeOpt.getOpt()) || cl.hasOption(majcScopeOpt.getOpt())) {
+      scopes.add(IteratorScope.majc);
+    }
+    if (cl.hasOption(allScopeOpt.getOpt()) || cl.hasOption(scanScopeOpt.getOpt())) {
+      scopes.add(IteratorScope.scan);
+    }
+    if (scopes.isEmpty()) {
+      throw new IllegalArgumentException("You must select at least one scope to configure");
+    }
+    final IteratorSetting setting = new IteratorSetting(priority, name, classname, options);
+    shellState.getConnector().tableOperations().attachIterator(tableName, setting, scopes);
+  }
+
+  protected void setNamespaceProperties(final CommandLine cl, final Shell shellState, final int priority, final Map<String,String> options,
+      final String classname, final String name) throws AccumuloException, AccumuloSecurityException, ShellCommandException, NamespaceNotFoundException {
+    // remove empty values
+
+    final String namespace = OptUtil.getNamespaceOpt(cl, shellState);
+
+    if (!shellState.getConnector().namespaceOperations().testClassLoad(namespace, classname, SortedKeyValueIterator.class.getName())) {
+      throw new ShellCommandException(ErrorCode.INITIALIZATION_FAILURE, "Servers are unable to load " + classname + " as type "
+          + SortedKeyValueIterator.class.getName());
+    }
+
+    final String aggregatorClass = options.get("aggregatorClass");
+    @SuppressWarnings("deprecation")
+    String deprecatedAggregatorClassName = org.apache.accumulo.core.iterators.aggregation.Aggregator.class.getName();
+    if (aggregatorClass != null && !shellState.getConnector().namespaceOperations().testClassLoad(namespace, aggregatorClass, deprecatedAggregatorClassName)) {
+      throw new ShellCommandException(ErrorCode.INITIALIZATION_FAILURE, "Servers are unable to load " + aggregatorClass + " as type "
+          + deprecatedAggregatorClassName);
+    }
+
+    for (Iterator<Entry<String,String>> i = options.entrySet().iterator(); i.hasNext();) {
+      final Entry<String,String> entry = i.next();
+      if (entry.getValue() == null || entry.getValue().isEmpty()) {
+        i.remove();
+      }
+    }
+    final EnumSet<IteratorScope> scopes = EnumSet.noneOf(IteratorScope.class);
+    if (cl.hasOption(allScopeOpt.getOpt()) || cl.hasOption(mincScopeOpt.getOpt())) {
+      scopes.add(IteratorScope.minc);
+    }
+    if (cl.hasOption(allScopeOpt.getOpt()) || cl.hasOption(majcScopeOpt.getOpt())) {
+      scopes.add(IteratorScope.majc);
+    }
+    if (cl.hasOption(allScopeOpt.getOpt()) || cl.hasOption(scanScopeOpt.getOpt())) {
+      scopes.add(IteratorScope.scan);
+    }
+    if (scopes.isEmpty()) {
+      throw new IllegalArgumentException("You must select at least one scope to configure");
+    }
+    final IteratorSetting setting = new IteratorSetting(priority, name, classname, options);
+    shellState.getConnector().namespaceOperations().attachIterator(namespace, setting, scopes);
+  }
+
+  private static String setUpOptions(ClassLoader classloader, final ConsoleReader reader, final String className, final Map<String,String> options)
+      throws IOException, ShellCommandException {
+    String input;
+    @SuppressWarnings("rawtypes")
+    SortedKeyValueIterator untypedInstance;
+    @SuppressWarnings("rawtypes")
+    Class<? extends SortedKeyValueIterator> clazz;
+    try {
+      clazz = classloader.loadClass(className).asSubclass(SortedKeyValueIterator.class);
+      untypedInstance = clazz.newInstance();
+    } catch (ClassNotFoundException e) {
+      StringBuilder msg = new StringBuilder("Unable to load ").append(className);
+      if (className.indexOf('.') < 0) {
+        msg.append("; did you use a fully qualified package name?");
+      } else {
+        msg.append("; class not found.");
+      }
+      throw new ShellCommandException(ErrorCode.INITIALIZATION_FAILURE, msg.toString());
+    } catch (InstantiationException e) {
+      throw new IllegalArgumentException(e.getMessage());
+    } catch (IllegalAccessException e) {
+      throw new IllegalArgumentException(e.getMessage());
+    } catch (ClassCastException e) {
+      StringBuilder msg = new StringBuilder(50);
+      msg.append(className).append(" loaded successfully but does not implement SortedKeyValueIterator.");
+      msg.append(" This class cannot be used with this command.");
+      throw new ShellCommandException(ErrorCode.INITIALIZATION_FAILURE, msg.toString());
+    }
+
+    @SuppressWarnings("unchecked")
+    SortedKeyValueIterator<Key,Value> skvi = (SortedKeyValueIterator<Key,Value>) untypedInstance;
+    OptionDescriber iterOptions = null;
+    if (OptionDescriber.class.isAssignableFrom(skvi.getClass())) {
+      iterOptions = (OptionDescriber) skvi;
+    }
+
+    String iteratorName;
+    if (null != iterOptions) {
+      final IteratorOptions itopts = iterOptions.describeOptions();
+      iteratorName = itopts.getName();
+      
+      if (iteratorName == null) {
+        throw new IllegalArgumentException(className + " described its default distinguishing name as null");
+      }
+      String shortClassName = className;
+      if (className.contains(".")) {
+        shortClassName = className.substring(className.lastIndexOf('.') + 1);
+      }
+      final Map<String,String> localOptions = new HashMap<String,String>();
+      do {
+        // clean up the overall options that caused things to fail
+        for (String key : localOptions.keySet()) {
+          options.remove(key);
+        }
+        localOptions.clear();
+  
+        reader.println(itopts.getDescription());
+  
+        String prompt;
+        if (itopts.getNamedOptions() != null) {
+          for (Entry<String,String> e : itopts.getNamedOptions().entrySet()) {
+            prompt = Shell.repeat("-", 10) + "> set " + shortClassName + " parameter " + e.getKey() + ", " + e.getValue() + ": ";
+            reader.flush();
+            input = reader.readLine(prompt);
+            if (input == null) {
+              reader.println();
+              throw new IOException("Input stream closed");
+            }
+            // Places all Parameters and Values into the LocalOptions, even if the value is "".
+            // This allows us to check for "" values when setting the iterators and allows us to remove
+            // the parameter and value from the table property.
+            localOptions.put(e.getKey(), input);
+          }
+        }
+  
+        if (itopts.getUnnamedOptionDescriptions() != null) {
+          for (String desc : itopts.getUnnamedOptionDescriptions()) {
+            reader.println(Shell.repeat("-", 10) + "> entering options: " + desc);
+            input = "start";
+            prompt = Shell.repeat("-", 10) + "> set " + shortClassName + " option (<name> <value>, hit enter to skip): ";
+            while (true) {
+              reader.flush();
+              input = reader.readLine(prompt);
+              if (input == null) {
+                reader.println();
+                throw new IOException("Input stream closed");
+              } else {
+                input = new String(input);
+              }
+  
+              if (input.length() == 0)
+                break;
+  
+              String[] sa = input.split(" ", 2);
+              localOptions.put(sa[0], sa[1]);
+            }
+          }
+        }
+  
+        options.putAll(localOptions);
+        if (!iterOptions.validateOptions(options))
+          reader.println("invalid options for " + clazz.getName());
+  
+      } while (!iterOptions.validateOptions(options));
+    } else {
+      reader.flush();
+      reader.println("The iterator class does not implement OptionDescriber. Consider this for better iterator configuration using this setiter command.");
+      iteratorName = reader.readLine("Name for iterator (enter to skip): ");
+      if (null == iteratorName) {
+        reader.println();
+        throw new IOException("Input stream closed");
+      } else if (StringUtils.isWhitespace(iteratorName)) {
+        // Treat whitespace or empty string as no name provided
+        iteratorName = null;
+      }
+      
+      reader.flush();
+      reader.println("Optional, configure name-value options for iterator:");
+      String prompt = Shell.repeat("-", 10) + "> set option (<name> <value>, hit enter to skip): ";
+      final HashMap<String,String> localOptions = new HashMap<String,String>();
+      
+      while (true) {
+        reader.flush();
+        input = reader.readLine(prompt);
+        if (input == null) {
+          reader.println();
+          throw new IOException("Input stream closed");
+        } else if (StringUtils.isWhitespace(input)) {
+          break;
+        } 
+
+        String[] sa = input.split(" ", 2);
+        localOptions.put(sa[0], sa[1]);
+      }
+      
+      options.putAll(localOptions);
+    }
+    
+    return iteratorName;
+  }
+
+  @Override
+  public String description() {
+    return "sets a table-specific or namespace-specific iterator";
+  }
+
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+
+    priorityOpt = new Option("p", "priority", true, "the order in which the iterator is applied");
+    priorityOpt.setArgName("pri");
+    priorityOpt.setRequired(true);
+
+    nameOpt = new Option("n", "name", true, "iterator to set");
+    nameOpt.setArgName("itername");
+
+    allScopeOpt = new Option("all", "all-scopes", false, "applied at scan time, minor and major compactions");
+    mincScopeOpt = new Option(IteratorScope.minc.name(), "minor-compaction", false, "applied at minor compaction");
+    majcScopeOpt = new Option(IteratorScope.majc.name(), "major-compaction", false, "applied at major compaction");
+    scanScopeOpt = new Option(IteratorScope.scan.name(), "scan-time", false, "applied at scan time");
+
+    final OptionGroup typeGroup = new OptionGroup();
+    classnameTypeOpt = new Option("class", "class-name", true, "a java class that implements SortedKeyValueIterator");
+    classnameTypeOpt.setArgName("name");
+    aggTypeOpt = new Option("agg", "aggregator", false, "an aggregating type");
+    regexTypeOpt = new Option("regex", "regular-expression", false, "a regex matching iterator");
+    versionTypeOpt = new Option("vers", "version", false, "a versioning iterator");
+    reqvisTypeOpt = new Option("reqvis", "require-visibility", false, "an iterator that omits entries with empty visibilities");
+    ageoffTypeOpt = new Option("ageoff", "ageoff", false, "an aging off iterator");
+
+    typeGroup.addOption(classnameTypeOpt);
+    typeGroup.addOption(aggTypeOpt);
+    typeGroup.addOption(regexTypeOpt);
+    typeGroup.addOption(versionTypeOpt);
+    typeGroup.addOption(reqvisTypeOpt);
+    typeGroup.addOption(ageoffTypeOpt);
+    typeGroup.setRequired(true);
+
+    final OptionGroup tableGroup = new OptionGroup();
+    tableGroup.addOption(OptUtil.tableOpt("table to configure iterators on"));
+    tableGroup.addOption(OptUtil.namespaceOpt("namespace to configure iterators on"));
+
+    o.addOption(priorityOpt);
+    o.addOption(nameOpt);
+    o.addOption(allScopeOpt);
+    o.addOption(mincScopeOpt);
+    o.addOption(majcScopeOpt);
+    o.addOption(scanScopeOpt);
+    o.addOptionGroup(typeGroup);
+    o.addOptionGroup(tableGroup);
+    return o;
+  }
+
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/SetScanIterCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/SetScanIterCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/SetScanIterCommand.java
new file mode 100644
index 0000000..3ae42dd
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/SetScanIterCommand.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.accumulo.shell.commands;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.IteratorSetting;
+import org.apache.accumulo.core.client.Scanner;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.core.iterators.IteratorUtil.IteratorScope;
+import org.apache.accumulo.core.iterators.SortedKeyValueIterator;
+import org.apache.accumulo.core.security.Authorizations;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.ShellCommandException;
+import org.apache.accumulo.shell.ShellCommandException.ErrorCode;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.OptionGroup;
+import org.apache.commons.cli.Options;
+
+public class SetScanIterCommand extends SetIterCommand {
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException, TableNotFoundException,
+      IOException, ShellCommandException {
+    Shell.log.warn("Deprecated, use " + new SetShellIterCommand().getName());
+    return super.execute(fullCommand, cl, shellState);
+  }
+  
+  @Override
+  protected void setTableProperties(final CommandLine cl, final Shell shellState, final int priority, final Map<String,String> options, final String classname,
+      final String name) throws AccumuloException, AccumuloSecurityException, ShellCommandException, TableNotFoundException {
+    
+    final String tableName = OptUtil.getTableOpt(cl, shellState);
+
+    // instead of setting table properties, just put the options in a list to use at scan time
+    Class<?> loadClass;
+    try {
+      loadClass = getClass().getClassLoader().loadClass(classname);
+    } catch (ClassNotFoundException e) {
+      throw new ShellCommandException(ErrorCode.INITIALIZATION_FAILURE, "Unable to load " + classname);
+    }
+    try {
+      loadClass.asSubclass(SortedKeyValueIterator.class);
+    } catch (ClassCastException ex) {
+      throw new ShellCommandException(ErrorCode.INITIALIZATION_FAILURE, "Unable to load " + classname  + " as type "
+          + SortedKeyValueIterator.class.getName());
+    }
+    
+    for (Iterator<Entry<String,String>> i = options.entrySet().iterator(); i.hasNext();) {
+      final Entry<String,String> entry = i.next();
+      if (entry.getValue() == null || entry.getValue().isEmpty()) {
+        i.remove();
+      }
+    }
+
+    List<IteratorSetting> tableScanIterators = shellState.scanIteratorOptions.get(tableName);
+    if (tableScanIterators == null) {
+      tableScanIterators = new ArrayList<IteratorSetting>();
+      shellState.scanIteratorOptions.put(tableName, tableScanIterators);
+    }
+    final IteratorSetting setting = new IteratorSetting(priority, name, classname);
+    setting.addOptions(options);
+    
+    // initialize a scanner to ensure the new setting does not conflict with existing settings
+    final String user = shellState.getConnector().whoami();
+    final Authorizations auths = shellState.getConnector().securityOperations().getUserAuthorizations(user);
+    final Scanner scanner = shellState.getConnector().createScanner(tableName, auths);
+    for (IteratorSetting s : tableScanIterators) {
+      scanner.addScanIterator(s);
+    }
+    scanner.addScanIterator(setting);
+    
+    // if no exception has been thrown, it's safe to add it to the list
+    tableScanIterators.add(setting);
+    Shell.log.debug("Scan iterators :" + shellState.scanIteratorOptions.get(tableName));
+  }
+  
+  @Override
+  public String description() {
+    return "sets a table-specific scan iterator for this shell session";
+  }
+  
+  @Override
+  public Options getOptions() {
+    // Remove the options that specify which type of iterator this is, since
+    // they are all scan iterators with this command.
+    final HashSet<OptionGroup> groups = new HashSet<OptionGroup>();
+    final Options parentOptions = super.getOptions();
+    final Options modifiedOptions = new Options();
+    for (Iterator<?> it = parentOptions.getOptions().iterator(); it.hasNext();) {
+      Option o = (Option) it.next();
+      if (!IteratorScope.majc.name().equals(o.getOpt()) && !IteratorScope.minc.name().equals(o.getOpt()) && !IteratorScope.scan.name().equals(o.getOpt())) {
+        modifiedOptions.addOption(o);
+        OptionGroup group = parentOptions.getOptionGroup(o);
+        if (group != null)
+          groups.add(group);
+      }
+    }
+    for (OptionGroup group : groups) {
+      modifiedOptions.addOptionGroup(group);
+    }
+    return modifiedOptions;
+  }
+  
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/SetShellIterCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/SetShellIterCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/SetShellIterCommand.java
new file mode 100644
index 0000000..c7fea56
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/SetShellIterCommand.java
@@ -0,0 +1,131 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.IteratorSetting;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.core.iterators.IteratorUtil.IteratorScope;
+import org.apache.accumulo.core.iterators.SortedKeyValueIterator;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.ShellCommandException;
+import org.apache.accumulo.shell.ShellCommandException.ErrorCode;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.OptionGroup;
+import org.apache.commons.cli.Options;
+
+public class SetShellIterCommand extends SetIterCommand {
+  private Option profileOpt;
+
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException,
+      TableNotFoundException, IOException, ShellCommandException {
+    return super.execute(fullCommand, cl, shellState);
+  }
+  
+  @Override
+  protected void setTableProperties(final CommandLine cl, final Shell shellState, final int priority, final Map<String,String> options, final String classname,
+      final String name) throws AccumuloException, AccumuloSecurityException, ShellCommandException, TableNotFoundException {
+    // instead of setting table properties, just put the options in a list to use at scan time
+    
+    String profile = cl.getOptionValue(profileOpt.getOpt());
+
+    // instead of setting table properties, just put the options in a list to use at scan time
+    Class<?> loadClass;
+    try {
+      loadClass = getClass().getClassLoader().loadClass(classname);
+    } catch (ClassNotFoundException e) {
+      throw new ShellCommandException(ErrorCode.INITIALIZATION_FAILURE, "Unable to load " + classname);
+    }
+    try {
+      loadClass.asSubclass(SortedKeyValueIterator.class);
+    } catch (ClassCastException ex) {
+      throw new ShellCommandException(ErrorCode.INITIALIZATION_FAILURE, "xUnable to load " + classname  + " as type "
+          + SortedKeyValueIterator.class.getName());
+    }
+    
+    for (Iterator<Entry<String,String>> i = options.entrySet().iterator(); i.hasNext();) {
+      final Entry<String,String> entry = i.next();
+      if (entry.getValue() == null || entry.getValue().isEmpty()) {
+        i.remove();
+      }
+    }
+
+    List<IteratorSetting> tableScanIterators = shellState.iteratorProfiles.get(profile);
+    if (tableScanIterators == null) {
+      tableScanIterators = new ArrayList<IteratorSetting>();
+      shellState.iteratorProfiles.put(profile, tableScanIterators);
+    }
+    final IteratorSetting setting = new IteratorSetting(priority, name, classname);
+    setting.addOptions(options);
+
+    Iterator<IteratorSetting> iter = tableScanIterators.iterator();
+    while (iter.hasNext()) {
+      if (iter.next().getName().equals(name)) {
+        iter.remove();
+      }
+    }
+
+    tableScanIterators.add(setting);
+  }
+  
+  @Override
+  public String description() {
+    return "adds an iterator to a profile for this shell session";
+  }
+  
+  @Override
+  public Options getOptions() {
+    // Remove the options that specify which type of iterator this is, since
+    // they are all scan iterators with this command.
+    final HashSet<OptionGroup> groups = new HashSet<OptionGroup>();
+    final Options parentOptions = super.getOptions();
+    final Options modifiedOptions = new Options();
+    for (Iterator<?> it = parentOptions.getOptions().iterator(); it.hasNext();) {
+      Option o = (Option) it.next();
+      if (!IteratorScope.majc.name().equals(o.getOpt()) && !IteratorScope.minc.name().equals(o.getOpt()) && !IteratorScope.scan.name().equals(o.getOpt())
+          && !"table".equals(o.getLongOpt())) {
+        modifiedOptions.addOption(o);
+        OptionGroup group = parentOptions.getOptionGroup(o);
+        if (group != null)
+          groups.add(group);
+      }
+    }
+    for (OptionGroup group : groups) {
+      modifiedOptions.addOptionGroup(group);
+    }
+    
+    profileOpt = new Option("pn", "profile", true, "iterator profile name");
+    profileOpt.setRequired(true);
+    profileOpt.setArgName("profile");
+    
+    modifiedOptions.addOption(profileOpt);
+
+    return modifiedOptions;
+  }
+  
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/ShellPluginConfigurationCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/ShellPluginConfigurationCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/ShellPluginConfigurationCommand.java
new file mode 100644
index 0000000..45d48e7
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/ShellPluginConfigurationCommand.java
@@ -0,0 +1,146 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.util.Iterator;
+import java.util.Map.Entry;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.core.conf.Property;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.accumulo.start.classloader.vfs.AccumuloVFSClassLoader;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.OptionGroup;
+import org.apache.commons.cli.Options;
+import org.apache.log4j.Logger;
+
+public abstract class ShellPluginConfigurationCommand extends Command {
+  private Option removePluginOption, pluginClassOption, listPluginOption;
+  
+  private String pluginType;
+  
+  private Property tableProp;
+  
+  private String classOpt;
+  
+  ShellPluginConfigurationCommand(final String typeName, final Property tableProp, final String classOpt) {
+    this.pluginType = typeName;
+    this.tableProp = tableProp;
+    this.classOpt = classOpt;
+  }
+
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    final String tableName = OptUtil.getTableOpt(cl, shellState);
+    
+    if (cl.hasOption(removePluginOption.getOpt())) {
+      // Remove the property
+      removePlugin(cl, shellState, tableName);
+      
+      shellState.getReader().println("Removed "+pluginType+" on " + tableName);
+    } else if (cl.hasOption(listPluginOption.getOpt())) {
+      // Get the options for this table
+      final Iterator<Entry<String,String>> iter = shellState.getConnector().tableOperations().getProperties(tableName).iterator();
+      
+      while (iter.hasNext()) {
+        Entry<String,String> ent = iter.next();
+        
+        // List all parameters with the property name
+        if (ent.getKey().startsWith(tableProp.toString())) {
+          shellState.getReader().println(ent.getKey() + ": " + ent.getValue());
+        }
+      }
+    } else {
+      // Set the plugin with the provided options
+      String className = cl.getOptionValue(pluginClassOption.getOpt());
+      
+      // Set the plugin property on the table
+      setPlugin(cl, shellState, tableName, className);
+    }
+    
+    return 0;
+  }
+
+  protected void setPlugin(final CommandLine cl, final Shell shellState, final String tableName, final String className) throws AccumuloException, AccumuloSecurityException {
+    shellState.getConnector().tableOperations().setProperty(tableName, tableProp.toString(), className);
+  }
+  
+  protected void removePlugin(final CommandLine cl, final Shell shellState, final String tableName) throws AccumuloException, AccumuloSecurityException {
+    shellState.getConnector().tableOperations().removeProperty(tableName, tableProp.toString());
+  }
+  
+  public static <T> Class<? extends T> getPluginClass(final String tableName, final Shell shellState, final Class<T> clazz, final Property pluginProp) {
+    Iterator<Entry<String,String>> props;
+    try {
+      props = shellState.getConnector().tableOperations().getProperties(tableName).iterator();
+    } catch (AccumuloException e) {
+      return null;
+    } catch (TableNotFoundException e) {
+      return null;
+    }
+    
+    while (props.hasNext()) {
+      final Entry<String,String> ent = props.next();
+      if (ent.getKey().equals(pluginProp.toString())) {
+        Class<? extends T> pluginClazz;
+        try {
+          pluginClazz = AccumuloVFSClassLoader.loadClass(ent.getValue(), clazz);
+        } catch (ClassNotFoundException e) {
+          Logger.getLogger(ShellPluginConfigurationCommand.class).warn("Class not found" + e.getMessage());
+          return null;
+        }
+        
+        return pluginClazz;
+      }
+    }
+    
+    return null;
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+    final OptionGroup actionGroup = new OptionGroup();
+    
+    pluginClassOption = new Option(classOpt, pluginType, true, "fully qualified name of the " + pluginType + " class to use");
+    pluginClassOption.setArgName("className");
+    
+    // Action to take: apply (default), remove, list
+    removePluginOption = new Option("r", "remove", false, "remove the current "+pluginType+"");
+    listPluginOption = new Option("l", "list", false, "display the current "+pluginType+"");
+    
+    actionGroup.addOption(pluginClassOption);
+    actionGroup.addOption(removePluginOption);
+    actionGroup.addOption(listPluginOption);
+    actionGroup.setRequired(true);
+    
+    o.addOptionGroup(actionGroup);
+    o.addOption(OptUtil.tableOpt("table to set the "+pluginType+" on"));
+    
+    return o;
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+  
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/SleepCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/SleepCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/SleepCommand.java
new file mode 100644
index 0000000..1f7ed5d
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/SleepCommand.java
@@ -0,0 +1,46 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+
+public class SleepCommand extends Command {
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    final double secs = Double.parseDouble(cl.getArgs()[0]);
+    Thread.sleep((long) (secs * 1000));
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "sleeps for the given number of seconds";
+  }
+  
+  @Override
+  public int numArgs() {
+    return 1;
+  }
+  
+  @Override
+  public String usage() {
+    return getName() + " <seconds>";
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/SystemPermissionsCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/SystemPermissionsCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/SystemPermissionsCommand.java
new file mode 100644
index 0000000..7cf4584
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/SystemPermissionsCommand.java
@@ -0,0 +1,44 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.io.IOException;
+
+import org.apache.accumulo.core.security.SystemPermission;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+
+public class SystemPermissionsCommand extends Command {
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws IOException {
+    for (String p : SystemPermission.printableValues()) {
+      shellState.getReader().println(p);
+    }
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "displays a list of valid system permissions";
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/TableCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/TableCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/TableCommand.java
new file mode 100644
index 0000000..6a563ab
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/TableCommand.java
@@ -0,0 +1,60 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Token;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+
+public class TableCommand extends Command {
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException, TableNotFoundException {
+    final String tableName = cl.getArgs()[0];
+    if (!shellState.getConnector().tableOperations().exists(tableName)) {
+      throw new TableNotFoundException(null, tableName, null);
+    }
+    shellState.setTableName(tableName);
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "switches to the specified table";
+  }
+  
+  @Override
+  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> special) {
+    registerCompletionForTables(root, special);
+  }
+  
+  @Override
+  public String usage() {
+    return getName() + " <tableName>";
+  }
+  
+  @Override
+  public int numArgs() {
+    return 1;
+  }
+}


[32/53] [abbrv] Revert "ACCUMULO-1897 Move shell into new package and module"

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/ShellOptionsJC.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/ShellOptionsJC.java b/core/src/main/java/org/apache/accumulo/core/util/shell/ShellOptionsJC.java
new file mode 100644
index 0000000..38692a0
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/ShellOptionsJC.java
@@ -0,0 +1,280 @@
+/*
+ * 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.accumulo.core.util.shell;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Scanner;
+import java.util.TreeMap;
+
+import org.apache.accumulo.core.client.ClientConfiguration;
+import org.apache.accumulo.core.client.ClientConfiguration.ClientProperty;
+import org.apache.accumulo.core.client.security.tokens.AuthenticationToken;
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.commons.configuration.PropertiesConfiguration;
+import org.apache.log4j.Logger;
+
+import com.beust.jcommander.DynamicParameter;
+import com.beust.jcommander.IStringConverter;
+import com.beust.jcommander.Parameter;
+import com.beust.jcommander.ParameterException;
+import com.beust.jcommander.converters.FileConverter;
+
+public class ShellOptionsJC {
+  // Use the Shell logger because this is really just an extension.
+  public static final Logger log = Logger.getLogger(Shell.class);
+
+  @Parameter(names = {"-u", "--user"}, description = "username (defaults to your OS user)")
+  private String username = System.getProperty("user.name", "root");
+
+  public static class PasswordConverter implements IStringConverter<String> {
+    public static final String STDIN = "stdin";
+
+    private enum KeyType {
+      PASS("pass:"), ENV("env:") {
+        @Override
+        String process(String value) {
+          return System.getenv(value);
+        }
+      },
+      FILE("file:") {
+        @Override
+        String process(String value) {
+          Scanner scanner = null;
+          try {
+            scanner = new Scanner(new File(value));
+            return scanner.nextLine();
+          } catch (FileNotFoundException e) {
+            throw new ParameterException(e);
+          } finally {
+            if (scanner != null) {
+              scanner.close();
+            }
+          }
+        }
+      },
+      STDIN(PasswordConverter.STDIN) {
+        @Override
+        public boolean matches(String value) {
+          return prefix.equals(value);
+        }
+
+        @Override
+        public String convert(String value) {
+          // Will check for this later
+          return prefix;
+        }
+      };
+
+      String prefix;
+
+      private KeyType(String prefix) {
+        this.prefix = prefix;
+      }
+
+      public boolean matches(String value) {
+        return value.startsWith(prefix);
+      }
+
+      public String convert(String value) {
+        return process(value.substring(prefix.length()));
+      }
+
+      String process(String value) {
+        return value;
+      }
+    };
+
+    @Override
+    public String convert(String value) {
+      for (KeyType keyType : KeyType.values()) {
+        if (keyType.matches(value)) {
+          return keyType.convert(value);
+        }
+      }
+
+      return value;
+    }
+  }
+
+  // Note: Don't use "password = true" because then it will prompt even if we have a token
+  @Parameter(names = {"-p", "--password"}, description = "password (can be specified as 'pass:<password>', 'file:<local file containing the password>', "
+      + "'env:<variable containing the pass>', or stdin)", converter = PasswordConverter.class)
+  private String password;
+
+  public static class TokenConverter implements IStringConverter<AuthenticationToken> {
+    @Override
+    public AuthenticationToken convert(String value) {
+      try {
+        return Class.forName(value).asSubclass(AuthenticationToken.class).newInstance();
+      } catch (Exception e) {
+        // Catching ClassNotFoundException, ClassCastException, InstantiationException and IllegalAccessException
+        throw new ParameterException(e);
+      }
+    }
+  }
+
+  @Parameter(names = {"-tc", "--tokenClass"}, description = "token type to create, use the -l to pass options", converter = TokenConverter.class)
+  private AuthenticationToken authenticationToken;
+
+  @DynamicParameter(names = {"-l", "--tokenProperty"}, description = "login properties in the format key=value. Reuse -l for each property")
+  private Map<String,String> tokenProperties = new TreeMap<String,String>();
+
+  @Parameter(names = "--disable-tab-completion", description = "disables tab completion (for less overhead when scripting)")
+  private boolean tabCompletionDisabled;
+
+  @Parameter(names = "--debug", description = "enables client debugging")
+  private boolean debugEnabled;
+
+  @Parameter(names = "--fake", description = "fake a connection to accumulo")
+  private boolean fake;
+
+  @Parameter(names = {"-?", "--help"}, help = true, description = "display this help")
+  private boolean helpEnabled;
+
+  @Parameter(names = {"-e", "--execute-command"}, description = "executes a command, and then exits")
+  private String execCommand;
+
+  @Parameter(names = {"-f", "--execute-file"}, description = "executes commands from a file at startup", converter = FileConverter.class)
+  private File execFile;
+
+  @Parameter(names = {"-fv", "--execute-file-verbose"}, description = "executes commands from a file at startup, with commands shown",
+      converter = FileConverter.class)
+  private File execFileVerbose;
+
+  @Parameter(names = {"-h", "--hdfsZooInstance"}, description = "use hdfs zoo instance")
+  private boolean hdfsZooInstance;
+
+  @Parameter(names = {"-z", "--zooKeeperInstance"}, description = "use a zookeeper instance with the given instance name and list of zoo hosts", arity = 2)
+  private List<String> zooKeeperInstance = new ArrayList<String>();
+
+  @Parameter(names = {"--ssl"}, description = "use ssl to connect to accumulo")
+  private boolean useSsl = false;
+
+  @Parameter(
+      names = "--config-file",
+      description = "read the given client config file.  If omitted, the path searched can be specified with $ACCUMULO_CLIENT_CONF_PATH, which defaults to ~/.accumulo/config:$ACCUMULO_CONF_DIR/client.conf:/etc/accumulo/client.conf")
+  private String clientConfigFile = null;
+
+  @Parameter(names = {"-zi", "--zooKeeperInstanceName"}, description = "use a zookeeper instance with the given instance name")
+  private String zooKeeperInstanceName;
+
+  @Parameter(names = {"-zh", "--zooKeeperHosts"}, description = "use a zookeeper instance with the given list of zoo hosts")
+  private String zooKeeperHosts;
+
+  @Parameter(names = "--auth-timeout", description = "minutes the shell can be idle without re-entering a password")
+  private int authTimeout = 60; // TODO Add validator for positive number
+
+  @Parameter(names = "--disable-auth-timeout", description = "disables requiring the user to re-type a password after being idle")
+  private boolean authTimeoutDisabled;
+
+  @Parameter(hidden = true)
+  private List<String> unrecognizedOptions;
+
+  public String getUsername() {
+    return username;
+  }
+
+  public String getPassword() {
+    return password;
+  }
+
+  public AuthenticationToken getAuthenticationToken() {
+    return authenticationToken;
+  }
+
+  public Map<String,String> getTokenProperties() {
+    return tokenProperties;
+  }
+
+  public boolean isTabCompletionDisabled() {
+    return tabCompletionDisabled;
+  }
+
+  public boolean isDebugEnabled() {
+    return debugEnabled;
+  }
+
+  public boolean isFake() {
+    return fake;
+  }
+
+  public boolean isHelpEnabled() {
+    return helpEnabled;
+  }
+
+  public String getExecCommand() {
+    return execCommand;
+  }
+
+  public File getExecFile() {
+    return execFile;
+  }
+
+  public File getExecFileVerbose() {
+    return execFileVerbose;
+  }
+
+  public boolean isHdfsZooInstance() {
+    return hdfsZooInstance;
+  }
+
+  public List<String> getZooKeeperInstance() {
+    return zooKeeperInstance;
+  }
+
+  public String getZooKeeperInstanceName() {
+    return zooKeeperInstanceName;
+  }
+
+  public String getZooKeeperHosts() {
+    return zooKeeperHosts;
+  }
+
+  public int getAuthTimeout() {
+    return authTimeout;
+  }
+
+  public boolean isAuthTimeoutDisabled() {
+    return authTimeoutDisabled;
+  }
+
+  public List<String> getUnrecognizedOptions() {
+    return unrecognizedOptions;
+  }
+
+  public boolean useSsl() {
+    return useSsl;
+  }
+
+  public String getClientConfigFile() {
+    return clientConfigFile;
+  }
+
+  public ClientConfiguration getClientConfiguration() throws ConfigurationException, FileNotFoundException {
+    ClientConfiguration clientConfig = clientConfigFile == null ? ClientConfiguration.loadDefault() : new ClientConfiguration(new PropertiesConfiguration(
+        getClientConfigFile()));
+    if (useSsl()) {
+      clientConfig.setProperty(ClientProperty.INSTANCE_RPC_SSL_ENABLED, "true");
+    }
+    return clientConfig;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/ShellUtil.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/ShellUtil.java b/core/src/main/java/org/apache/accumulo/core/util/shell/ShellUtil.java
new file mode 100644
index 0000000..f0dd505
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/ShellUtil.java
@@ -0,0 +1,60 @@
+/*
+ * 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.accumulo.core.util.shell;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.nio.charset.StandardCharsets;
+import java.util.List;
+import java.util.Scanner;
+
+import org.apache.commons.codec.binary.Base64;
+import org.apache.hadoop.io.Text;
+
+import com.google.common.collect.Lists;
+
+public class ShellUtil {
+
+  /**
+   * Scans the given file line-by-line (ignoring empty lines) and returns a list containing those lines. If decode is set to true, every line is decoded using
+   * {@link Base64#decodeBase64(byte[])} from the UTF-8 bytes of that line before inserting in the list.
+   * 
+   * @param filename
+   *          Path to the file that needs to be scanned
+   * @param decode
+   *          Whether to decode lines in the file
+   * @return List of {@link Text} objects containing data in the given file
+   * @throws FileNotFoundException
+   *           if the given file doesn't exist
+   */
+  public static List<Text> scanFile(String filename, boolean decode) throws FileNotFoundException {
+    String line;
+    Scanner file = new Scanner(new File(filename), StandardCharsets.UTF_8.name());
+    List<Text> result = Lists.newArrayList();
+    try {
+      while (file.hasNextLine()) {
+        line = file.nextLine();
+        if (!line.isEmpty()) {
+          result.add(decode ? new Text(Base64.decodeBase64(line.getBytes(StandardCharsets.UTF_8))) : new Text(line));
+        }
+      }
+    } finally {
+      file.close();
+    }
+    return result;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/Token.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/Token.java b/core/src/main/java/org/apache/accumulo/core/util/shell/Token.java
new file mode 100644
index 0000000..b6c5869
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/Token.java
@@ -0,0 +1,137 @@
+/*
+ * 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.accumulo.core.util.shell;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+/*
+ * A token is a word in a command in the shell.  The tree that this builds is used for
+ * tab-completion of tables, users, commands and certain other parts of the shell that
+ * can be realistically and quickly gathered. Tokens can have multiple commands grouped 
+ * together and many possible subcommands, although they are stored in a set so duplicates
+ * aren't allowed.
+ */
+
+public class Token {
+  private Set<String> command = new HashSet<String>();
+  private Set<Token> subcommands = new HashSet<Token>();
+  private boolean caseSensitive = false;
+  
+  public Token() {}
+  
+  public Token(String commandName) {
+    this();
+    command.add(commandName);
+  }
+  
+  public Token(Collection<String> commandNames) {
+    this();
+    command.addAll(commandNames);
+  }
+  
+  public Token(Set<String> commandNames, Set<Token> subCommandNames) {
+    this();
+    command.addAll(commandNames);
+    subcommands.addAll(subCommandNames);
+  }
+  
+  public void setCaseSensitive(boolean cs) {
+    caseSensitive = cs;
+  }
+  
+  public boolean getCaseSensitive() {
+    return caseSensitive;
+  }
+  
+  public Set<String> getCommandNames() {
+    return command;
+  }
+  
+  public Set<Token> getSubcommandList() {
+    return subcommands;
+  }
+  
+  public Token getSubcommand(String name) {
+    Iterator<Token> iter = subcommands.iterator();
+    while (iter.hasNext()) {
+      Token t = iter.next();
+      if (t.containsCommand(name))
+        return t;
+    }
+    return null;
+  }
+  
+  public Set<String> getSubcommandNames() {
+    HashSet<String> set = new HashSet<String>();
+    for (Token t : subcommands)
+      set.addAll(t.getCommandNames());
+    return set;
+  }
+  
+  public Set<String> getSubcommandNames(String startsWith) {
+    Iterator<Token> iter = subcommands.iterator();
+    HashSet<String> set = new HashSet<String>();
+    while (iter.hasNext()) {
+      Token t = iter.next();
+      Set<String> subset = t.getCommandNames();
+      for (String s : subset) {
+        if (!t.getCaseSensitive()) {
+          if (s.toLowerCase().startsWith(startsWith.toLowerCase())) {
+            set.add(s);
+          }
+        } else {
+          if (s.startsWith(startsWith)) {
+            set.add(s);
+          }
+        }
+      }
+    }
+    return set;
+  }
+  
+  public boolean containsCommand(String match) {
+    Iterator<String> iter = command.iterator();
+    while (iter.hasNext()) {
+      String t = iter.next();
+      if (caseSensitive) {
+        if (t.equals(match))
+          return true;
+      } else {
+        if (t.equalsIgnoreCase(match))
+          return true;
+      }
+    }
+    return false;
+  }
+  
+  public void addSubcommand(Token t) {
+    subcommands.add(t);
+  }
+  
+  public void addSubcommand(Collection<String> t) {
+    for (String a : t) {
+      addSubcommand(new Token(a));
+    }
+  }
+  
+  public String toString() {
+    return this.command.toString();
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/AboutCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/AboutCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/AboutCommand.java
new file mode 100644
index 0000000..a0a73e4
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/AboutCommand.java
@@ -0,0 +1,56 @@
+/*
+ * 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.accumulo.core.util.shell.commands;
+
+import java.io.IOException;
+
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.core.util.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+
+public class AboutCommand extends Command {
+  private Option verboseOption;
+  
+  @Override
+  public String description() {
+    return "displays information about this program";
+  }
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws IOException {
+    shellState.printInfo();
+    if (cl.hasOption(verboseOption.getOpt())) {
+      shellState.printVerboseInfo();
+    }
+    return 0;
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options opts = new Options();
+    verboseOption = new Option("v", "verbose", false, "display detailed session information");
+    opts.addOption(verboseOption);
+    return opts;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ActiveCompactionIterator.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ActiveCompactionIterator.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ActiveCompactionIterator.java
new file mode 100644
index 0000000..bd7d9b2
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ActiveCompactionIterator.java
@@ -0,0 +1,136 @@
+/*
+ * 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.accumulo.core.util.shell.commands;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.accumulo.core.client.IteratorSetting;
+import org.apache.accumulo.core.client.admin.ActiveCompaction;
+import org.apache.accumulo.core.client.admin.InstanceOperations;
+import org.apache.accumulo.core.util.Duration;
+
+class ActiveCompactionIterator implements Iterator<String> {
+  
+  private InstanceOperations instanceOps;
+  private Iterator<String> tsIter;
+  private Iterator<String> compactionIter;
+  
+  private static String maxDecimal(double count) {
+    if (count < 9.995)
+      return String.format("%.2f", count);
+    if (count < 99.95)
+      return String.format("%.1f", count);
+    return String.format("%.0f", count);
+  }
+
+  private static String shortenCount(long count) {
+    if (count < 1000)
+      return count + "";
+    if (count < 1000000)
+      return maxDecimal(count / 1000.0) + "K";
+    if (count < 1000000000)
+      return maxDecimal(count / 1000000.0) + "M";
+    return maxDecimal(count / 1000000000.0) + "B";
+  }
+
+  private void readNext() {
+    final List<String> compactions = new ArrayList<String>();
+    
+    while (tsIter.hasNext()) {
+      
+      final String tserver = tsIter.next();
+      try {
+        List<ActiveCompaction> acl = instanceOps.getActiveCompactions(tserver);
+        
+        acl = new ArrayList<ActiveCompaction>(acl);
+        
+        Collections.sort(acl, new Comparator<ActiveCompaction>() {
+          @Override
+          public int compare(ActiveCompaction o1, ActiveCompaction o2) {
+            return (int) (o2.getAge() - o1.getAge());
+          }
+        });
+
+        for (ActiveCompaction ac : acl) {
+          String output = ac.getOutputFile();
+          int index = output.indexOf("tables");
+          if (index > 0) {
+            output = output.substring(index + 6);
+          }
+          
+          ac.getIterators();
+          
+          List<String> iterList = new ArrayList<String>();
+          Map<String,Map<String,String>> iterOpts = new HashMap<String,Map<String,String>>();
+          for (IteratorSetting is : ac.getIterators()) {
+            iterList.add(is.getName() + "=" + is.getPriority() + "," + is.getIteratorClass());
+            iterOpts.put(is.getName(), is.getOptions());
+          }
+
+          compactions.add(String.format("%21s | %9s | %5s | %6s | %5s | %5s | %15s | %-40s | %5s | %35s | %9s | %s", tserver,
+              Duration.format(ac.getAge(), "", "-"), ac.getType(), ac.getReason(), shortenCount(ac.getEntriesRead()), shortenCount(ac.getEntriesWritten()),
+              ac.getTable(), ac.getExtent(), ac.getInputFiles().size(), output, iterList, iterOpts));
+        }
+      } catch (Exception e) {
+        compactions.add(tserver + " ERROR " + e.getMessage());
+      }
+      
+      if (compactions.size() > 0) {
+        break;
+      }
+    }
+    
+    compactionIter = compactions.iterator();
+  }
+  
+  ActiveCompactionIterator(List<String> tservers, InstanceOperations instanceOps) {
+    this.instanceOps = instanceOps;
+    this.tsIter = tservers.iterator();
+    
+    final String header = String.format(" %-21s| %-9s | %-5s | %-6s | %-5s | %-5s | %-15s | %-40s | %-5s | %-35s | %-9s | %s", "TABLET SERVER", "AGE", "TYPE",
+        "REASON", "READ", "WROTE", "TABLE", "TABLET", "INPUT", "OUTPUT", "ITERATORS", "ITERATOR OPTIONS");
+    
+    compactionIter = Collections.singletonList(header).iterator();
+  }
+  
+  @Override
+  public boolean hasNext() {
+    return compactionIter.hasNext();
+  }
+  
+  @Override
+  public String next() {
+    final String next = compactionIter.next();
+    
+    if (!compactionIter.hasNext())
+      readNext();
+    
+    return next;
+  }
+  
+  @Override
+  public void remove() {
+    throw new UnsupportedOperationException();
+  }
+  
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ActiveScanIterator.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ActiveScanIterator.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ActiveScanIterator.java
new file mode 100644
index 0000000..f1e736f
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ActiveScanIterator.java
@@ -0,0 +1,91 @@
+/*
+ * 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.accumulo.core.util.shell.commands;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.accumulo.core.client.admin.ActiveScan;
+import org.apache.accumulo.core.client.admin.InstanceOperations;
+import org.apache.accumulo.core.client.admin.ScanType;
+import org.apache.accumulo.core.util.Duration;
+
+class ActiveScanIterator implements Iterator<String> {
+  
+  private InstanceOperations instanceOps;
+  private Iterator<String> tsIter;
+  private Iterator<String> scansIter;
+  
+  private void readNext() {
+    final List<String> scans = new ArrayList<String>();
+    
+    while (tsIter.hasNext()) {
+      
+      final String tserver = tsIter.next();
+      try {
+        final List<ActiveScan> asl = instanceOps.getActiveScans(tserver);
+        
+        for (ActiveScan as : asl) {
+          scans.add(String.format("%21s |%21s |%9s |%9s |%7s |%6s |%8s |%8s |%10s |%20s |%10s |%10s | %s", tserver, as.getClient(),
+              Duration.format(as.getAge(), "", "-"), Duration.format(as.getLastContactTime(), "", "-"), as.getState(), as.getType(), as.getUser(),
+              as.getTable(), as.getColumns(), as.getAuthorizations(), (as.getType() == ScanType.SINGLE ? as.getExtent() : "N/A"), as.getSsiList(), as.getSsio()));
+        }
+      } catch (Exception e) {
+        scans.add(tserver + " ERROR " + e.getMessage());
+      }
+      
+      if (scans.size() > 0) {
+        break;
+      }
+    }
+    
+    scansIter = scans.iterator();
+  }
+  
+  ActiveScanIterator(List<String> tservers, InstanceOperations instanceOps) {
+    this.instanceOps = instanceOps;
+    this.tsIter = tservers.iterator();
+    
+    final String header = String.format(" %-21s| %-21s| %-9s| %-9s| %-7s| %-6s| %-8s| %-8s| %-10s| %-20s| %-10s| %-10s | %s", "TABLET SERVER", "CLIENT", "AGE",
+        "LAST", "STATE", "TYPE", "USER", "TABLE", "COLUMNS", "AUTHORIZATIONS", "TABLET", "ITERATORS", "ITERATOR OPTIONS");
+    
+    scansIter = Collections.singletonList(header).iterator();
+  }
+  
+  @Override
+  public boolean hasNext() {
+    return scansIter.hasNext();
+  }
+  
+  @Override
+  public String next() {
+    final String next = scansIter.next();
+    
+    if (!scansIter.hasNext())
+      readNext();
+    
+    return next;
+  }
+  
+  @Override
+  public void remove() {
+    throw new UnsupportedOperationException();
+  }
+  
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/AddAuthsCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/AddAuthsCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/AddAuthsCommand.java
new file mode 100644
index 0000000..bd478de
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/AddAuthsCommand.java
@@ -0,0 +1,82 @@
+/*
+ * 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.accumulo.core.util.shell.commands;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.security.Authorizations;
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.core.util.shell.Shell.Command;
+import org.apache.accumulo.core.util.shell.Token;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.OptionGroup;
+import org.apache.commons.cli.Options;
+
+public class AddAuthsCommand extends Command {
+  private Option userOpt;
+  private Option scanOptAuths;
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException {
+    final String user = cl.getOptionValue(userOpt.getOpt(), shellState.getConnector().whoami());
+    final String scanOpts = cl.getOptionValue(scanOptAuths.getOpt());
+    Authorizations auths = shellState.getConnector().securityOperations().getUserAuthorizations(user);
+    StringBuilder userAuths = new StringBuilder();
+    if (!auths.isEmpty()) {
+      userAuths.append(auths.toString());
+      userAuths.append(",");
+    }
+    userAuths.append(scanOpts);
+    shellState.getConnector().securityOperations().changeUserAuthorizations(user, ScanCommand.parseAuthorizations(userAuths.toString()));
+    Shell.log.debug("Changed record-level authorizations for user " + user);
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "adds authorizations to the maximum scan authorizations for a user";
+  }
+  
+  @Override
+  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> completionSet) {
+    registerCompletionForUsers(root, completionSet);
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+    final OptionGroup setOrClear = new OptionGroup();
+    scanOptAuths = new Option("s", "scan-authorizations", true, "scan authorizations to set");
+    scanOptAuths.setArgName("comma-separated-authorizations");
+    setOrClear.addOption(scanOptAuths);
+    setOrClear.setRequired(true);
+    o.addOptionGroup(setOrClear);
+    userOpt = new Option(Shell.userOption, "user", true, "user to operate on");
+    userOpt.setArgName("user");
+    o.addOption(userOpt);
+    return o;
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/AddSplitsCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/AddSplitsCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/AddSplitsCommand.java
new file mode 100644
index 0000000..b8ba621
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/AddSplitsCommand.java
@@ -0,0 +1,88 @@
+/*
+ * 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.accumulo.core.util.shell.commands;
+
+import java.util.TreeSet;
+
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.core.util.shell.Shell.Command;
+import org.apache.accumulo.core.util.shell.ShellUtil;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.MissingArgumentException;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+import org.apache.hadoop.io.Text;
+
+public class AddSplitsCommand extends Command {
+  private Option optSplitsFile, base64Opt;
+  
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    final String tableName = OptUtil.getTableOpt(cl, shellState);
+    final boolean decode = cl.hasOption(base64Opt.getOpt());
+    
+    final TreeSet<Text> splits = new TreeSet<Text>();
+    
+    if (cl.hasOption(optSplitsFile.getOpt())) {
+      splits.addAll(ShellUtil.scanFile(cl.getOptionValue(optSplitsFile.getOpt()), decode));
+    } else {
+      if (cl.getArgList().isEmpty()) {
+        throw new MissingArgumentException("No split points specified");
+      }
+      for (String s : cl.getArgs()) {
+        splits.add(new Text(s.getBytes(Shell.CHARSET)));
+      }
+    }
+    
+    if (!shellState.getConnector().tableOperations().exists(tableName)) {
+      throw new TableNotFoundException(null, tableName, null);
+    }
+    shellState.getConnector().tableOperations().addSplits(tableName, splits);
+    
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "adds split points to an existing table";
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+    
+    optSplitsFile = new Option("sf", "splits-file", true, "file with a newline-separated list of rows to split the table with");
+    optSplitsFile.setArgName("filename");
+    
+    base64Opt = new Option("b64", "base64encoded", false, "decode encoded split points (splits file only)");
+    
+    o.addOption(OptUtil.tableOpt("name of the table to add split points to"));
+    o.addOption(optSplitsFile);
+    o.addOption(base64Opt);
+    return o;
+  }
+  
+  @Override
+  public String usage() {
+    return getName() + " [<split>{ <split>} ]";
+  }
+  
+  @Override
+  public int numArgs() {
+    return Shell.NO_FIXED_ARG_LENGTH_CHECK;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/AuthenticateCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/AuthenticateCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/AuthenticateCommand.java
new file mode 100644
index 0000000..8ebdae8
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/AuthenticateCommand.java
@@ -0,0 +1,66 @@
+/*
+ * 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.accumulo.core.util.shell.commands;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.security.tokens.PasswordToken;
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.core.util.shell.Shell.Command;
+import org.apache.accumulo.core.util.shell.Token;
+import org.apache.commons.cli.CommandLine;
+
+public class AuthenticateCommand extends Command {
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException, IOException {
+    final String user = cl.getArgs()[0];
+    final String p = shellState.readMaskedLine("Enter current password for '" + user + "': ", '*');
+    if (p == null) {
+      shellState.getReader().println();
+      return 0;
+    } // user canceled
+    final byte[] password = p.getBytes(StandardCharsets.UTF_8);
+    final boolean valid = shellState.getConnector().securityOperations().authenticateUser(user, new PasswordToken(password));
+    shellState.getReader().println((valid ? "V" : "Not v") + "alid");
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "verifies a user's credentials";
+  }
+  
+  @Override
+  public String usage() {
+    return getName() + " <username>";
+  }
+  
+  @Override
+  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> completionSet) {
+    registerCompletionForUsers(root, completionSet);
+  }
+  
+  @Override
+  public int numArgs() {
+    return 1;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ByeCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ByeCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ByeCommand.java
new file mode 100644
index 0000000..f0c9d24
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ByeCommand.java
@@ -0,0 +1,19 @@
+/*
+ * 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.accumulo.core.util.shell.commands;
+
+public class ByeCommand extends ExitCommand {}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ClasspathCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ClasspathCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ClasspathCommand.java
new file mode 100644
index 0000000..b2fe300
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ClasspathCommand.java
@@ -0,0 +1,55 @@
+/*
+ * 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.accumulo.core.util.shell.commands;
+
+import java.io.IOException;
+
+import jline.console.ConsoleReader;
+
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.core.util.shell.Shell.Command;
+import org.apache.accumulo.start.classloader.vfs.AccumuloVFSClassLoader;
+import org.apache.accumulo.start.classloader.vfs.AccumuloVFSClassLoader.Printer;
+import org.apache.commons.cli.CommandLine;
+
+public class ClasspathCommand extends Command {
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) {
+    final ConsoleReader reader = shellState.getReader();
+    AccumuloVFSClassLoader.printClassPath(new Printer() {
+      @Override
+      public void print(String s) {
+        try {
+          reader.println(s);
+        } catch (IOException ex) {
+          throw new RuntimeException(ex);
+        }
+      }
+    });
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "lists the current files on the classpath";
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ClearCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ClearCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ClearCommand.java
new file mode 100644
index 0000000..4f15650
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ClearCommand.java
@@ -0,0 +1,52 @@
+/*
+ * 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.accumulo.core.util.shell.commands;
+
+import java.io.IOException;
+
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.core.util.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+
+public class ClearCommand extends Command {
+  @Override
+  public String description() {
+    return "clears the screen";
+  }
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws IOException {
+    // custom clear screen, so I don't have to redraw the prompt twice
+    if (!shellState.getReader().getTerminal().isAnsiSupported()) {
+      throw new IOException("Terminal does not support ANSI commands");
+    }
+    // send the ANSI code to clear the screen
+    shellState.getReader().print(((char) 27) + "[2J");
+    shellState.getReader().flush();
+    
+    // then send the ANSI code to go to position 1,1
+    shellState.getReader().print(((char) 27) + "[1;1H");
+    shellState.getReader().flush();
+    
+    return 0;
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/CloneTableCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/CloneTableCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/CloneTableCommand.java
new file mode 100644
index 0000000..207e530
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/CloneTableCommand.java
@@ -0,0 +1,102 @@
+/*
+ * 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.accumulo.core.util.shell.commands;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.TableExistsException;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.core.util.shell.Shell.Command;
+import org.apache.accumulo.core.util.shell.Token;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+
+public class CloneTableCommand extends Command {
+  
+  private Option setPropsOption;
+  private Option excludePropsOption;
+  private Option noFlushOption;
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException, TableNotFoundException,
+      TableExistsException {
+    
+    final HashMap<String,String> props = new HashMap<String,String>();
+    final HashSet<String> exclude = new HashSet<String>();
+    boolean flush = true;
+    
+    if (cl.hasOption(setPropsOption.getOpt())) {
+      String[] keyVals = cl.getOptionValue(setPropsOption.getOpt()).split(",");
+      for (String keyVal : keyVals) {
+        String[] sa = keyVal.split("=");
+        props.put(sa[0], sa[1]);
+      }
+    }
+    
+    if (cl.hasOption(excludePropsOption.getOpt())) {
+      String[] keys = cl.getOptionValue(excludePropsOption.getOpt()).split(",");
+      for (String key : keys) {
+        exclude.add(key);
+      }
+    }
+    
+    if (cl.hasOption(noFlushOption.getOpt())) {
+      flush = false;
+    }
+    
+    shellState.getConnector().tableOperations().clone(cl.getArgs()[0], cl.getArgs()[1], flush, props, exclude);
+    return 0;
+  }
+  
+  @Override
+  public String usage() {
+    return getName() + " <current table name> <new table name>";
+  }
+  
+  @Override
+  public String description() {
+    return "clones a table";
+  }
+  
+  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> completionSet) {
+    registerCompletionForTables(root, completionSet);
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+    setPropsOption = new Option("s", "set", true, "set initial properties before the table comes online. Expects <prop>=<value>{,<prop>=<value>}");
+    o.addOption(setPropsOption);
+    excludePropsOption = new Option("e", "exclude", true, "exclude properties that should not be copied from source table. Expects <prop>{,<prop>}");
+    o.addOption(excludePropsOption);
+    noFlushOption = new Option("nf", "noFlush", false, "do not flush table data in memory before cloning.");
+    o.addOption(noFlushOption);
+    return o;
+  }
+  
+  @Override
+  public int numArgs() {
+    return 2;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ClsCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ClsCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ClsCommand.java
new file mode 100644
index 0000000..cef6098
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ClsCommand.java
@@ -0,0 +1,19 @@
+/*
+ * 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.accumulo.core.util.shell.commands;
+
+public class ClsCommand extends ClearCommand {}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/CompactCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/CompactCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/CompactCommand.java
new file mode 100644
index 0000000..55e9395
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/CompactCommand.java
@@ -0,0 +1,129 @@
+/*
+ * 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.accumulo.core.util.shell.commands;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.IteratorSetting;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+import org.apache.hadoop.io.Text;
+
+public class CompactCommand extends TableOperation {
+  private Option noFlushOption, waitOpt, profileOpt, cancelOpt;
+  private boolean flush;
+  private Text startRow;
+  private Text endRow;
+  private List<IteratorSetting> iterators;
+  
+  boolean override = false;
+  private boolean wait;
+  
+  private boolean cancel = false;
+
+  @Override
+  public String description() {
+    return "sets all tablets for a table to major compact as soon as possible (based on current time)";
+  }
+  
+  protected void doTableOp(final Shell shellState, final String tableName) throws AccumuloException, AccumuloSecurityException {
+    // compact the tables
+    
+    if (cancel) {
+      try {
+        shellState.getConnector().tableOperations().cancelCompaction(tableName);
+        Shell.log.info("Compaction canceled for table " + tableName);
+      } catch (TableNotFoundException e) {
+        throw new AccumuloException(e);
+      }
+    } else {
+      try {
+        if (wait) {
+          Shell.log.info("Compacting table ...");
+        }
+        
+        shellState.getConnector().tableOperations().compact(tableName, startRow, endRow, iterators, flush, wait);
+        
+        Shell.log.info("Compaction of table " + tableName + " " + (wait ? "completed" : "started") + " for given range");
+      } catch (Exception ex) {
+        throw new AccumuloException(ex);
+      }
+    }
+  }
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    
+    if (cl.hasOption(cancelOpt.getLongOpt())) {
+      cancel = true;
+      
+      if (cl.getOptions().length > 2) {
+        throw new IllegalArgumentException("Can not specify other options with cancel");
+      }
+    } else {
+      cancel = false;
+    }
+
+    flush = !cl.hasOption(noFlushOption.getOpt());
+    startRow = OptUtil.getStartRow(cl);
+    endRow = OptUtil.getEndRow(cl);
+    wait = cl.hasOption(waitOpt.getOpt());
+    
+    if (cl.hasOption(profileOpt.getOpt())) {
+      List<IteratorSetting> iterators = shellState.iteratorProfiles.get(cl.getOptionValue(profileOpt.getOpt()));
+      if (iterators == null) {
+        Shell.log.error("Profile " + cl.getOptionValue(profileOpt.getOpt()) + " does not exist");
+        return -1;
+      }
+      
+      this.iterators = new ArrayList<IteratorSetting>(iterators);
+    } else {
+      this.iterators = Collections.emptyList();
+    }
+
+
+    return super.execute(fullCommand, cl, shellState);
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options opts = super.getOptions();
+    
+    opts.addOption(OptUtil.startRowOpt());
+    opts.addOption(OptUtil.endRowOpt());
+    noFlushOption = new Option("nf", "noFlush", false, "do not flush table data in memory before compacting.");
+    opts.addOption(noFlushOption);
+    waitOpt = new Option("w", "wait", false, "wait for compact to finish");
+    opts.addOption(waitOpt);
+    
+    profileOpt = new Option("pn", "profile", true, "iterator profile name");
+    profileOpt.setArgName("profile");
+    opts.addOption(profileOpt);
+
+    cancelOpt = new Option(null, "cancel", false, "cancel user initiated compactions");
+    opts.addOption(cancelOpt);
+
+    return opts;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ConfigCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ConfigCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ConfigCommand.java
new file mode 100644
index 0000000..c76a51f
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ConfigCommand.java
@@ -0,0 +1,315 @@
+/*
+ * 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.accumulo.core.util.shell.commands;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.TreeMap;
+
+import jline.console.ConsoleReader;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.NamespaceNotFoundException;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.core.client.impl.Namespaces;
+import org.apache.accumulo.core.client.impl.Tables;
+import org.apache.accumulo.core.conf.AccumuloConfiguration;
+import org.apache.accumulo.core.conf.Property;
+import org.apache.accumulo.core.security.ColumnVisibility;
+import org.apache.accumulo.core.util.BadArgumentException;
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.core.util.shell.Shell.Command;
+import org.apache.accumulo.core.util.shell.Shell.PrintFile;
+import org.apache.accumulo.core.util.shell.Token;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.OptionGroup;
+import org.apache.commons.cli.Options;
+
+public class ConfigCommand extends Command {
+  private Option tableOpt, deleteOpt, setOpt, filterOpt, disablePaginationOpt, outputFileOpt, namespaceOpt;
+
+  private int COL1 = 10, COL2 = 7;
+  private ConsoleReader reader;
+
+  @Override
+  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> completionSet) {
+    final Token cmd = new Token(getName());
+    final Token sub = new Token("-" + setOpt.getOpt());
+    for (Property p : Property.values()) {
+      if (!(p.getKey().endsWith(".")) && !p.isExperimental()) {
+        sub.addSubcommand(new Token(p.toString()));
+      }
+    }
+    cmd.addSubcommand(sub);
+    root.addSubcommand(cmd);
+  }
+
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException,
+      TableNotFoundException, IOException, ClassNotFoundException, NamespaceNotFoundException {
+    reader = shellState.getReader();
+
+    final String tableName = cl.getOptionValue(tableOpt.getOpt());
+    if (tableName != null && !shellState.getConnector().tableOperations().exists(tableName)) {
+      throw new TableNotFoundException(null, tableName, null);
+    }
+    final String namespace = cl.getOptionValue(namespaceOpt.getOpt());
+    if (namespace != null && !shellState.getConnector().namespaceOperations().exists(namespace)) {
+      throw new NamespaceNotFoundException(null, namespace, null);
+    }
+    if (cl.hasOption(deleteOpt.getOpt())) {
+      // delete property from table
+      String property = cl.getOptionValue(deleteOpt.getOpt());
+      if (property.contains("=")) {
+        throw new BadArgumentException("Invalid '=' operator in delete operation.", fullCommand, fullCommand.indexOf('='));
+      }
+      if (tableName != null) {
+        if (!Property.isValidTablePropertyKey(property)) {
+          Shell.log.warn("Invalid per-table property : " + property + ", still removing from zookeeper if it's there.");
+        }
+        shellState.getConnector().tableOperations().removeProperty(tableName, property);
+        Shell.log.debug("Successfully deleted table configuration option.");
+      } else if (namespace != null) {
+        if (!Property.isValidTablePropertyKey(property)) {
+          Shell.log.warn("Invalid per-table property : " + property + ", still removing from zookeeper if it's there.");
+        }
+        shellState.getConnector().namespaceOperations().removeProperty(namespace, property);
+        Shell.log.debug("Successfully deleted namespace configuration option.");
+      } else {
+        if (!Property.isValidZooPropertyKey(property)) {
+          Shell.log.warn("Invalid per-table property : " + property + ", still removing from zookeeper if it's there.");
+        }
+        shellState.getConnector().instanceOperations().removeProperty(property);
+        Shell.log.debug("Successfully deleted system configuration option");
+      }
+    } else if (cl.hasOption(setOpt.getOpt())) {
+      // set property on table
+      String property = cl.getOptionValue(setOpt.getOpt()), value = null;
+      if (!property.contains("=")) {
+        throw new BadArgumentException("Missing '=' operator in set operation.", fullCommand, fullCommand.indexOf(property));
+      }
+      final String pair[] = property.split("=", 2);
+      property = pair[0];
+      value = pair[1];
+
+      if (tableName != null) {
+        if (!Property.isValidTablePropertyKey(property)) {
+          throw new BadArgumentException("Invalid per-table property.", fullCommand, fullCommand.indexOf(property));
+        }
+        if (property.equals(Property.TABLE_DEFAULT_SCANTIME_VISIBILITY.getKey())) {
+          new ColumnVisibility(value); // validate that it is a valid expression
+        }
+        shellState.getConnector().tableOperations().setProperty(tableName, property, value);
+        Shell.log.debug("Successfully set table configuration option.");
+      } else if (namespace != null) {
+        if (!Property.isValidTablePropertyKey(property)) {
+          throw new BadArgumentException("Invalid per-table property.", fullCommand, fullCommand.indexOf(property));
+        }
+        if (property.equals(Property.TABLE_DEFAULT_SCANTIME_VISIBILITY.getKey())) {
+          new ColumnVisibility(value); // validate that it is a valid expression
+        }
+        shellState.getConnector().namespaceOperations().setProperty(namespace, property, value);
+        Shell.log.debug("Successfully set table configuration option.");
+      } else {
+        if (!Property.isValidZooPropertyKey(property)) {
+          throw new BadArgumentException("Property cannot be modified in zookeeper", fullCommand, fullCommand.indexOf(property));
+        }
+        shellState.getConnector().instanceOperations().setProperty(property, value);
+        Shell.log.debug("Successfully set system configuration option");
+      }
+    } else {
+      // display properties
+      final TreeMap<String,String> systemConfig = new TreeMap<String,String>();
+      systemConfig.putAll(shellState.getConnector().instanceOperations().getSystemConfiguration());
+
+      final String outputFile = cl.getOptionValue(outputFileOpt.getOpt());
+      final PrintFile printFile = outputFile == null ? null : new PrintFile(outputFile);
+
+      final TreeMap<String,String> siteConfig = new TreeMap<String,String>();
+      siteConfig.putAll(shellState.getConnector().instanceOperations().getSiteConfiguration());
+
+      final TreeMap<String,String> defaults = new TreeMap<String,String>();
+      for (Entry<String,String> defaultEntry : AccumuloConfiguration.getDefaultConfiguration()) {
+        defaults.put(defaultEntry.getKey(), defaultEntry.getValue());
+      }
+
+      final TreeMap<String,String> namespaceConfig = new TreeMap<String,String>();
+      if (tableName != null) {
+        String n = Namespaces.getNamespaceName(shellState.getInstance(),
+            Tables.getNamespaceId(shellState.getInstance(), Tables.getTableId(shellState.getInstance(), tableName)));
+        for (Entry<String,String> e : shellState.getConnector().namespaceOperations().getProperties(n)) {
+          namespaceConfig.put(e.getKey(), e.getValue());
+        }
+      }
+
+      Iterable<Entry<String,String>> acuconf = shellState.getConnector().instanceOperations().getSystemConfiguration().entrySet();
+      if (tableName != null) {
+        acuconf = shellState.getConnector().tableOperations().getProperties(tableName);
+      } else if (namespace != null) {
+        acuconf = shellState.getConnector().namespaceOperations().getProperties(namespace);
+      }
+      final TreeMap<String,String> sortedConf = new TreeMap<String,String>();
+      for (Entry<String,String> propEntry : acuconf) {
+        sortedConf.put(propEntry.getKey(), propEntry.getValue());
+      }
+
+      for (Entry<String,String> propEntry : acuconf) {
+        final String key = propEntry.getKey();
+        // only show properties with similar names to that
+        // specified, or all of them if none specified
+        if (cl.hasOption(filterOpt.getOpt()) && !key.contains(cl.getOptionValue(filterOpt.getOpt()))) {
+          continue;
+        }
+        if ((tableName != null || namespace != null) && !Property.isValidTablePropertyKey(key)) {
+          continue;
+        }
+        COL2 = Math.max(COL2, propEntry.getKey().length() + 3);
+      }
+
+      final ArrayList<String> output = new ArrayList<String>();
+      printConfHeader(output);
+
+      for (Entry<String,String> propEntry : sortedConf.entrySet()) {
+        final String key = propEntry.getKey();
+
+        // only show properties with similar names to that
+        // specified, or all of them if none specified
+        if (cl.hasOption(filterOpt.getOpt()) && !key.contains(cl.getOptionValue(filterOpt.getOpt()))) {
+          continue;
+        }
+        if ((tableName != null || namespace != null) && !Property.isValidTablePropertyKey(key)) {
+          continue;
+        }
+        String siteVal = siteConfig.get(key);
+        String sysVal = systemConfig.get(key);
+        String curVal = propEntry.getValue();
+        String dfault = defaults.get(key);
+        String nspVal = namespaceConfig.get(key);
+        boolean printed = false;
+
+        if (dfault != null && key.toLowerCase().contains("password")) {
+          siteVal = sysVal = dfault = curVal = curVal.replaceAll(".", "*");
+        }
+        if (sysVal != null) {
+          if (defaults.containsKey(key) && !Property.getPropertyByKey(key).isExperimental()) {
+            printConfLine(output, "default", key, dfault);
+            printed = true;
+          }
+          if (!defaults.containsKey(key) || !defaults.get(key).equals(siteVal)) {
+            printConfLine(output, "site", printed ? "   @override" : key, siteVal == null ? "" : siteVal);
+            printed = true;
+          }
+          if (!siteConfig.containsKey(key) || !siteVal.equals(sysVal)) {
+            printConfLine(output, "system", printed ? "   @override" : key, sysVal == null ? "" : sysVal);
+            printed = true;
+          }
+
+        }
+        if (nspVal != null) {
+          if (!systemConfig.containsKey(key) || !sysVal.equals(nspVal)) {
+            printConfLine(output, "namespace", printed ? "   @override" : key, nspVal == null ? "" : nspVal);
+            printed = true;
+          }
+        }
+
+        // show per-table value only if it is different (overridden)
+        if (tableName != null && !curVal.equals(nspVal)) {
+          printConfLine(output, "table", printed ? "   @override" : key, curVal);
+        } else if (namespace != null && !curVal.equals(sysVal)) {
+          printConfLine(output, "namespace", printed ? "   @override" : key, curVal);
+        }
+      }
+      printConfFooter(output);
+      shellState.printLines(output.iterator(), !cl.hasOption(disablePaginationOpt.getOpt()), printFile);
+      if (printFile != null) {
+        printFile.close();
+      }
+    }
+    return 0;
+  }
+
+  private void printConfHeader(List<String> output) {
+    printConfFooter(output);
+    output.add(String.format("%-" + COL1 + "s | %-" + COL2 + "s | %s", "SCOPE", "NAME", "VALUE"));
+    printConfFooter(output);
+  }
+
+  private void printConfLine(List<String> output, String s1, String s2, String s3) {
+    if (s2.length() < COL2) {
+      s2 += " " + Shell.repeat(".", COL2 - s2.length() - 1);
+    }
+    output.add(String.format("%-" + COL1 + "s | %-" + COL2 + "s | %s", s1, s2,
+        s3.replace("\n", "\n" + Shell.repeat(" ", COL1 + 1) + "|" + Shell.repeat(" ", COL2 + 2) + "|" + " ")));
+  }
+
+  private void printConfFooter(List<String> output) {
+    int col3 = Math.max(1, Math.min(Integer.MAX_VALUE, reader.getTerminal().getWidth() - COL1 - COL2 - 6));
+    output.add(String.format("%" + COL1 + "s-+-%" + COL2 + "s-+-%-" + col3 + "s", Shell.repeat("-", COL1), Shell.repeat("-", COL2), Shell.repeat("-", col3)));
+  }
+
+  @Override
+  public String description() {
+    return "prints system properties and table specific properties";
+  }
+
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+    final OptionGroup og = new OptionGroup();
+    final OptionGroup tgroup = new OptionGroup();
+
+    tableOpt = new Option(Shell.tableOption, "table", true, "table to display/set/delete properties for");
+    deleteOpt = new Option("d", "delete", true, "delete a per-table property");
+    setOpt = new Option("s", "set", true, "set a per-table property");
+    filterOpt = new Option("f", "filter", true, "show only properties that contain this string");
+    disablePaginationOpt = new Option("np", "no-pagination", false, "disables pagination of output");
+    outputFileOpt = new Option("o", "output", true, "local file to write the scan output to");
+    namespaceOpt = new Option(Shell.namespaceOption, "namespace", true, "namespace to display/set/delete properties for");
+
+    tableOpt.setArgName("table");
+    deleteOpt.setArgName("property");
+    setOpt.setArgName("property=value");
+    filterOpt.setArgName("string");
+    outputFileOpt.setArgName("file");
+    namespaceOpt.setArgName("namespace");
+
+    og.addOption(deleteOpt);
+    og.addOption(setOpt);
+    og.addOption(filterOpt);
+
+    tgroup.addOption(tableOpt);
+    tgroup.addOption(namespaceOpt);
+
+    o.addOptionGroup(tgroup);
+    o.addOptionGroup(og);
+    o.addOption(disablePaginationOpt);
+    o.addOption(outputFileOpt);
+
+    return o;
+  }
+
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ConstraintCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ConstraintCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ConstraintCommand.java
new file mode 100644
index 0000000..208ac4a
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ConstraintCommand.java
@@ -0,0 +1,134 @@
+/*
+ * 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.accumulo.core.util.shell.commands;
+
+import java.util.Map.Entry;
+
+import org.apache.accumulo.core.constraints.Constraint;
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.core.util.shell.Shell.Command;
+import org.apache.accumulo.core.util.shell.ShellCommandException;
+import org.apache.accumulo.core.util.shell.ShellCommandException.ErrorCode;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.OptionGroup;
+import org.apache.commons.cli.Options;
+
+public class ConstraintCommand extends Command {
+  protected Option namespaceOpt;
+
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    final String tableName;
+    final String namespace;
+
+    if (cl.hasOption(namespaceOpt.getOpt())) {
+      namespace = cl.getOptionValue(namespaceOpt.getOpt());
+    } else {
+      namespace = null;
+    }
+
+    if (cl.hasOption(OptUtil.tableOpt().getOpt()) || !shellState.getTableName().isEmpty()) {
+      tableName = OptUtil.getTableOpt(cl, shellState);
+    } else {
+      tableName = null;
+    }
+
+    int i;
+    switch (OptUtil.getAldOpt(cl)) {
+      case ADD:
+        for (String constraint : cl.getArgs()) {
+          if (namespace != null) {
+            if (!shellState.getConnector().namespaceOperations().testClassLoad(namespace, constraint, Constraint.class.getName())) {
+              throw new ShellCommandException(ErrorCode.INITIALIZATION_FAILURE, "Servers are unable to load " + constraint + " as type "
+                  + Constraint.class.getName());
+            }
+            i = shellState.getConnector().namespaceOperations().addConstraint(namespace, constraint);
+            shellState.getReader().println("Added constraint " + constraint + " to namespace " + namespace + " with number " + i);
+          } else if (tableName != null && !tableName.isEmpty()) {
+            if (!shellState.getConnector().tableOperations().testClassLoad(tableName, constraint, Constraint.class.getName())) {
+              throw new ShellCommandException(ErrorCode.INITIALIZATION_FAILURE, "Servers are unable to load " + constraint + " as type "
+                  + Constraint.class.getName());
+            }
+            i = shellState.getConnector().tableOperations().addConstraint(tableName, constraint);
+            shellState.getReader().println("Added constraint " + constraint + " to table " + tableName + " with number " + i);
+          } else {
+            throw new IllegalArgumentException("Please specify either a table or a namespace");
+          }
+        }
+        break;
+      case DELETE:
+        for (String constraint : cl.getArgs()) {
+          i = Integer.parseInt(constraint);
+          if (namespace != null) {
+            shellState.getConnector().namespaceOperations().removeConstraint(namespace, i);
+            shellState.getReader().println("Removed constraint " + i + " from namespace " + namespace);
+          } else if (tableName != null) {
+            shellState.getConnector().tableOperations().removeConstraint(tableName, i);
+            shellState.getReader().println("Removed constraint " + i + " from table " + tableName);
+          } else {
+            throw new IllegalArgumentException("Please specify either a table or a namespace");
+          }
+        }
+        break;
+      case LIST:
+        if (namespace != null) {
+          for (Entry<String,Integer> property : shellState.getConnector().namespaceOperations().listConstraints(namespace).entrySet()) {
+            shellState.getReader().println(property.toString());
+          }
+        } else if (tableName != null) {
+          for (Entry<String,Integer> property : shellState.getConnector().tableOperations().listConstraints(tableName).entrySet()) {
+            shellState.getReader().println(property.toString());
+          }
+        } else {
+          throw new IllegalArgumentException("Please specify either a table or a namespace");
+        }
+    }
+
+    return 0;
+  }
+
+  @Override
+  public String description() {
+    return "adds, deletes, or lists constraints for a table";
+  }
+
+  @Override
+  public int numArgs() {
+    return Shell.NO_FIXED_ARG_LENGTH_CHECK;
+  }
+
+  @Override
+  public String usage() {
+    return getName() + " <constraint>{ <constraint>}";
+  }
+
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+    o.addOptionGroup(OptUtil.addListDeleteGroup("constraint"));
+
+    OptionGroup grp = new OptionGroup();
+    grp.addOption(OptUtil.tableOpt("table to add, delete, or list constraints for"));
+    namespaceOpt = new Option(Shell.namespaceOption, "namespace", true, "name of a namespace to operate on");
+    namespaceOpt.setArgName("namespace");
+    grp.addOption(namespaceOpt);
+
+    o.addOptionGroup(grp);
+    return o;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/CreateNamespaceCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/CreateNamespaceCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/CreateNamespaceCommand.java
new file mode 100644
index 0000000..a9f3deb
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/CreateNamespaceCommand.java
@@ -0,0 +1,99 @@
+/*
+ * 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.accumulo.core.util.shell.commands;
+
+import java.io.IOException;
+import java.util.Map.Entry;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.NamespaceExistsException;
+import org.apache.accumulo.core.client.NamespaceNotFoundException;
+import org.apache.accumulo.core.client.TableExistsException;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.core.conf.Property;
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.core.util.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.OptionGroup;
+import org.apache.commons.cli.Options;
+
+public class CreateNamespaceCommand extends Command {
+  private Option createNamespaceOptCopyConfig;
+
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException,
+      TableExistsException, TableNotFoundException, IOException, ClassNotFoundException, NamespaceExistsException, NamespaceNotFoundException {
+
+    if (createNamespaceOptCopyConfig == null) {
+      getOptions();
+    }
+
+    String namespace = cl.getArgs()[0];
+
+    shellState.getConnector().namespaceOperations().create(namespace);
+
+    // Copy options if flag was set
+    Iterable<Entry<String,String>> configuration = null;
+    if (cl.hasOption(createNamespaceOptCopyConfig.getOpt())) {
+      String copy = cl.getOptionValue(createNamespaceOptCopyConfig.getOpt());
+      if (shellState.getConnector().namespaceOperations().exists(namespace)) {
+        configuration = shellState.getConnector().namespaceOperations().getProperties(copy);
+      }
+    } 
+    if (configuration != null) {
+      for (Entry<String,String> entry : configuration) {
+        if (Property.isValidTablePropertyKey(entry.getKey())) {
+          shellState.getConnector().namespaceOperations().setProperty(namespace, entry.getKey(), entry.getValue());
+        }
+      }
+    }
+
+    return 0;
+  }
+
+  @Override
+  public String description() {
+    return "creates a new namespace";
+  }
+
+  @Override
+  public String usage() {
+    return getName() + " <namespaceName>";
+  }
+
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+
+    createNamespaceOptCopyConfig = new Option("cc", "copy-config", true, "namespace to copy configuration from");
+    createNamespaceOptCopyConfig.setArgName("namespace");
+
+    OptionGroup ogp = new OptionGroup();
+    ogp.addOption(createNamespaceOptCopyConfig);
+
+    o.addOptionGroup(ogp);
+
+    return o;
+  }
+
+  @Override
+  public int numArgs() {
+    return 1;
+  }
+}


[19/53] [abbrv] git commit: Merge branch '1.5.2-SNAPSHOT' into 1.6.0-SNAPSHOT

Posted by el...@apache.org.
Merge branch '1.5.2-SNAPSHOT' into 1.6.0-SNAPSHOT

Conflicts:
	core/src/main/java/org/apache/accumulo/core/client/mapreduce/InputFormatBase.java
	core/src/test/java/org/apache/accumulo/core/client/mapreduce/EmptySplitsAccumuloInputFormat.java
	server/master/src/main/java/org/apache/accumulo/master/util/FateAdmin.java


Project: http://git-wip-us.apache.org/repos/asf/accumulo/repo
Commit: http://git-wip-us.apache.org/repos/asf/accumulo/commit/14e2b64f
Tree: http://git-wip-us.apache.org/repos/asf/accumulo/tree/14e2b64f
Diff: http://git-wip-us.apache.org/repos/asf/accumulo/diff/14e2b64f

Branch: refs/heads/ACCUMULO-378
Commit: 14e2b64f74c5ecb1e9f906045d461830daa278ae
Parents: 88f24d2 5363d78
Author: Christopher Tubbs <ct...@apache.org>
Authored: Mon Apr 7 20:31:35 2014 -0400
Committer: Christopher Tubbs <ct...@apache.org>
Committed: Mon Apr 7 20:31:35 2014 -0400

----------------------------------------------------------------------
 .../core/client/mapred/InputFormatBase.java     |  1 +
 .../client/mapreduce/AccumuloInputFormat.java   |  2 +-
 .../core/client/mapreduce/InputFormatBase.java  |  1 +
 .../EmptySplitsAccumuloInputFormat.java         | 10 ++++----
 .../org/apache/accumulo/fate/ReadOnlyStore.java | 22 ++++++++---------
 .../java/org/apache/accumulo/fate/TStore.java   | 16 ++++++-------
 .../apache/accumulo/master/util/FateAdmin.java  | 25 ++++++++++----------
 7 files changed, 39 insertions(+), 38 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/accumulo/blob/14e2b64f/core/src/main/java/org/apache/accumulo/core/client/mapred/InputFormatBase.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/accumulo/blob/14e2b64f/core/src/main/java/org/apache/accumulo/core/client/mapreduce/AccumuloInputFormat.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/accumulo/blob/14e2b64f/core/src/main/java/org/apache/accumulo/core/client/mapreduce/InputFormatBase.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/accumulo/blob/14e2b64f/core/src/test/java/org/apache/accumulo/core/client/mapreduce/EmptySplitsAccumuloInputFormat.java
----------------------------------------------------------------------
diff --cc core/src/test/java/org/apache/accumulo/core/client/mapreduce/EmptySplitsAccumuloInputFormat.java
index 7d3dde6,68ac78f..dd531c0
--- a/core/src/test/java/org/apache/accumulo/core/client/mapreduce/EmptySplitsAccumuloInputFormat.java
+++ b/core/src/test/java/org/apache/accumulo/core/client/mapreduce/EmptySplitsAccumuloInputFormat.java
@@@ -27,19 -27,11 +27,19 @@@ import org.apache.hadoop.mapreduce.JobC
   * AccumuloInputFormat which returns an "empty" RangeInputSplit
   */
  public class EmptySplitsAccumuloInputFormat extends AccumuloInputFormat {
-   
+ 
    @Override
    public List<InputSplit> getSplits(JobContext context) throws IOException {
 -    super.getSplits(context);
 +    List<InputSplit> oldSplits = super.getSplits(context);
 +    List<InputSplit> newSplits = new ArrayList<InputSplit>(oldSplits.size());
-     
+ 
 -    return Arrays.<InputSplit> asList(new org.apache.accumulo.core.client.mapreduce.RangeInputSplit());
 +    // Copy only the necessary information
 +    for (InputSplit oldSplit : oldSplits) {
-       org.apache.accumulo.core.client.mapreduce.RangeInputSplit newSplit = new org.apache.accumulo.core.client.mapreduce.RangeInputSplit((org.apache.accumulo.core.client.mapreduce.RangeInputSplit) oldSplit);
++      org.apache.accumulo.core.client.mapreduce.RangeInputSplit newSplit = new org.apache.accumulo.core.client.mapreduce.RangeInputSplit(
++          (org.apache.accumulo.core.client.mapreduce.RangeInputSplit) oldSplit);
 +      newSplits.add(newSplit);
 +    }
-     
-     
++
 +    return newSplits;
    }
  }

http://git-wip-us.apache.org/repos/asf/accumulo/blob/14e2b64f/server/master/src/main/java/org/apache/accumulo/master/util/FateAdmin.java
----------------------------------------------------------------------
diff --cc server/master/src/main/java/org/apache/accumulo/master/util/FateAdmin.java
index 4e72832,0000000..759bb70
mode 100644,000000..100644
--- a/server/master/src/main/java/org/apache/accumulo/master/util/FateAdmin.java
+++ b/server/master/src/main/java/org/apache/accumulo/master/util/FateAdmin.java
@@@ -1,93 -1,0 +1,94 @@@
 +/*
 + * 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.accumulo.master.util;
 +
 +import java.util.ArrayList;
 +import java.util.List;
 +
 +import org.apache.accumulo.core.Constants;
 +import org.apache.accumulo.core.cli.Help;
 +import org.apache.accumulo.core.client.Instance;
 +import org.apache.accumulo.core.zookeeper.ZooUtil;
 +import org.apache.accumulo.fate.AdminUtil;
- import org.apache.accumulo.fate.ZooStore;
 +import org.apache.accumulo.fate.ReadOnlyStore;
++import org.apache.accumulo.fate.ZooStore;
 +import org.apache.accumulo.fate.zookeeper.IZooReaderWriter;
 +import org.apache.accumulo.master.Master;
 +import org.apache.accumulo.server.client.HdfsZooInstance;
 +import org.apache.accumulo.server.zookeeper.ZooReaderWriter;
 +
 +import com.beust.jcommander.JCommander;
 +import com.beust.jcommander.Parameter;
 +import com.beust.jcommander.Parameters;
 +
 +/**
 + * A utility to administer FATE operations
 + */
 +public class FateAdmin {
-   
++
 +  static class TxOpts {
 +    @Parameter(description = "<txid>", required = true)
 +    List<String> args = new ArrayList<String>();
 +  }
-   
++
 +  @Parameters(commandDescription = "Stop an existing FATE by transaction id")
 +  static class FailOpts extends TxOpts {}
-   
++
 +  @Parameters(commandDescription = "Delete an existing FATE by transaction id")
 +  static class DeleteOpts extends TxOpts {}
-   
++
 +  @Parameters(commandDescription = "List the existing FATE transactions")
 +  static class PrintOpts {}
-   
++
 +  public static void main(String[] args) throws Exception {
 +    Help opts = new Help();
 +    JCommander jc = new JCommander(opts);
 +    jc.setProgramName(FateAdmin.class.getName());
 +    jc.addCommand("fail", new FailOpts());
 +    jc.addCommand("delete", new DeleteOpts());
 +    jc.addCommand("print", new PrintOpts());
 +    jc.parse(args);
 +    if (opts.help || jc.getParsedCommand() == null) {
 +      jc.usage();
 +      System.exit(1);
 +    }
-     
-     System.err.printf("This tool has been deprecated%nFATE administration now available within 'accumulo shell'%n$ fate fail <txid>... | delete <txid>... | print [<txid>...]%n%n");
-     
++
++    System.err
++        .printf("This tool has been deprecated%nFATE administration now available within 'accumulo shell'%n$ fate fail <txid>... | delete <txid>... | print [<txid>...]%n%n");
++
 +    AdminUtil<Master> admin = new AdminUtil<Master>();
-     
++
 +    Instance instance = HdfsZooInstance.getInstance();
 +    String path = ZooUtil.getRoot(instance) + Constants.ZFATE;
 +    String masterPath = ZooUtil.getRoot(instance) + Constants.ZMASTER_LOCK;
 +    IZooReaderWriter zk = ZooReaderWriter.getRetryingInstance();
 +    ZooStore<Master> zs = new ZooStore<Master>(path, zk);
-     
++
 +    if (jc.getParsedCommand().equals("fail")) {
 +      if (!admin.prepFail(zs, zk, masterPath, args[1])) {
 +        System.exit(1);
 +      }
 +    } else if (jc.getParsedCommand().equals("delete")) {
 +      if (!admin.prepDelete(zs, zk, masterPath, args[1])) {
 +        System.exit(1);
 +      }
 +      admin.deleteLocks(zs, zk, ZooUtil.getRoot(instance) + Constants.ZTABLE_LOCKS, args[1]);
 +    } else if (jc.getParsedCommand().equals("print")) {
-       admin.print(new ReadOnlyStore(zs), zk, ZooUtil.getRoot(instance) + Constants.ZTABLE_LOCKS);
++      admin.print(new ReadOnlyStore<Master>(zs), zk, ZooUtil.getRoot(instance) + Constants.ZTABLE_LOCKS);
 +    }
 +  }
 +}


[02/53] [abbrv] ACCUMULO-1897 Move shell into new package and module

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/TableOperation.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/TableOperation.java b/shell/src/main/java/org/apache/accumulo/shell/commands/TableOperation.java
new file mode 100644
index 0000000..032579b
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/TableOperation.java
@@ -0,0 +1,153 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.util.Map;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import org.apache.accumulo.core.client.Instance;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.core.client.impl.Namespaces;
+import org.apache.accumulo.core.client.impl.Tables;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Token;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.OptionGroup;
+import org.apache.commons.cli.Options;
+
+public abstract class TableOperation extends Command {
+
+  protected Option optTablePattern, optTableName, optNamespace;
+  private boolean force = true;
+  private boolean useCommandLine = true;
+
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    // populate the tableSet set with the tables you want to operate on
+    final SortedSet<String> tableSet = new TreeSet<String>();
+    if (cl.hasOption(optTablePattern.getOpt())) {
+      for (String table : shellState.getConnector().tableOperations().list())
+        if (table.matches(cl.getOptionValue(optTablePattern.getOpt()))) {
+          tableSet.add(table);
+        }
+    } else if (cl.hasOption(optTableName.getOpt())) {
+      tableSet.add(cl.getOptionValue(optTableName.getOpt()));
+    } else if (cl.hasOption(optNamespace.getOpt())) {
+      Instance instance = shellState.getInstance();
+      String namespaceId = Namespaces.getNamespaceId(instance, cl.getOptionValue(optNamespace.getOpt()));
+      for (String tableId : Namespaces.getTableIds(instance, namespaceId)) {
+        tableSet.add(Tables.getTableName(instance, tableId));
+      }
+    } else if (useCommandLine && cl.getArgs().length > 0) {
+      for (String tableName : cl.getArgs()) {
+        tableSet.add(tableName);
+      }
+    } else {
+      shellState.checkTableState();
+      tableSet.add(shellState.getTableName());
+    }
+
+    if (tableSet.isEmpty())
+      Shell.log.warn("No tables found that match your criteria");
+
+    boolean more = true;
+    // flush the tables
+    for (String tableName : tableSet) {
+      if (!more) {
+        break;
+      }
+      if (!shellState.getConnector().tableOperations().exists(tableName)) {
+        throw new TableNotFoundException(null, tableName, null);
+      }
+      boolean operate = true;
+      if (!force) {
+        shellState.getReader().flush();
+        String line = shellState.getReader().readLine(getName() + " { " + tableName + " } (yes|no)? ");
+        more = line != null;
+        operate = line != null && (line.equalsIgnoreCase("y") || line.equalsIgnoreCase("yes"));
+      }
+      if (operate) {
+        doTableOp(shellState, tableName);
+      }
+    }
+
+    return 0;
+  }
+
+  protected abstract void doTableOp(Shell shellState, String tableName) throws Exception;
+
+  @Override
+  public String description() {
+    return "makes a best effort to flush tables from memory to disk";
+  }
+
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+
+    optTablePattern = new Option("p", "pattern", true, "regex pattern of table names to operate on");
+    optTablePattern.setArgName("pattern");
+
+    optTableName = new Option(Shell.tableOption, "table", true, "name of a table to operate on");
+    optTableName.setArgName("tableName");
+
+    optNamespace = new Option(Shell.namespaceOption, "namespace", true, "name of a namespace to operate on");
+    optNamespace.setArgName("namespace");
+
+    final OptionGroup opg = new OptionGroup();
+
+    opg.addOption(optTablePattern);
+    opg.addOption(optTableName);
+    opg.addOption(optNamespace);
+
+    o.addOptionGroup(opg);
+
+    return o;
+  }
+
+  @Override
+  public int numArgs() {
+    return useCommandLine ? Shell.NO_FIXED_ARG_LENGTH_CHECK : 0;
+  }
+
+  protected void force() {
+    force = true;
+  }
+
+  protected void noForce() {
+    force = false;
+  }
+
+  protected void disableUnflaggedTableOptions() {
+    useCommandLine = false;
+  }
+
+  @Override
+  public String usage() {
+    return getName() + " [<table>{ <table>}]";
+  }
+
+  @Override
+  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> special) {
+    if (useCommandLine)
+      registerCompletionForTables(root, special);
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/TablePermissionsCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/TablePermissionsCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/TablePermissionsCommand.java
new file mode 100644
index 0000000..75e3fbd
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/TablePermissionsCommand.java
@@ -0,0 +1,44 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.io.IOException;
+
+import org.apache.accumulo.core.security.TablePermission;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+
+public class TablePermissionsCommand extends Command {
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws IOException {
+    for (String p : TablePermission.printableValues()) {
+      shellState.getReader().println(p);
+    }
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "displays a list of valid table permissions";
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/TablesCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/TablesCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/TablesCommand.java
new file mode 100644
index 0000000..5bded8d
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/TablesCommand.java
@@ -0,0 +1,107 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.TreeMap;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.NamespaceNotFoundException;
+import org.apache.accumulo.core.client.impl.Tables;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+import org.apache.commons.collections.MapUtils;
+
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+import com.google.common.collect.Iterators;
+import com.google.common.collect.Maps;
+
+public class TablesCommand extends Command {
+  static final String NAME_AND_ID_FORMAT = "%-20s => %9s%n";
+
+  private Option tableIdOption;
+  private Option sortByTableIdOption;
+  private Option disablePaginationOpt;
+
+  @SuppressWarnings("unchecked")
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException, IOException,
+      NamespaceNotFoundException {
+
+    final String namespace = cl.hasOption(OptUtil.namespaceOpt().getOpt()) ? OptUtil.getNamespaceOpt(cl, shellState) : null;
+    Map<String,String> tables = shellState.getConnector().tableOperations().tableIdMap();
+
+    // filter only specified namespace
+    tables = Maps.filterKeys(tables, new Predicate<String>() {
+      @Override
+      public boolean apply(String tableName) {
+        return namespace == null || Tables.qualify(tableName).getFirst().equals(namespace);
+      }
+    });
+
+    final boolean sortByTableId = cl.hasOption(sortByTableIdOption.getOpt());
+    tables = new TreeMap<String,String>((sortByTableId ? MapUtils.invertMap(tables) : tables));
+
+    Iterator<String> it = Iterators.transform(tables.entrySet().iterator(), new Function<Entry<String,String>,String>() {
+      @Override
+      public String apply(Map.Entry<String,String> entry) {
+        String tableName = String.valueOf(sortByTableId ? entry.getValue() : entry.getKey());
+        String tableId = String.valueOf(sortByTableId ? entry.getKey() : entry.getValue());
+        if (namespace != null)
+          tableName = Tables.qualify(tableName).getSecond();
+        if (cl.hasOption(tableIdOption.getOpt()))
+          return String.format(NAME_AND_ID_FORMAT, tableName, tableId);
+        else
+          return tableName;
+      };
+    });
+
+    shellState.printLines(it, !cl.hasOption(disablePaginationOpt.getOpt()));
+    return 0;
+  }
+
+  @Override
+  public String description() {
+    return "displays a list of all existing tables";
+  }
+
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+    tableIdOption = new Option("l", "list-ids", false, "display internal table ids along with the table name");
+    o.addOption(tableIdOption);
+    sortByTableIdOption = new Option("s", "sort-ids", false, "with -l: sort output by table ids");
+    o.addOption(sortByTableIdOption);
+    disablePaginationOpt = new Option("np", "no-pagination", false, "disable pagination of output");
+    o.addOption(disablePaginationOpt);
+    o.addOption(OptUtil.namespaceOpt("name of namespace to list only its tables"));
+    return o;
+  }
+
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/TraceCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/TraceCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/TraceCommand.java
new file mode 100644
index 0000000..7f63570
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/TraceCommand.java
@@ -0,0 +1,101 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.io.IOException;
+import java.util.Map;
+
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.trace.instrument.Trace;
+import org.apache.accumulo.core.client.Scanner;
+import org.apache.accumulo.core.conf.Property;
+import org.apache.accumulo.core.data.Range;
+import org.apache.accumulo.core.security.Authorizations;
+import org.apache.accumulo.core.trace.TraceDump;
+import org.apache.accumulo.core.trace.TraceDump.Printer;
+import org.apache.accumulo.core.util.BadArgumentException;
+import org.apache.accumulo.core.util.UtilWaitThread;
+import org.apache.commons.cli.CommandLine;
+import org.apache.hadoop.io.Text;
+
+public class TraceCommand extends DebugCommand {
+  
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws IOException {
+    if (cl.getArgs().length == 1) {
+      if (cl.getArgs()[0].equalsIgnoreCase("on")) {
+        Trace.on("shell:" + shellState.getPrincipal());
+      } else if (cl.getArgs()[0].equalsIgnoreCase("off")) {
+        if (Trace.isTracing()) {
+          final long trace = Trace.currentTrace().traceId();
+          Trace.off();
+          StringBuffer sb = new StringBuffer();
+          int traceCount = 0;
+          for (int i = 0; i < 30; i++) {
+            sb = new StringBuffer();
+            try {
+              final Map<String,String> properties = shellState.getConnector().instanceOperations().getSystemConfiguration();
+              final String table = properties.get(Property.TRACE_TABLE.getKey());
+              final String user = shellState.getConnector().whoami();
+              final Authorizations auths = shellState.getConnector().securityOperations().getUserAuthorizations(user);
+              final Scanner scanner = shellState.getConnector().createScanner(table, auths);
+              scanner.setRange(new Range(new Text(Long.toHexString(trace))));
+              final StringBuffer finalSB = sb;
+              traceCount = TraceDump.printTrace(scanner, new Printer() {
+                @Override
+                public void print(final String line) {
+                  try {
+                    finalSB.append(line + "\n");
+                  } catch (Exception ex) {
+                    throw new RuntimeException(ex);
+                  }
+                }
+              });
+              if (traceCount > 0) {
+                shellState.getReader().print(sb.toString());
+                break;
+              }
+            } catch (Exception ex) {
+              shellState.printException(ex);
+            }
+            shellState.getReader().println("Waiting for trace information");
+            shellState.getReader().flush();
+            UtilWaitThread.sleep(500);
+          }
+          if (traceCount < 0) {
+            // display the trace even though there are unrooted spans
+            shellState.getReader().print(sb.toString());
+          }
+        } else {
+          shellState.getReader().println("Not tracing");
+        }
+      } else
+        throw new BadArgumentException("Argument must be 'on' or 'off'", fullCommand, fullCommand.indexOf(cl.getArgs()[0]));
+    } else if (cl.getArgs().length == 0) {
+      shellState.getReader().println(Trace.isTracing() ? "on" : "off");
+    } else {
+      shellState.printException(new IllegalArgumentException("Expected 0 or 1 argument. There were " + cl.getArgs().length + "."));
+      printHelp(shellState);
+      return 1;
+    }
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "turns trace logging on or off";
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/UserCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/UserCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/UserCommand.java
new file mode 100644
index 0000000..491f144
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/UserCommand.java
@@ -0,0 +1,71 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.security.tokens.PasswordToken;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Token;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+
+public class UserCommand extends Command {
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException, IOException {
+    // save old credentials and connection in case of failure
+    String user = cl.getArgs()[0];
+    byte[] pass;
+    
+    // We can't let the wrapping try around the execute method deal
+    // with the exceptions because we have to do something if one
+    // of these methods fails
+    final String p = shellState.readMaskedLine("Enter password for user " + user + ": ", '*');
+    if (p == null) {
+      shellState.getReader().println();
+      return 0;
+    } // user canceled
+    pass = p.getBytes(StandardCharsets.UTF_8);
+    shellState.updateUser(user, new PasswordToken(pass));
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "switches to the specified user";
+  }
+  
+  @Override
+  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> special) {
+    registerCompletionForUsers(root, special);
+  }
+  
+  @Override
+  public String usage() {
+    return getName() + " <username>";
+  }
+  
+  @Override
+  public int numArgs() {
+    return 1;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/UserPermissionsCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/UserPermissionsCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/UserPermissionsCommand.java
new file mode 100644
index 0000000..ad6a20d
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/UserPermissionsCommand.java
@@ -0,0 +1,106 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.io.IOException;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.security.NamespacePermission;
+import org.apache.accumulo.core.security.SystemPermission;
+import org.apache.accumulo.core.security.TablePermission;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+
+public class UserPermissionsCommand extends Command {
+  private Option userOpt;
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException, IOException {
+    final String user = cl.getOptionValue(userOpt.getOpt(), shellState.getConnector().whoami());
+
+    String delim = "";
+    shellState.getReader().print("System permissions: ");
+    for (SystemPermission p : SystemPermission.values()) {
+      if (p != null && shellState.getConnector().securityOperations().hasSystemPermission(user, p)) {
+        shellState.getReader().print(delim + "System." + p.name());
+        delim = ", ";
+      }
+    }
+    shellState.getReader().println();
+
+    boolean runOnce = true;
+    for (String n : shellState.getConnector().namespaceOperations().list()) {
+      delim = "";
+      for (NamespacePermission p : NamespacePermission.values()) {
+        if (p != null && shellState.getConnector().securityOperations().hasNamespacePermission(user, n, p)) {
+          if (runOnce) {
+            shellState.getReader().print("\nNamespace permissions (" + n + "): ");
+            runOnce = false;
+          }
+          shellState.getReader().print(delim + "Namespace." + p.name());
+          delim = ", ";
+        }
+      }
+      runOnce = true;
+    }
+    shellState.getReader().println();
+
+    
+    runOnce = true;
+    for (String t : shellState.getConnector().tableOperations().list()) {
+      delim = "";
+      for (TablePermission p : TablePermission.values()) {
+        if (shellState.getConnector().securityOperations().hasTablePermission(user, t, p) && p != null) {
+          if (runOnce) {
+            shellState.getReader().print("\nTable permissions (" + t + "): ");
+            runOnce = false;
+          }
+          shellState.getReader().print(delim + "Table." + p.name());
+          delim = ", ";
+        }
+
+      }
+      runOnce = true;
+    }
+    shellState.getReader().println();
+
+    return 0;
+  }
+
+  @Override
+  public String description() {
+    return "displays a user's system, table, and namespace permissions";
+  }
+
+  @Override
+  public Options getOptions() {
+    Options o = new Options();
+    userOpt = new Option(Shell.userOption, "user", true, "user to operate on");
+    userOpt.setArgName("user");
+    o.addOption(userOpt);
+    return o;
+  }
+
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/UsersCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/UsersCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/UsersCommand.java
new file mode 100644
index 0000000..5ea61bf
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/UsersCommand.java
@@ -0,0 +1,45 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.io.IOException;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+
+public class UsersCommand extends Command {
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException, IOException {
+    for (String user : shellState.getConnector().securityOperations().listLocalUsers()) {
+      shellState.getReader().println(user);
+    }
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "displays a list of existing users";
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/commands/WhoAmICommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/WhoAmICommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/WhoAmICommand.java
new file mode 100644
index 0000000..f80a621
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/WhoAmICommand.java
@@ -0,0 +1,41 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.io.IOException;
+
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+
+public class WhoAmICommand extends Command {
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws IOException {
+    shellState.getReader().println(shellState.getConnector().whoami());
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "reports the current user name";
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/format/DeleterFormatter.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/format/DeleterFormatter.java b/shell/src/main/java/org/apache/accumulo/shell/format/DeleterFormatter.java
new file mode 100644
index 0000000..b90b55e
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/format/DeleterFormatter.java
@@ -0,0 +1,102 @@
+/*
+ * 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.accumulo.shell.format;
+
+import java.io.IOException;
+import java.util.Map.Entry;
+
+import org.apache.accumulo.core.client.BatchWriter;
+import org.apache.accumulo.core.client.MutationsRejectedException;
+import org.apache.accumulo.core.data.ConstraintViolationSummary;
+import org.apache.accumulo.core.data.Key;
+import org.apache.accumulo.core.data.Mutation;
+import org.apache.accumulo.core.data.Value;
+import org.apache.accumulo.core.security.ColumnVisibility;
+import org.apache.accumulo.core.util.format.DefaultFormatter;
+import org.apache.accumulo.shell.Shell;
+import org.apache.log4j.Logger;
+
+public class DeleterFormatter extends DefaultFormatter {
+  
+  private static final Logger log = Logger.getLogger(DeleterFormatter.class);
+  private BatchWriter writer;
+  private Shell shellState;
+  private boolean printTimestamps;
+  private boolean force;
+  private boolean more;
+  
+  public DeleterFormatter(BatchWriter writer, Iterable<Entry<Key,Value>> scanner, boolean printTimestamps, Shell shellState, boolean force) {
+    super.initialize(scanner, printTimestamps);
+    this.writer = writer;
+    this.shellState = shellState;
+    this.printTimestamps = printTimestamps;
+    this.force = force;
+    this.more = true;
+  }
+  
+  @Override
+  public boolean hasNext() {
+    if (!getScannerIterator().hasNext() || !more) {
+      try {
+        writer.close();
+      } catch (MutationsRejectedException e) {
+        log.error(e.toString());
+        if (Shell.isDebuggingEnabled())
+          for (ConstraintViolationSummary cvs : e.getConstraintViolationSummaries())
+            log.trace(cvs.toString());
+      }
+      return false;
+    }
+    return true;
+  }
+  
+  /**
+   * @return null, because the iteration will provide prompts and handle deletes internally.
+   */
+  @Override
+  public String next() {
+    Entry<Key,Value> next = getScannerIterator().next();
+    Key key = next.getKey();
+    Mutation m = new Mutation(key.getRow());
+    String entryStr = formatEntry(next, printTimestamps);
+    boolean delete = force;
+    try {
+      if (!force) {
+        shellState.getReader().flush();
+        String line = shellState.getReader().readLine("Delete { " + entryStr + " } ? ");
+        more = line != null;
+        delete = line != null && (line.equalsIgnoreCase("y") || line.equalsIgnoreCase("yes"));
+      }
+      if (delete) {
+        m.putDelete(key.getColumnFamily(), key.getColumnQualifier(), new ColumnVisibility(key.getColumnVisibility()), key.getTimestamp());
+        try {
+          writer.addMutation(m);
+        } catch (MutationsRejectedException e) {
+          log.error(e.toString());
+          if (Shell.isDebuggingEnabled())
+            for (ConstraintViolationSummary cvs : e.getConstraintViolationSummaries())
+              log.trace(cvs.toString());
+        }
+      }
+      shellState.getReader().print(String.format("[%s] %s%n", delete ? "DELETED" : "SKIPPED", entryStr));
+    } catch (IOException e) {
+      log.error("Cannot write to console", e);
+      throw new RuntimeException(e);
+    }
+    return null;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/java/org/apache/accumulo/shell/mock/MockShell.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/mock/MockShell.java b/shell/src/main/java/org/apache/accumulo/shell/mock/MockShell.java
new file mode 100644
index 0000000..151648a
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/mock/MockShell.java
@@ -0,0 +1,143 @@
+/*
+ * 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.accumulo.shell.mock;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.charset.StandardCharsets;
+
+import jline.console.ConsoleReader;
+
+import org.apache.accumulo.core.client.mock.MockInstance;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.ShellOptionsJC;
+
+/**
+ * An Accumulo Shell implementation that allows a developer to attach an InputStream and Writer to the Shell for testing purposes.
+ */
+public class MockShell extends Shell {
+  private static final String NEWLINE = "\n";
+  
+  protected InputStream in;
+  protected OutputStream out;
+  
+  public MockShell(InputStream in, OutputStream out) throws IOException {
+    super();
+    this.in = in;
+    this.out = out;
+  }
+  
+  public boolean config(String... args) {
+    configError = super.config(args);
+    
+    // Update the ConsoleReader with the input and output "redirected"
+    try {
+      this.reader = new ConsoleReader(in, out);
+    } catch (Exception e) {
+      printException(e);
+      configError = true;
+    }
+    
+    // Don't need this for testing purposes
+    this.reader.setHistoryEnabled(false);
+    this.reader.setPaginationEnabled(false);
+    
+    // Make the parsing from the client easier;
+    this.verbose = false;
+    return configError;
+  }
+  
+  @Override
+  protected void setInstance(ShellOptionsJC options) {
+    // We always want a MockInstance for this test
+    instance = new MockInstance();
+  }
+  
+  public int start() throws IOException {
+    if (configError)
+      return 1;
+    
+    String input;
+    if (isVerbose())
+      printInfo();
+    
+    if (execFile != null) {
+      java.util.Scanner scanner = new java.util.Scanner(execFile, StandardCharsets.UTF_8.name());
+      try {
+        while (scanner.hasNextLine() && !hasExited()) {
+          execCommand(scanner.nextLine(), true, isVerbose());
+        }
+      } finally {
+        scanner.close();
+      }
+    } else if (execCommand != null) {
+      for (String command : execCommand.split("\n")) {
+        execCommand(command, true, isVerbose());
+      }
+      return exitCode;
+    }
+    
+    while (true) {
+      if (hasExited())
+        return exitCode;
+      
+      reader.setPrompt(getDefaultPrompt());
+      input = reader.readLine();
+      if (input == null) {
+        reader.println();
+        return exitCode;
+      } // user canceled
+      
+      execCommand(input, false, false);
+    }
+  }
+  
+  /**
+   * @param in
+   *          the in to set
+   */
+  public void setConsoleInputStream(InputStream in) {
+    this.in = in;
+  }
+  
+  /**
+   * @param out
+   *          the output stream to set
+   */
+  public void setConsoleWriter(OutputStream out) {
+    this.out = out;
+  }
+  
+  /**
+   * Convenience method to create the byte-array to hand to the console
+   * 
+   * @param commands
+   *          An array of commands to run
+   * @return A byte[] input stream which can be handed to the console.
+   */
+  public static ByteArrayInputStream makeCommands(String... commands) {
+    StringBuilder sb = new StringBuilder(commands.length * 8);
+    
+    for (String command : commands) {
+      sb.append(command).append(NEWLINE);
+    }
+    
+    return new ByteArrayInputStream(sb.toString().getBytes(StandardCharsets.UTF_8));
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/main/resources/.gitignore
----------------------------------------------------------------------
diff --git a/shell/src/main/resources/.gitignore b/shell/src/main/resources/.gitignore
new file mode 100644
index 0000000..e69de29

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/test/java/org/apache/accumulo/shell/PasswordConverterTest.java
----------------------------------------------------------------------
diff --git a/shell/src/test/java/org/apache/accumulo/shell/PasswordConverterTest.java b/shell/src/test/java/org/apache/accumulo/shell/PasswordConverterTest.java
new file mode 100644
index 0000000..8e03830
--- /dev/null
+++ b/shell/src/test/java/org/apache/accumulo/shell/PasswordConverterTest.java
@@ -0,0 +1,113 @@
+/*
+ * 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.accumulo.shell;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStreamWriter;
+import java.io.PipedInputStream;
+import java.io.PipedOutputStream;
+import java.util.Scanner;
+
+import org.apache.accumulo.shell.ShellOptionsJC.PasswordConverter;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import com.beust.jcommander.JCommander;
+import com.beust.jcommander.Parameter;
+import com.beust.jcommander.ParameterException;
+
+public class PasswordConverterTest {
+  
+  private class Password {
+    @Parameter(names = "--password", converter = PasswordConverter.class)
+    String password;
+  }
+  
+  private String[] argv;
+  private Password password;
+  private static InputStream realIn;
+  
+  @BeforeClass
+  public static void saveIn() {
+    realIn = System.in;
+  }
+  
+  @Before
+  public void setup() throws IOException {
+    argv = new String[] {"--password", ""};
+    password = new Password();
+    
+    PipedInputStream in = new PipedInputStream();
+    PipedOutputStream out = new PipedOutputStream(in);
+    OutputStreamWriter osw = new OutputStreamWriter(out);
+    osw.write("secret");
+    osw.close();
+    
+    System.setIn(in);
+  }
+  
+  @After
+  public void teardown() {
+    System.setIn(realIn);
+  }
+  
+  @Test
+  public void testPass() {
+    String expected = String.valueOf(Math.random());
+    argv[1] = "pass:" + expected;
+    new JCommander(password, argv);
+    assertEquals(expected, password.password);
+  }
+  
+  @Test
+  public void testEnv() {
+    String name = System.getenv().keySet().iterator().next();
+    argv[1] = "env:" + name;
+    new JCommander(password, argv);
+    assertEquals(System.getenv(name), password.password);
+  }
+  
+  @Test
+  public void testFile() throws FileNotFoundException {
+    argv[1] = "file:pom.xml";
+    Scanner scan = new Scanner(new File("pom.xml"));
+    String expected = scan.nextLine();
+    scan.close();
+    new JCommander(password, argv);
+    assertEquals(expected, password.password);
+  }
+  
+  @Test(expected=ParameterException.class)
+  public void testNoFile() throws FileNotFoundException {
+    argv[1] = "file:doesnotexist";
+    new JCommander(password, argv);
+  }
+
+  @Test
+  public void testStdin() {
+    argv[1] = "stdin";
+    new JCommander(password, argv);
+    assertEquals("stdin", password.password);
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/test/java/org/apache/accumulo/shell/ShellConfigTest.java
----------------------------------------------------------------------
diff --git a/shell/src/test/java/org/apache/accumulo/shell/ShellConfigTest.java b/shell/src/test/java/org/apache/accumulo/shell/ShellConfigTest.java
new file mode 100644
index 0000000..27f3247
--- /dev/null
+++ b/shell/src/test/java/org/apache/accumulo/shell/ShellConfigTest.java
@@ -0,0 +1,91 @@
+/*
+ * 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.accumulo.shell;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.io.FileDescriptor;
+import java.io.FileInputStream;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+
+import jline.console.ConsoleReader;
+
+import org.apache.accumulo.core.client.security.tokens.PasswordToken;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.ShellTest.TestOutputStream;
+import org.apache.log4j.Level;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.beust.jcommander.ParameterException;
+
+public class ShellConfigTest {
+  TestOutputStream output;
+  Shell shell;
+  PrintStream out;
+  
+  @Before
+  public void setUp() throws Exception {
+    Shell.log.setLevel(Level.ERROR);
+    
+    out = System.out;
+    output = new TestOutputStream();
+    System.setOut(new PrintStream(output));
+
+    shell = new Shell(new ConsoleReader(new FileInputStream(FileDescriptor.in), output), new PrintWriter(output));
+    shell.setLogErrorsToConsole();
+  }
+  
+  @After
+  public void teardown() throws Exception {
+    shell.shutdown();
+    output.clear();
+    System.setOut(out);
+  }
+  
+  @Test
+  public void testHelp() {
+    assertTrue(shell.config("--help"));
+    assertTrue("Did not print usage", output.get().startsWith("Usage"));
+  }
+  
+  @Test
+  public void testBadArg() {
+    assertTrue(shell.config("--bogus"));
+    assertTrue("Did not print usage", output.get().startsWith("Usage"));
+  }
+  
+  @Test
+  public void testToken() {
+    assertTrue(shell.config("--fake", "-tc", PasswordToken.class.getCanonicalName()));
+    assertTrue(output.get().contains(ParameterException.class.getCanonicalName()));
+  }
+  
+  @Test
+  public void testTokenAndOption() {
+    assertFalse(shell.config("--fake", "-tc", PasswordToken.class.getCanonicalName(), "-u", "foo", "-l", "password=foo"));
+  }
+  
+  @Test
+  public void testTokenAndOptionAndPassword() {
+    assertTrue(shell.config("--fake", "-tc", PasswordToken.class.getCanonicalName(), "-l", "password=foo", "-p", "bar"));
+    assertTrue(output.get().contains(ParameterException.class.getCanonicalName()));
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/test/java/org/apache/accumulo/shell/ShellSetInstanceTest.java
----------------------------------------------------------------------
diff --git a/shell/src/test/java/org/apache/accumulo/shell/ShellSetInstanceTest.java b/shell/src/test/java/org/apache/accumulo/shell/ShellSetInstanceTest.java
new file mode 100644
index 0000000..463f97d
--- /dev/null
+++ b/shell/src/test/java/org/apache/accumulo/shell/ShellSetInstanceTest.java
@@ -0,0 +1,244 @@
+/*
+ * 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.accumulo.shell;
+
+import static org.easymock.EasyMock.anyObject;
+import static org.easymock.EasyMock.expect;
+import static org.powermock.api.easymock.PowerMock.createMock;
+import static org.powermock.api.easymock.PowerMock.expectLastCall;
+import static org.powermock.api.easymock.PowerMock.expectNew;
+import static org.powermock.api.easymock.PowerMock.mockStatic;
+import static org.powermock.api.easymock.PowerMock.replay;
+import static org.powermock.api.easymock.PowerMock.verify;
+
+import java.io.FileDescriptor;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.util.Collections;
+import java.util.List;
+import java.util.UUID;
+
+import jline.console.ConsoleReader;
+
+import org.apache.accumulo.core.client.ClientConfiguration;
+import org.apache.accumulo.core.client.ClientConfiguration.ClientProperty;
+import org.apache.accumulo.core.client.ZooKeeperInstance;
+import org.apache.accumulo.core.client.mock.MockInstance;
+import org.apache.accumulo.core.conf.AccumuloConfiguration;
+import org.apache.accumulo.core.conf.ConfigSanityCheck;
+import org.apache.accumulo.core.conf.Property;
+import org.apache.accumulo.core.conf.SiteConfiguration;
+import org.apache.accumulo.core.zookeeper.ZooUtil;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.ShellOptionsJC;
+import org.apache.hadoop.fs.Path;
+import org.apache.log4j.Level;
+import org.easymock.EasyMock;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+@RunWith(PowerMockRunner.class)
+@PrepareForTest({Shell.class, ZooUtil.class, ConfigSanityCheck.class})
+public class ShellSetInstanceTest {
+  public static class TestOutputStream extends OutputStream {
+    StringBuilder sb = new StringBuilder();
+
+    @Override
+    public void write(int b) throws IOException {
+      sb.append((char) (0xff & b));
+    }
+
+    public String get() {
+      return sb.toString();
+    }
+
+    public void clear() {
+      sb.setLength(0);
+    }
+  }
+
+  @BeforeClass
+  public static void setupClass() {
+    // This is necessary because PowerMock messes with Hadoop's ability to
+    // determine the current user (see security.UserGroupInformation).
+    System.setProperty("HADOOP_USER_NAME", "test");
+  }
+  @AfterClass
+  public static void teardownClass() {
+    System.clearProperty("HADOOP_USER_NAME");
+  }
+
+  private TestOutputStream output;
+  private Shell shell;
+
+  @Before
+  public void setup() throws IOException {
+    Shell.log.setLevel(Level.OFF);
+    output = new TestOutputStream();
+    shell = new Shell(new ConsoleReader(new FileInputStream(FileDescriptor.in), output), new PrintWriter(output));
+    shell.setLogErrorsToConsole();
+  }
+  @After
+  public void tearDown() {
+    shell.shutdown();
+    SiteConfiguration.clearInstance();
+  }
+
+  @Test
+  public void testSetInstance_Fake() throws Exception {
+    ShellOptionsJC opts = createMock(ShellOptionsJC.class);
+    expect(opts.isFake()).andReturn(true);
+    replay(opts);
+    MockInstance theInstance = createMock(MockInstance.class);
+    expectNew(MockInstance.class, "fake").andReturn(theInstance);
+    replay(theInstance, MockInstance.class);
+
+    shell.setInstance(opts);
+    verify(theInstance, MockInstance.class);
+  }
+  @Test
+  public void testSetInstance_HdfsZooInstance_Explicit() throws Exception {
+    testSetInstance_HdfsZooInstance(true, false, false);
+  }
+  @Test
+  public void testSetInstance_HdfsZooInstance_InstanceGiven() throws Exception {
+    testSetInstance_HdfsZooInstance(false, true, false);
+  }
+  @Test
+  public void testSetInstance_HdfsZooInstance_HostsGiven() throws Exception {
+    testSetInstance_HdfsZooInstance(false, false, true);
+  }
+  @Test
+  public void testSetInstance_HdfsZooInstance_Implicit() throws Exception {
+    testSetInstance_HdfsZooInstance(false, false, false);
+  }
+  
+  @SuppressWarnings("deprecation")
+  private void testSetInstance_HdfsZooInstance(boolean explicitHdfs, boolean onlyInstance, boolean onlyHosts)
+    throws Exception {
+    ClientConfiguration clientConf = createMock(ClientConfiguration.class);
+    ShellOptionsJC opts = createMock(ShellOptionsJC.class);
+    expect(opts.isFake()).andReturn(false);
+    expect(opts.getClientConfiguration()).andReturn(clientConf);
+    expect(opts.isHdfsZooInstance()).andReturn(explicitHdfs);
+    if (!explicitHdfs) {
+      expect(opts.getZooKeeperInstance())
+        .andReturn(Collections.<String>emptyList());
+      if (onlyInstance) {
+        expect(opts.getZooKeeperInstanceName()).andReturn("instance");
+        expect(clientConf.withInstance("instance")).andReturn(clientConf);
+      } else {
+        expect(opts.getZooKeeperInstanceName()).andReturn(null);
+      }
+      if (onlyHosts) {
+        expect(opts.getZooKeeperHosts()).andReturn("host3,host4");
+        expect(clientConf.withZkHosts("host3,host4")).andReturn(clientConf);
+      } else {
+        expect(opts.getZooKeeperHosts()).andReturn(null);
+      }
+    }
+    replay(opts);
+
+    if (!onlyInstance) {
+      expect(clientConf.get(ClientProperty.INSTANCE_NAME)).andReturn(null);
+    }
+
+    mockStatic(ConfigSanityCheck.class);
+    ConfigSanityCheck.validate(EasyMock.<AccumuloConfiguration>anyObject());
+    expectLastCall().atLeastOnce();
+    replay(ConfigSanityCheck.class);
+
+    if (!onlyHosts) {
+      expect(clientConf.containsKey(Property.INSTANCE_ZK_HOST.getKey())).andReturn(true).atLeastOnce();
+      expect(clientConf.getString(Property.INSTANCE_ZK_HOST.getKey())).andReturn("host1,host2").atLeastOnce();
+      expect(clientConf.withZkHosts("host1,host2")).andReturn(clientConf);
+    }
+    if (!onlyInstance) {
+      expect(clientConf.containsKey(Property.INSTANCE_VOLUMES.getKey())).andReturn(false).atLeastOnce();
+      expect(clientConf.containsKey(Property.INSTANCE_DFS_DIR.getKey())).andReturn(true).atLeastOnce();
+      expect(clientConf.containsKey(Property.INSTANCE_DFS_URI.getKey())).andReturn(true).atLeastOnce();
+      expect(clientConf.getString(Property.INSTANCE_DFS_URI.getKey())).andReturn("hdfs://nn1").atLeastOnce();
+      expect(clientConf.getString(Property.INSTANCE_DFS_DIR.getKey())).andReturn("/dfs").atLeastOnce();
+    }
+
+    UUID randomUUID = null;
+    if (!onlyInstance) {
+      mockStatic(ZooUtil.class);
+      randomUUID = UUID.randomUUID();
+      expect(ZooUtil.getInstanceIDFromHdfs(anyObject(Path.class), anyObject(AccumuloConfiguration.class)))
+        .andReturn(randomUUID.toString());
+      replay(ZooUtil.class);
+      expect(clientConf.withInstance(randomUUID)).andReturn(clientConf);
+    }
+    replay(clientConf);
+
+    ZooKeeperInstance theInstance = createMock(ZooKeeperInstance.class);
+    
+    expectNew(ZooKeeperInstance.class, clientConf).andReturn(theInstance);
+    replay(theInstance, ZooKeeperInstance.class);
+
+    shell.setInstance(opts);
+    verify(theInstance, ZooKeeperInstance.class);
+  }
+  @Test
+  public void testSetInstance_ZKInstance_DashZ() throws Exception {
+    testSetInstance_ZKInstance(true);
+  }
+  @Test
+  public void testSetInstance_ZKInstance_DashZIandZH() throws Exception {
+    testSetInstance_ZKInstance(false);
+  }
+  private void testSetInstance_ZKInstance(boolean dashZ) throws Exception {
+    ClientConfiguration clientConf = createMock(ClientConfiguration.class);
+    ShellOptionsJC opts = createMock(ShellOptionsJC.class);
+    expect(opts.isFake()).andReturn(false);
+    expect(opts.getClientConfiguration()).andReturn(clientConf);
+    expect(opts.isHdfsZooInstance()).andReturn(false);
+    if (dashZ) {
+      expect(clientConf.withInstance("foo")).andReturn(clientConf);
+      expect(clientConf.withZkHosts("host1,host2")).andReturn(clientConf);
+      List<String> zl = new java.util.ArrayList<String>();
+      zl.add("foo");
+      zl.add("host1,host2");
+      expect(opts.getZooKeeperInstance()).andReturn(zl);
+      expectLastCall().anyTimes();
+    } else {
+      expect(clientConf.withInstance("bar")).andReturn(clientConf);
+      expect(clientConf.withZkHosts("host3,host4")).andReturn(clientConf);
+      expect(opts.getZooKeeperInstance()).andReturn(Collections.<String>emptyList());
+      expect(opts.getZooKeeperInstanceName()).andReturn("bar");
+      expect(opts.getZooKeeperHosts()).andReturn("host3,host4");
+    }
+    replay(clientConf);
+    replay(opts);
+
+    ZooKeeperInstance theInstance = createMock(ZooKeeperInstance.class);
+    expectNew(ZooKeeperInstance.class, clientConf).andReturn(theInstance);
+    replay(theInstance, ZooKeeperInstance.class);
+
+    shell.setInstance(opts);
+    verify(theInstance, ZooKeeperInstance.class);
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/test/java/org/apache/accumulo/shell/ShellTest.java
----------------------------------------------------------------------
diff --git a/shell/src/test/java/org/apache/accumulo/shell/ShellTest.java b/shell/src/test/java/org/apache/accumulo/shell/ShellTest.java
new file mode 100644
index 0000000..ef12baa
--- /dev/null
+++ b/shell/src/test/java/org/apache/accumulo/shell/ShellTest.java
@@ -0,0 +1,282 @@
+/*
+ * 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.accumulo.shell;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.TimeZone;
+
+import jline.console.ConsoleReader;
+
+import org.apache.accumulo.core.util.format.DateStringFormatter;
+import org.apache.accumulo.shell.Shell;
+import org.apache.log4j.Level;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class ShellTest {
+  public static class TestOutputStream extends OutputStream {
+    StringBuilder sb = new StringBuilder();
+
+    @Override
+    public void write(int b) throws IOException {
+      sb.append((char) (0xff & b));
+    }
+
+    public String get() {
+      return sb.toString();
+    }
+
+    public void clear() {
+      sb.setLength(0);
+    }
+  }
+
+  public static class StringInputStream extends InputStream {
+    private String source = "";
+    private int offset = 0;
+
+    @Override
+    public int read() throws IOException {
+      if (offset == source.length())
+        return '\n';
+      else
+        return source.charAt(offset++);
+    }
+
+    public void set(String other) {
+      source = other;
+      offset = 0;
+    }
+  }
+
+  private StringInputStream input;
+  private TestOutputStream output;
+  private Shell shell;
+
+  void exec(String cmd) throws IOException {
+    output.clear();
+    shell.execCommand(cmd, true, true);
+  }
+
+  void exec(String cmd, boolean expectGoodExit) throws IOException {
+    exec(cmd);
+    if (expectGoodExit)
+      assertGoodExit("", true);
+    else
+      assertBadExit("", true);
+  }
+
+  void exec(String cmd, boolean expectGoodExit, String expectString) throws IOException {
+    exec(cmd, expectGoodExit, expectString, true);
+  }
+
+  void exec(String cmd, boolean expectGoodExit, String expectString, boolean stringPresent) throws IOException {
+    exec(cmd);
+    if (expectGoodExit)
+      assertGoodExit(expectString, stringPresent);
+    else
+      assertBadExit(expectString, stringPresent);
+  }
+
+  @Before
+  public void setup() throws IOException {
+    TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
+    Shell.log.setLevel(Level.OFF);
+    output = new TestOutputStream();
+    input = new StringInputStream();
+    PrintWriter pw = new PrintWriter(new OutputStreamWriter(output));
+    shell = new Shell(new ConsoleReader(input, output), pw);
+    shell.setLogErrorsToConsole();
+    shell.config("--fake", "-u", "test", "-p", "secret");
+  }
+
+  @After
+  public void teardown() {
+    shell.shutdown();
+  }
+
+  void assertGoodExit(String s, boolean stringPresent) {
+    Shell.log.debug(output.get());
+    assertEquals(shell.getExitCode(), 0);
+    if (s.length() > 0)
+      assertEquals(s + " present in " + output.get() + " was not " + stringPresent, stringPresent, output.get().contains(s));
+  }
+
+  void assertBadExit(String s, boolean stringPresent) {
+    Shell.log.debug(output.get());
+    assertTrue(shell.getExitCode() > 0);
+    if (s.length() > 0)
+      assertEquals(s + " present in " + output.get() + " was not " + stringPresent, stringPresent, output.get().contains(s));
+    shell.resetExitCode();
+  }
+
+  @Test
+  public void aboutTest() throws IOException {
+    Shell.log.debug("Starting about test -----------------------------------");
+    exec("about", true, "Shell - Apache Accumulo Interactive Shell");
+    exec("about -v", true, "Current user:");
+    exec("about arg", false, "java.lang.IllegalArgumentException: Expected 0 arguments");
+  }
+
+  @Test
+  public void addGetSplitsTest() throws IOException {
+    Shell.log.debug("Starting addGetSplits test ----------------------------");
+    exec("addsplits arg", false, "java.lang.IllegalStateException: Not in a table context");
+    exec("createtable test", true);
+    exec("addsplits 1 \\x80", true);
+    exec("getsplits", true, "1\n\\x80");
+    exec("deletetable test -f", true, "Table: [test] has been deleted");
+  }
+
+  @Test
+  public void insertDeleteScanTest() throws IOException {
+    Shell.log.debug("Starting insertDeleteScan test ------------------------");
+    exec("insert r f q v", false, "java.lang.IllegalStateException: Not in a table context");
+    exec("delete r f q", false, "java.lang.IllegalStateException: Not in a table context");
+    exec("createtable test", true);
+    exec("insert r f q v", true);
+    exec("scan", true, "r f:q []    v");
+    exec("delete r f q", true);
+    exec("scan", true, "r f:q []    v", false);
+    exec("insert \\x90 \\xa0 \\xb0 \\xc0\\xd0\\xe0\\xf0", true);
+    exec("scan", true, "\\x90 \\xA0:\\xB0 []    \\xC0\\xD0");
+    exec("scan -f 2", true, "\\x90 \\xA0:\\xB0 []    \\xC0\\xD0");
+    exec("scan -f 2", true, "\\x90 \\xA0:\\xB0 []    \\xC0\\xD0\\xE0", false);
+    exec("scan -b \\x90 -e \\x90 -c \\xA0", true, "\\x90 \\xA0:\\xB0 []    \\xC0");
+    exec("scan -b \\x90 -e \\x90 -c \\xA0:\\xB0", true, "\\x90 \\xA0:\\xB0 []    \\xC0");
+    exec("scan -b \\x90 -be", true, "\\x90 \\xA0:\\xB0 []    \\xC0", false);
+    exec("scan -e \\x90 -ee", true, "\\x90 \\xA0:\\xB0 []    \\xC0", false);
+    exec("scan -b \\x90\\x00", true, "\\x90 \\xA0:\\xB0 []    \\xC0", false);
+    exec("scan -e \\x8f", true, "\\x90 \\xA0:\\xB0 []    \\xC0", false);
+    exec("delete \\x90 \\xa0 \\xb0", true);
+    exec("scan", true, "\\x90 \\xA0:\\xB0 []    \\xC0", false);
+    exec("deletetable test -f", true, "Table: [test] has been deleted");
+  }
+
+  @Test
+  public void authsTest() throws Exception {
+    Shell.log.debug("Starting auths test --------------------------");
+    exec("setauths x,y,z", false, "Missing required option");
+    exec("setauths -s x,y,z -u notauser", false, "user does not exist");
+    exec("setauths -s y,z,x", true);
+    exec("getauths -u notauser", false, "user does not exist");
+    exec("getauths", true, "x,y,z");
+    exec("addauths -u notauser", false, "Missing required option");
+    exec("addauths -u notauser -s foo", false, "user does not exist");
+    exec("addauths -s a", true);
+    exec("getauths", true, "a,x,y,z");
+    exec("setauths -c", true);
+  }
+
+  @Test
+  public void userTest() throws Exception {
+    Shell.log.debug("Starting user test --------------------------");
+    // Test cannot be done via junit because createuser only prompts for password
+    // exec("createuser root", false, "user exists");
+  }
+
+  @Test
+  public void duContextTest() throws Exception {
+    Shell.log.debug("Starting du context test --------------------------");
+    exec("createtable t", true);
+    exec("du", true, "0 [t]");
+    exec("deletetable t -f", true, "Table: [t] has been deleted");
+  }
+
+  @Test
+  public void duTest() throws IOException {
+    Shell.log.debug("Starting DU test --------------------------");
+    exec("createtable t", true);
+    exec("du t", true, "0 [t]");
+    exec("deletetable t -f", true, "Table: [t] has been deleted");
+  }
+
+  @Test
+  public void duPatternTest() throws IOException {
+    Shell.log.debug("Starting DU with pattern test --------------------------");
+    exec("createtable t", true);
+    exec("createtable tt", true);
+    exec("du -p t.*", true, "0 [t, tt]");
+    exec("deletetable t -f", true, "Table: [t] has been deleted");
+    exec("deletetable tt -f", true, "Table: [tt] has been deleted");
+  }
+
+  @Test
+  public void scanDateStringFormatterTest() throws IOException {
+    Shell.log.debug("Starting scan dateStringFormatter test --------------------------");
+    exec("createtable t", true);
+    exec("insert r f q v -ts 0", true);
+    DateFormat dateFormat = new SimpleDateFormat(DateStringFormatter.DATE_FORMAT);
+    String expected = String.format("r f:q [] %s    v", dateFormat.format(new Date(0)));
+    exec("scan -fm org.apache.accumulo.core.util.format.DateStringFormatter -st", true, expected);
+    exec("deletetable t -f", true, "Table: [t] has been deleted");
+  }
+
+  @Test
+  public void commentTest() throws IOException {
+    Shell.log.debug("Starting comment test --------------------------");
+    exec("#", true, "Unknown command", false);
+    exec("# foo", true, "Unknown command", false);
+    exec("- foo", true, "Unknown command", true);
+  }
+
+  @Test
+  public void execFileTest() throws IOException {
+    Shell.log.debug("Starting exec file test --------------------------");
+    shell.config("--fake", "-u", "test", "-p", "secret", "-f", "src/test/resources/shelltest.txt");
+    assertEquals(0, shell.start());
+    assertGoodExit("Unknown command", false);
+  }
+
+  @Test
+  public void setIterTest() throws IOException {
+    Shell.log.debug("Starting setiter test --------------------------");
+    exec("createtable t", true);
+
+    String cmdJustClass = "setiter -class VersioningIterator -p 1";
+    exec(cmdJustClass, false, "java.lang.IllegalArgumentException", false);
+    exec(cmdJustClass, false, "fully qualified package name", true);
+
+    String cmdFullPackage = "setiter -class o.a.a.foo -p 1";
+    exec(cmdFullPackage, false, "java.lang.IllegalArgumentException", false);
+    exec(cmdFullPackage, false, "class not found", true);
+
+    String cmdNoOption = "setiter -class java.lang.String -p 1";
+    exec(cmdNoOption, false, "loaded successfully but does not implement SortedKeyValueIterator", true);
+
+    input.set("\n\n");
+    exec("setiter -scan -class org.apache.accumulo.core.iterators.ColumnFamilyCounter -p 30 -name foo", true);
+    
+    input.set("bar\nname value\n");
+    exec("setiter -scan -class org.apache.accumulo.core.iterators.ColumnFamilyCounter -p 31", true);
+    
+    //TODO can't verify this as config -t fails, functionality verified in ShellServerIT
+    
+    exec("deletetable t -f", true, "Table: [t] has been deleted");
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/test/java/org/apache/accumulo/shell/ShellUtilTest.java
----------------------------------------------------------------------
diff --git a/shell/src/test/java/org/apache/accumulo/shell/ShellUtilTest.java b/shell/src/test/java/org/apache/accumulo/shell/ShellUtilTest.java
new file mode 100644
index 0000000..4e99336
--- /dev/null
+++ b/shell/src/test/java/org/apache/accumulo/shell/ShellUtilTest.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.accumulo.shell;
+
+import static org.junit.Assert.*;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.util.List;
+
+import org.apache.accumulo.shell.ShellUtil;
+import org.apache.commons.codec.binary.Base64;
+import org.apache.commons.io.FileUtils;
+import org.apache.hadoop.io.Text;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+
+import com.google.common.collect.ImmutableList;
+
+public class ShellUtilTest {
+
+  @Rule
+  public TemporaryFolder folder = new TemporaryFolder(new File(System.getProperty("user.dir") + "/target"));
+
+  // String with 3 lines, with one empty line
+  private static final String FILEDATA = "line1\n\nline2";
+
+  @Test
+  public void testWithoutDecode() throws IOException {
+    File testFile = new File(folder.getRoot(), "testFileNoDecode.txt");
+    FileUtils.writeStringToFile(testFile, FILEDATA);
+    List<Text> output = ShellUtil.scanFile(testFile.getAbsolutePath(), false);
+    assertEquals(ImmutableList.of(new Text("line1"), new Text("line2")), output);
+  }
+
+  @Test
+  public void testWithDecode() throws IOException {
+    File testFile = new File(folder.getRoot(), "testFileWithDecode.txt");
+    FileUtils.writeStringToFile(testFile, FILEDATA);
+    List<Text> output = ShellUtil.scanFile(testFile.getAbsolutePath(), true);
+    assertEquals(
+        ImmutableList.of(new Text(Base64.decodeBase64("line1".getBytes(StandardCharsets.UTF_8))), new Text(Base64.decodeBase64("line2".getBytes(StandardCharsets.UTF_8)))),
+        output);
+  }
+
+  @Test(expected = FileNotFoundException.class)
+  public void testWithMissingFile() throws FileNotFoundException {
+    ShellUtil.scanFile("missingFile.txt", false);
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/test/java/org/apache/accumulo/shell/command/FormatterCommandTest.java
----------------------------------------------------------------------
diff --git a/shell/src/test/java/org/apache/accumulo/shell/command/FormatterCommandTest.java b/shell/src/test/java/org/apache/accumulo/shell/command/FormatterCommandTest.java
new file mode 100644
index 0000000..203f08f
--- /dev/null
+++ b/shell/src/test/java/org/apache/accumulo/shell/command/FormatterCommandTest.java
@@ -0,0 +1,184 @@
+/*
+ * 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.accumulo.shell.command;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Iterator;
+import java.util.Map.Entry;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.TableExistsException;
+import org.apache.accumulo.core.data.Key;
+import org.apache.accumulo.core.data.Value;
+import org.apache.accumulo.core.util.format.Formatter;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.mock.MockShell;
+import org.apache.log4j.Level;
+import org.apache.log4j.Logger;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * Uses the MockShell to test the shell output with Formatters
+ */
+public class FormatterCommandTest {
+  ByteArrayOutputStream out = null;
+  InputStream in = null;
+  
+  @Test
+  public void test() throws IOException, AccumuloException, AccumuloSecurityException, TableExistsException, ClassNotFoundException {
+    // Keep the Shell AUDIT log off the test output
+    Logger.getLogger(Shell.class).setLevel(Level.WARN);
+    
+    final String[] args = new String[] {"--fake", "-u", "root", "-p", ""};
+    
+    final String[] commands = createCommands();
+    
+    in = MockShell.makeCommands(commands);
+    out = new ByteArrayOutputStream();
+    
+    final MockShell shell = new MockShell(in, out);
+    shell.config(args);
+    
+    // Can't call createtable in the shell with MockAccumulo
+    shell.getConnector().tableOperations().create("test");
+    
+    try {
+      shell.start();
+    } catch (Exception e) {
+      Assert.fail("Exception while running commands: " + e.getMessage());
+    }
+    
+    shell.getReader().flush();
+    
+    final String[] output = new String(out.toByteArray()).split("\n\r");
+    
+    boolean formatterOn = false;
+    
+    final String[] expectedDefault = new String[] {"row cf:cq []    1234abcd", "row cf1:cq1 []    9876fedc", "row2 cf:cq []    13579bdf",
+        "row2 cf1:cq []    2468ace"};
+    
+    final String[] expectedFormatted = new String[] {"row cf:cq []    0x31 0x32 0x33 0x34 0x61 0x62 0x63 0x64",
+        "row cf1:cq1 []    0x39 0x38 0x37 0x36 0x66 0x65 0x64 0x63", "row2 cf:cq []    0x31 0x33 0x35 0x37 0x39 0x62 0x64 0x66",
+        "row2 cf1:cq []    0x32 0x34 0x36 0x38 0x61 0x63 0x65"};
+    
+    int outputIndex = 0;
+    while (outputIndex < output.length) {
+      final String line = output[outputIndex];
+      
+      if (line.startsWith("root@mock-instance")) {
+        if (line.contains("formatter")) {
+          formatterOn = true;
+        }
+        
+        outputIndex++;
+      } else if (line.startsWith("row")) {
+        int expectedIndex = 0;
+        String[] comparisonData;
+        
+        // Pick the type of data we expect (formatted or default)
+        if (formatterOn) {
+          comparisonData = expectedFormatted;
+        } else {
+          comparisonData = expectedDefault;
+        }
+        
+        // Ensure each output is what we expected
+        while (expectedIndex + outputIndex < output.length && expectedIndex < expectedFormatted.length) {
+          Assert.assertEquals(comparisonData[expectedIndex].trim(), output[expectedIndex + outputIndex].trim());
+          expectedIndex++;
+        }
+        
+        outputIndex += expectedIndex;
+      }
+    }
+  }
+  
+  private String[] createCommands() {
+    return new String[] {"table test", "insert row cf cq 1234abcd", "insert row cf1 cq1 9876fedc", "insert row2 cf cq 13579bdf", "insert row2 cf1 cq 2468ace",
+        "scan", "formatter -t test -f org.apache.accumulo.core.util.shell.command.FormatterCommandTest$HexFormatter", "scan"};
+  }
+  
+  /**
+   * <p>
+   * Simple <code>Formatter</code> that will convert each character in the Value from decimal to hexadecimal. Will automatically skip over characters in the
+   * value which do not fall within the [0-9,a-f] range.
+   * </p>
+   * 
+   * <p>
+   * Example: <code>'0'</code> will be displayed as <code>'0x30'</code>
+   * </p>
+   */
+  public static class HexFormatter implements Formatter {
+    private Iterator<Entry<Key,Value>> iter = null;
+    private boolean printTs = false;
+    
+    private final static String tab = "\t";
+    private final static String newline = "\n";
+    
+    public HexFormatter() {}
+    
+    @Override
+    public boolean hasNext() {
+      return this.iter.hasNext();
+    }
+    
+    @Override
+    public String next() {
+      final Entry<Key,Value> entry = iter.next();
+      
+      String key;
+      
+      // Observe the timestamps
+      if (printTs) {
+        key = entry.getKey().toString();
+      } else {
+        key = entry.getKey().toStringNoTime();
+      }
+      
+      final Value v = entry.getValue();
+      
+      // Approximate how much space we'll need
+      final StringBuilder sb = new StringBuilder(key.length() + v.getSize() * 5);
+      
+      sb.append(key).append(tab);
+      
+      for (byte b : v.get()) {
+        if ((b >= 48 && b <= 57) || (b >= 97 || b <= 102)) {
+          sb.append(String.format("0x%x ", Integer.valueOf(b)));
+        }
+      }
+      
+      sb.append(newline);
+      
+      return sb.toString();
+    }
+    
+    @Override
+    public void remove() {}
+    
+    @Override
+    public void initialize(final Iterable<Entry<Key,Value>> scanner, final boolean printTimestamps) {
+      this.iter = scanner.iterator();
+      this.printTs = printTimestamps;
+    }
+  }
+  
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/test/java/org/apache/accumulo/shell/format/DeleterFormatterTest.java
----------------------------------------------------------------------
diff --git a/shell/src/test/java/org/apache/accumulo/shell/format/DeleterFormatterTest.java b/shell/src/test/java/org/apache/accumulo/shell/format/DeleterFormatterTest.java
new file mode 100644
index 0000000..e5b7394
--- /dev/null
+++ b/shell/src/test/java/org/apache/accumulo/shell/format/DeleterFormatterTest.java
@@ -0,0 +1,177 @@
+/*
+ * 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.accumulo.shell.format;
+
+import static org.easymock.EasyMock.anyObject;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.createNiceMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.expectLastCall;
+import static org.easymock.EasyMock.replay;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+import java.util.Collections;
+import java.util.Map;
+import java.util.TreeMap;
+
+import jline.UnsupportedTerminal;
+import jline.console.ConsoleReader;
+
+import org.apache.accumulo.core.client.BatchWriter;
+import org.apache.accumulo.core.client.MutationsRejectedException;
+import org.apache.accumulo.core.data.Key;
+import org.apache.accumulo.core.data.Mutation;
+import org.apache.accumulo.core.data.Value;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.format.DeleterFormatter;
+import org.junit.Before;
+import org.junit.Test;
+
+public class DeleterFormatterTest {
+  DeleterFormatter formatter;
+  Map<Key,Value> data;
+  BatchWriter writer;
+  BatchWriter exceptionWriter;
+  Shell shellState;
+
+  ByteArrayOutputStream baos;
+  ConsoleReader reader;
+
+  SettableInputStream input;
+
+  class SettableInputStream extends InputStream {
+    ByteArrayInputStream bais;
+
+    @Override
+    public int read() throws IOException {
+      return bais.read();
+    }
+
+    public void set(String in) {
+      bais = new ByteArrayInputStream(in.getBytes(StandardCharsets.UTF_8));
+    }
+  };
+
+  @Before
+  public void setUp() throws IOException, MutationsRejectedException {
+    input = new SettableInputStream();
+    baos = new ByteArrayOutputStream();
+
+    MutationsRejectedException mre = createMock(MutationsRejectedException.class);
+
+    writer = createNiceMock(BatchWriter.class);
+    exceptionWriter = createNiceMock(BatchWriter.class);
+    exceptionWriter.close();
+    expectLastCall().andThrow(mre);
+    exceptionWriter.addMutation(anyObject(Mutation.class));
+    expectLastCall().andThrow(mre);
+
+    shellState = createNiceMock(Shell.class);
+
+    reader = new ConsoleReader(input, baos, new UnsupportedTerminal());
+    expect(shellState.getReader()).andReturn(reader).anyTimes();
+
+    replay(writer, exceptionWriter, shellState);
+
+    data = new TreeMap<Key,Value>();
+    data.put(new Key("r", "cf", "cq"), new Value("value".getBytes(StandardCharsets.UTF_8)));
+  }
+
+  @Test
+  public void testEmpty() {
+    formatter = new DeleterFormatter(writer, Collections.<Key,Value> emptyMap().entrySet(), true, shellState, true);
+    assertFalse(formatter.hasNext());
+  }
+
+  @Test
+  public void testSingle() throws IOException {
+    formatter = new DeleterFormatter(writer, data.entrySet(), true, shellState, true);
+
+    assertTrue(formatter.hasNext());
+    assertNull(formatter.next());
+
+    verify("[DELETED]", " r ", "cf", "cq", "value");
+  }
+
+  @Test
+  public void testNo() throws IOException {
+    input.set("no\n");
+    data.put(new Key("z"), new Value("v2".getBytes(StandardCharsets.UTF_8)));
+    formatter = new DeleterFormatter(writer, data.entrySet(), true, shellState, false);
+
+    assertTrue(formatter.hasNext());
+    assertNull(formatter.next());
+
+    verify("[SKIPPED]", " r ", "cf", "cq", "value");
+
+    assertTrue(formatter.hasNext());
+  }
+
+  @Test
+  public void testNoConfirmation() throws IOException {
+    input.set("");
+    data.put(new Key("z"), new Value("v2".getBytes(StandardCharsets.UTF_8)));
+    formatter = new DeleterFormatter(writer, data.entrySet(), true, shellState, false);
+
+    assertTrue(formatter.hasNext());
+    assertNull(formatter.next());
+
+    verify("[SKIPPED]", " r ", "cf", "cq", "value");
+
+    assertFalse(formatter.hasNext());
+  }
+
+  @Test
+  public void testYes() throws IOException {
+    input.set("y\nyes\n");
+    data.put(new Key("z"), new Value("v2".getBytes(StandardCharsets.UTF_8)));
+    formatter = new DeleterFormatter(writer, data.entrySet(), true, shellState, false);
+
+    assertTrue(formatter.hasNext());
+    assertNull(formatter.next());
+    verify("[DELETED]", " r ", "cf", "cq", "value");
+
+    assertTrue(formatter.hasNext());
+    assertNull(formatter.next());
+    verify("[DELETED]", " z ", "v2");
+  }
+
+  @Test
+  public void testMutationException() {
+    formatter = new DeleterFormatter(exceptionWriter, data.entrySet(), true, shellState, true);
+
+    assertTrue(formatter.hasNext());
+    assertNull(formatter.next());
+    assertFalse(formatter.hasNext());
+  }
+
+  private void verify(String... chunks) throws IOException {
+    reader.flush();
+
+    String output = baos.toString();
+    for (String chunk : chunks) {
+      assertTrue(output.contains(chunk));
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/test/resources/log4j.properties
----------------------------------------------------------------------
diff --git a/shell/src/test/resources/log4j.properties b/shell/src/test/resources/log4j.properties
new file mode 100644
index 0000000..9f968f8
--- /dev/null
+++ b/shell/src/test/resources/log4j.properties
@@ -0,0 +1,28 @@
+# 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.
+
+log4j.rootLogger=INFO, CA
+log4j.appender.CA=org.apache.log4j.ConsoleAppender
+log4j.appender.CA.layout=org.apache.log4j.PatternLayout
+log4j.appender.CA.layout.ConversionPattern=[%t] %-5p %c %x - %m%n
+
+log4j.logger.org.apache.accumulo.core.iterators.system.VisibilityFilter=FATAL
+log4j.logger.org.apache.accumulo.core.iterators.user.TransformingIteratorTest$IllegalVisCompactionKeyTransformingIterator=FATAL
+log4j.logger.org.apache.accumulo.core.iterators.user.TransformingIteratorTest$IllegalVisKeyTransformingIterator=FATAL
+log4j.logger.org.apache.commons.vfs2.impl.DefaultFileSystemManager=WARN
+log4j.logger.org.apache.hadoop.mapred=ERROR
+log4j.logger.org.apache.hadoop.mapreduce.lib.output.FileOutputCommitter=ERROR
+log4j.logger.org.apache.hadoop.util.ProcessTree=ERROR
+log4j.logger.org.apache.accumulo.core.util.format=FATAL

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/shell/src/test/resources/shelltest.txt
----------------------------------------------------------------------
diff --git a/shell/src/test/resources/shelltest.txt b/shell/src/test/resources/shelltest.txt
new file mode 100644
index 0000000..19b6f61
--- /dev/null
+++ b/shell/src/test/resources/shelltest.txt
@@ -0,0 +1,16 @@
+# 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.
+exit
+foo

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/start/src/main/java/org/apache/accumulo/start/Main.java
----------------------------------------------------------------------
diff --git a/start/src/main/java/org/apache/accumulo/start/Main.java b/start/src/main/java/org/apache/accumulo/start/Main.java
index 3c7da95..f34cd30 100644
--- a/start/src/main/java/org/apache/accumulo/start/Main.java
+++ b/start/src/main/java/org/apache/accumulo/start/Main.java
@@ -54,7 +54,7 @@ public class Main {
       } else if (args[0].equals("tserver")) {
         runTMP = cl.loadClass("org.apache.accumulo.tserver.TabletServer");
       } else if (args[0].equals("shell")) {
-        runTMP = cl.loadClass("org.apache.accumulo.core.util.shell.Shell");
+        runTMP = cl.loadClass("org.apache.accumulo.shell.Shell");
       } else if (args[0].equals("init")) {
         runTMP = cl.loadClass("org.apache.accumulo.server.init.Initialize");
       } else if (args[0].equals("admin")) {

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bcc9e7e4/test/src/test/java/org/apache/accumulo/test/ShellServerIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/accumulo/test/ShellServerIT.java b/test/src/test/java/org/apache/accumulo/test/ShellServerIT.java
index b3d44e3..bff8c3a 100644
--- a/test/src/test/java/org/apache/accumulo/test/ShellServerIT.java
+++ b/test/src/test/java/org/apache/accumulo/test/ShellServerIT.java
@@ -56,7 +56,7 @@ import org.apache.accumulo.core.metadata.MetadataTable;
 import org.apache.accumulo.core.metadata.RootTable;
 import org.apache.accumulo.core.security.Authorizations;
 import org.apache.accumulo.core.util.UtilWaitThread;
-import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.shell.Shell;
 import org.apache.accumulo.test.functional.FunctionalTestUtils;
 import org.apache.accumulo.test.functional.SimpleMacIT;
 import org.apache.accumulo.test.functional.SlowIterator;


[31/53] [abbrv] Revert "ACCUMULO-1897 Move shell into new package and module"

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/CreateTableCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/CreateTableCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/CreateTableCommand.java
new file mode 100644
index 0000000..bc5f1d1
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/CreateTableCommand.java
@@ -0,0 +1,203 @@
+/*
+ * 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.accumulo.core.util.shell.commands;
+
+import java.io.IOException;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.TableExistsException;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.core.client.admin.TimeType;
+import org.apache.accumulo.core.client.impl.Tables;
+import org.apache.accumulo.core.conf.Property;
+import org.apache.accumulo.core.iterators.IteratorUtil;
+import org.apache.accumulo.core.security.VisibilityConstraint;
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.core.util.shell.Shell.Command;
+import org.apache.accumulo.core.util.shell.ShellUtil;
+import org.apache.accumulo.core.util.shell.Token;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.OptionGroup;
+import org.apache.commons.cli.Options;
+import org.apache.hadoop.io.Text;
+
+public class CreateTableCommand extends Command {
+  private Option createTableOptCopySplits;
+  private Option createTableOptCopyConfig;
+  private Option createTableOptSplit;
+  private Option createTableOptTimeLogical;
+  private Option createTableOptTimeMillis;
+  private Option createTableNoDefaultIters;
+  private Option createTableOptEVC;
+  private Option base64Opt;
+  private Option createTableOptFormatter;
+
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException,
+      TableExistsException, TableNotFoundException, IOException, ClassNotFoundException {
+
+    final String testTableName = cl.getArgs()[0];
+
+    if (!testTableName.matches(Tables.VALID_NAME_REGEX)) {
+      shellState.getReader().println("Only letters, numbers and underscores are allowed for use in table names.");
+      throw new IllegalArgumentException();
+    }
+
+    final String tableName = cl.getArgs()[0];
+    if (shellState.getConnector().tableOperations().exists(tableName)) {
+      throw new TableExistsException(null, tableName, null);
+    }
+    final SortedSet<Text> partitions = new TreeSet<Text>();
+    final boolean decode = cl.hasOption(base64Opt.getOpt());
+
+    if (cl.hasOption(createTableOptSplit.getOpt())) {
+      partitions.addAll(ShellUtil.scanFile(cl.getOptionValue(createTableOptSplit.getOpt()), decode));
+    } else if (cl.hasOption(createTableOptCopySplits.getOpt())) {
+      final String oldTable = cl.getOptionValue(createTableOptCopySplits.getOpt());
+      if (!shellState.getConnector().tableOperations().exists(oldTable)) {
+        throw new TableNotFoundException(null, oldTable, null);
+      }
+      partitions.addAll(shellState.getConnector().tableOperations().listSplits(oldTable));
+    }
+
+    if (cl.hasOption(createTableOptCopyConfig.getOpt())) {
+      final String oldTable = cl.getOptionValue(createTableOptCopyConfig.getOpt());
+      if (!shellState.getConnector().tableOperations().exists(oldTable)) {
+        throw new TableNotFoundException(null, oldTable, null);
+      }
+    }
+
+    TimeType timeType = TimeType.MILLIS;
+    if (cl.hasOption(createTableOptTimeLogical.getOpt())) {
+      timeType = TimeType.LOGICAL;
+    }
+
+    // create table
+    shellState.getConnector().tableOperations().create(tableName, true, timeType);
+    if (partitions.size() > 0) {
+      shellState.getConnector().tableOperations().addSplits(tableName, partitions);
+    }
+
+    shellState.setTableName(tableName); // switch shell to new table context
+
+    if (cl.hasOption(createTableNoDefaultIters.getOpt())) {
+      for (String key : IteratorUtil.generateInitialTableProperties(true).keySet()) {
+        shellState.getConnector().tableOperations().removeProperty(tableName, key);
+      }
+    }
+
+    // Copy options if flag was set
+    if (cl.hasOption(createTableOptCopyConfig.getOpt())) {
+      if (shellState.getConnector().tableOperations().exists(tableName)) {
+        final Iterable<Entry<String,String>> configuration = shellState.getConnector().tableOperations()
+            .getProperties(cl.getOptionValue(createTableOptCopyConfig.getOpt()));
+        for (Entry<String,String> entry : configuration) {
+          if (Property.isValidTablePropertyKey(entry.getKey())) {
+            shellState.getConnector().tableOperations().setProperty(tableName, entry.getKey(), entry.getValue());
+          }
+        }
+      }
+    }
+
+    if (cl.hasOption(createTableOptEVC.getOpt())) {
+      try {
+        shellState.getConnector().tableOperations().addConstraint(tableName, VisibilityConstraint.class.getName());
+      } catch (AccumuloException e) {
+        Shell.log.warn(e.getMessage() + " while setting visibility constraint, but table was created");
+      }
+    }
+
+    // Load custom formatter if set
+    if (cl.hasOption(createTableOptFormatter.getOpt())) {
+      final String formatterClass = cl.getOptionValue(createTableOptFormatter.getOpt());
+
+      shellState.getConnector().tableOperations().setProperty(tableName, Property.TABLE_FORMATTER_CLASS.toString(), formatterClass);
+    }
+
+    return 0;
+  }
+
+  @Override
+  public String description() {
+    return "creates a new table, with optional aggregators and optionally pre-split";
+  }
+
+  @Override
+  public String usage() {
+    return getName() + " <tableName>";
+  }
+
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+
+    createTableOptCopyConfig = new Option("cc", "copy-config", true, "table to copy configuration from");
+    createTableOptCopySplits = new Option("cs", "copy-splits", true, "table to copy current splits from");
+    createTableOptSplit = new Option("sf", "splits-file", true, "file with a newline-separated list of rows to split the table with");
+    createTableOptTimeLogical = new Option("tl", "time-logical", false, "use logical time");
+    createTableOptTimeMillis = new Option("tm", "time-millis", false, "use time in milliseconds");
+    createTableNoDefaultIters = new Option("ndi", "no-default-iterators", false, "prevent creation of the normal default iterator set");
+    createTableOptEVC = new Option("evc", "enable-visibility-constraint", false,
+        "prevent users from writing data they cannot read.  When enabling this, consider disabling bulk import and alter table.");
+    createTableOptFormatter = new Option("f", "formatter", true, "default formatter to set");
+
+    createTableOptCopyConfig.setArgName("table");
+    createTableOptCopySplits.setArgName("table");
+    createTableOptSplit.setArgName("filename");
+    createTableOptFormatter.setArgName("className");
+
+    // Splits and CopySplits are put in an optionsgroup to make them
+    // mutually exclusive
+    final OptionGroup splitOrCopySplit = new OptionGroup();
+    splitOrCopySplit.addOption(createTableOptSplit);
+    splitOrCopySplit.addOption(createTableOptCopySplits);
+
+    final OptionGroup timeGroup = new OptionGroup();
+    timeGroup.addOption(createTableOptTimeLogical);
+    timeGroup.addOption(createTableOptTimeMillis);
+
+    base64Opt = new Option("b64", "base64encoded", false, "decode encoded split points");
+    o.addOption(base64Opt);
+
+    o.addOptionGroup(splitOrCopySplit);
+    o.addOptionGroup(timeGroup);
+    o.addOption(createTableOptSplit);
+    o.addOption(createTableOptCopyConfig);
+    o.addOption(createTableNoDefaultIters);
+    o.addOption(createTableOptEVC);
+    o.addOption(createTableOptFormatter);
+
+    return o;
+  }
+
+  @Override
+  public int numArgs() {
+    return 1;
+  }
+
+  @Override
+  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> special) {
+    registerCompletionForNamespaces(root, special);
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/CreateUserCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/CreateUserCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/CreateUserCommand.java
new file mode 100644
index 0000000..aa3d7b9
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/CreateUserCommand.java
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.accumulo.core.util.shell.commands;
+
+import java.io.IOException;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.TableExistsException;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.core.client.security.tokens.PasswordToken;
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.core.util.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Options;
+
+public class CreateUserCommand extends Command {
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, TableNotFoundException,
+      AccumuloSecurityException, TableExistsException, IOException {
+    final String user = cl.getArgs()[0];
+    
+    final String password = shellState.readMaskedLine("Enter new password for '" + user + "': ", '*');
+    if (password == null) {
+      shellState.getReader().println();
+      return 0;
+    } // user canceled
+    String passwordConfirm = shellState.readMaskedLine("Please confirm new password for '" + user + "': ", '*');
+    if (passwordConfirm == null) {
+      shellState.getReader().println();
+      return 0;
+    } // user canceled
+    
+    if (!password.equals(passwordConfirm)) {
+      throw new IllegalArgumentException("Passwords do not match");
+    }
+    shellState.getConnector().securityOperations().createLocalUser(user, new PasswordToken(password));
+    Shell.log.debug("Created user " + user);
+    return 0;
+  }
+  
+  @Override
+  public String usage() {
+    return getName() + " <username>";
+  }
+  
+  @Override
+  public String description() {
+    return "creates a new user";
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+    return o;
+  }
+  
+  @Override
+  public int numArgs() {
+    return 1;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DUCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DUCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DUCommand.java
new file mode 100644
index 0000000..660ec6c
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DUCommand.java
@@ -0,0 +1,124 @@
+/*
+ * 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.accumulo.core.util.shell.commands;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import org.apache.accumulo.core.client.Instance;
+import org.apache.accumulo.core.client.NamespaceNotFoundException;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.core.client.admin.DiskUsage;
+import org.apache.accumulo.core.client.impl.Namespaces;
+import org.apache.accumulo.core.util.NumUtil;
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.core.util.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+
+public class DUCommand extends Command {
+
+  private Option optTablePattern, optHumanReadble, optNamespace;
+
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws IOException, TableNotFoundException,
+      NamespaceNotFoundException {
+
+    final SortedSet<String> tables = new TreeSet<String>(Arrays.asList(cl.getArgs()));
+
+    if (cl.hasOption(Shell.tableOption)) {
+      String tableName = cl.getOptionValue(Shell.tableOption);
+      if (!shellState.getConnector().tableOperations().exists(tableName)) {
+        throw new TableNotFoundException(tableName, tableName, "specified table that doesn't exist");
+      }
+      tables.add(tableName);
+    }
+
+    if (cl.hasOption(optNamespace.getOpt())) {
+      Instance instance = shellState.getInstance();
+      String namespaceId = Namespaces.getNamespaceId(instance, cl.getOptionValue(optNamespace.getOpt()));
+      tables.addAll(Namespaces.getTableNames(instance, namespaceId));
+    }
+
+    boolean prettyPrint = cl.hasOption(optHumanReadble.getOpt()) ? true : false;
+
+    // Add any patterns
+    if (cl.hasOption(optTablePattern.getOpt())) {
+      for (String table : shellState.getConnector().tableOperations().list()) {
+        if (table.matches(cl.getOptionValue(optTablePattern.getOpt()))) {
+          tables.add(table);
+        }
+      }
+    }
+
+    // If we didn't get any tables, and we have a table selected, add the current table
+    if (tables.isEmpty() && !shellState.getTableName().isEmpty()) {
+      tables.add(shellState.getTableName());
+    }
+
+    try {
+      String valueFormat = prettyPrint ? "%9s" : "%,24d";
+      for (DiskUsage usage : shellState.getConnector().tableOperations().getDiskUsage(tables)) {
+        Object value = prettyPrint ? NumUtil.bigNumberForSize(usage.getUsage()) : usage.getUsage();
+        shellState.getReader().println(String.format(valueFormat + " %s", value, usage.getTables()));
+      }
+    } catch (Exception ex) {
+      throw new RuntimeException(ex);
+    }
+    return 0;
+  }
+
+  @Override
+  public String description() {
+    return "prints how much space, in bytes, is used by files referenced by a table.  When multiple tables are specified it prints how much space, in bytes, is used by files shared between tables, if any.";
+  }
+
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+
+    optTablePattern = new Option("p", "pattern", true, "regex pattern of table names");
+    optTablePattern.setArgName("pattern");
+
+    optHumanReadble = new Option("h", "human-readable", false, "format large sizes to human readable units");
+    optHumanReadble.setArgName("human readable output");
+
+    optNamespace = new Option(Shell.namespaceOption, "namespace", true, "name of a namespace");
+    optNamespace.setArgName("namespace");
+
+    o.addOption(OptUtil.tableOpt("table to examine"));
+
+    o.addOption(optTablePattern);
+    o.addOption(optHumanReadble);
+    o.addOption(optNamespace);
+
+    return o;
+  }
+
+  @Override
+  public String usage() {
+    return getName() + " <table>{ <table>}";
+  }
+
+  @Override
+  public int numArgs() {
+    return Shell.NO_FIXED_ARG_LENGTH_CHECK;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DebugCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DebugCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DebugCommand.java
new file mode 100644
index 0000000..206b5901
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DebugCommand.java
@@ -0,0 +1,71 @@
+/*
+ * 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.accumulo.core.util.shell.commands;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.accumulo.core.util.BadArgumentException;
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.core.util.shell.Shell.Command;
+import org.apache.accumulo.core.util.shell.Token;
+import org.apache.commons.cli.CommandLine;
+
+public class DebugCommand extends Command {
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws IOException {
+    if (cl.getArgs().length == 1) {
+      if (cl.getArgs()[0].equalsIgnoreCase("on")) {
+        Shell.setDebugging(true);
+      } else if (cl.getArgs()[0].equalsIgnoreCase("off")) {
+        Shell.setDebugging(false);
+      } else {
+        throw new BadArgumentException("Argument must be 'on' or 'off'", fullCommand, fullCommand.indexOf(cl.getArgs()[0]));
+      }
+    } else if (cl.getArgs().length == 0) {
+      shellState.getReader().println(Shell.isDebuggingEnabled() ? "on" : "off");
+    } else {
+      shellState.printException(new IllegalArgumentException("Expected 0 or 1 argument. There were " + cl.getArgs().length + "."));
+      printHelp(shellState);
+      return 1;
+    }
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "turns debug logging on or off";
+  }
+  
+  @Override
+  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> special) {
+    final Token debug_command = new Token(getName());
+    debug_command.addSubcommand(Arrays.asList(new String[] {"on", "off"}));
+    root.addSubcommand(debug_command);
+  }
+  
+  @Override
+  public String usage() {
+    return getName() + " [ on | off ]";
+  }
+  
+  @Override
+  public int numArgs() {
+    return Shell.NO_FIXED_ARG_LENGTH_CHECK;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteCommand.java
new file mode 100644
index 0000000..b409ccc
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteCommand.java
@@ -0,0 +1,112 @@
+/*
+ * 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.accumulo.core.util.shell.commands;
+
+import java.io.IOException;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.BatchWriter;
+import org.apache.accumulo.core.client.BatchWriterConfig;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.core.conf.AccumuloConfiguration;
+import org.apache.accumulo.core.data.Mutation;
+import org.apache.accumulo.core.security.ColumnVisibility;
+import org.apache.accumulo.core.tabletserver.thrift.ConstraintViolationException;
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.core.util.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+import org.apache.hadoop.io.Text;
+
+public class DeleteCommand extends Command {
+  private Option deleteOptAuths, timestampOpt;
+  private Option timeoutOption;
+  
+  protected long getTimeout(final CommandLine cl) {
+    if (cl.hasOption(timeoutOption.getLongOpt())) {
+      return AccumuloConfiguration.getTimeInMillis(cl.getOptionValue(timeoutOption.getLongOpt()));
+    }
+    
+    return Long.MAX_VALUE;
+  }
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException,
+      TableNotFoundException, IOException, ConstraintViolationException {
+    shellState.checkTableState();
+    
+    final Mutation m = new Mutation(new Text(cl.getArgs()[0].getBytes(Shell.CHARSET)));
+    final Text colf = new Text(cl.getArgs()[1].getBytes(Shell.CHARSET));
+    final Text colq = new Text(cl.getArgs()[2].getBytes(Shell.CHARSET));
+    
+    if (cl.hasOption(deleteOptAuths.getOpt())) {
+      final ColumnVisibility le = new ColumnVisibility(cl.getOptionValue(deleteOptAuths.getOpt()));
+      if (cl.hasOption(timestampOpt.getOpt())) {
+        m.putDelete(colf, colq, le, Long.parseLong(cl.getOptionValue(timestampOpt.getOpt())));
+      } else {
+        m.putDelete(colf, colq, le);
+      }
+    } else if (cl.hasOption(timestampOpt.getOpt())) {
+      m.putDelete(colf, colq, Long.parseLong(cl.getOptionValue(timestampOpt.getOpt())));
+    } else {
+      m.putDelete(colf, colq);
+    }
+    final BatchWriter bw = shellState.getConnector().createBatchWriter(shellState.getTableName(),
+        new BatchWriterConfig().setMaxMemory(Math.max(m.estimatedMemoryUsed(), 1024)).setMaxWriteThreads(1).setTimeout(getTimeout(cl), TimeUnit.MILLISECONDS));
+    bw.addMutation(m);
+    bw.close();
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "deletes a record from a table";
+  }
+  
+  @Override
+  public String usage() {
+    return getName() + " <row> <colfamily> <colqualifier>";
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+    
+    deleteOptAuths = new Option("l", "visibility-label", true, "formatted visibility");
+    deleteOptAuths.setArgName("expression");
+    o.addOption(deleteOptAuths);
+    
+    timestampOpt = new Option("ts", "timestamp", true, "timestamp to use for deletion");
+    timestampOpt.setArgName("timestamp");
+    o.addOption(timestampOpt);
+    
+    timeoutOption = new Option(null, "timeout", true,
+        "time before insert should fail if no data is written. If no unit is given assumes seconds.  Units d,h,m,s,and ms are supported.  e.g. 30s or 100ms");
+    timeoutOption.setArgName("timeout");
+    o.addOption(timeoutOption);
+    
+    return o;
+  }
+  
+  @Override
+  public int numArgs() {
+    return 3;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteIterCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteIterCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteIterCommand.java
new file mode 100644
index 0000000..c100325
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteIterCommand.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.accumulo.core.util.shell.commands;
+
+import java.util.EnumSet;
+
+import org.apache.accumulo.core.iterators.IteratorUtil.IteratorScope;
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.core.util.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.OptionGroup;
+import org.apache.commons.cli.Options;
+
+public class DeleteIterCommand extends Command {
+  private Option allScopeOpt, mincScopeOpt, majcScopeOpt, scanScopeOpt, nameOpt;
+
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+
+    boolean tables = cl.hasOption(OptUtil.tableOpt().getOpt()) || !shellState.getTableName().isEmpty();
+    boolean namespaces = cl.hasOption(OptUtil.namespaceOpt().getOpt());
+
+    final String name = cl.getOptionValue(nameOpt.getOpt());
+
+    if (namespaces) {
+      if (!shellState.getConnector().namespaceOperations().listIterators(OptUtil.getNamespaceOpt(cl, shellState)).containsKey(name)) {
+        Shell.log.warn("no iterators found that match your criteria");
+        return 0;
+      }
+    } else if (tables) {
+      if (!shellState.getConnector().tableOperations().listIterators(OptUtil.getTableOpt(cl, shellState)).containsKey(name)) {
+        Shell.log.warn("no iterators found that match your criteria");
+        return 0;
+      }
+    } else {
+      throw new IllegalArgumentException("No table or namespace specified");
+    }
+
+    final EnumSet<IteratorScope> scopes = EnumSet.noneOf(IteratorScope.class);
+    if (cl.hasOption(allScopeOpt.getOpt()) || cl.hasOption(mincScopeOpt.getOpt())) {
+      scopes.add(IteratorScope.minc);
+    }
+    if (cl.hasOption(allScopeOpt.getOpt()) || cl.hasOption(majcScopeOpt.getOpt())) {
+      scopes.add(IteratorScope.majc);
+    }
+    if (cl.hasOption(allScopeOpt.getOpt()) || cl.hasOption(scanScopeOpt.getOpt())) {
+      scopes.add(IteratorScope.scan);
+    }
+    if (scopes.isEmpty()) {
+      throw new IllegalArgumentException("You must select at least one scope to configure");
+    }
+
+    if (namespaces) {
+      shellState.getConnector().namespaceOperations().removeIterator(OptUtil.getNamespaceOpt(cl, shellState), name, scopes);
+    } else if (tables) {
+      shellState.getConnector().tableOperations().removeIterator(OptUtil.getTableOpt(cl, shellState), name, scopes);
+    } else {
+      throw new IllegalArgumentException("No table or namespace specified");
+    }
+    return 0;
+  }
+
+  @Override
+  public String description() {
+    return "deletes a table-specific or namespace-specific iterator";
+  }
+
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+
+    nameOpt = new Option("n", "name", true, "iterator to delete");
+    nameOpt.setArgName("itername");
+    nameOpt.setRequired(true);
+
+    allScopeOpt = new Option("all", "all-scopes", false, "remove from all scopes");
+    mincScopeOpt = new Option(IteratorScope.minc.name(), "minor-compaction", false, "remove from minor compaction scope");
+    majcScopeOpt = new Option(IteratorScope.majc.name(), "major-compaction", false, "remove from major compaction scope");
+    scanScopeOpt = new Option(IteratorScope.scan.name(), "scan-time", false, "remove from scan scope");
+
+    OptionGroup grp = new OptionGroup();
+    grp.addOption(OptUtil.tableOpt("table to delete the iterator from"));
+    grp.addOption(OptUtil.namespaceOpt("namespace to delete the iterator from"));
+    o.addOptionGroup(grp);
+    o.addOption(nameOpt);
+
+    o.addOption(allScopeOpt);
+    o.addOption(mincScopeOpt);
+    o.addOption(majcScopeOpt);
+    o.addOption(scanScopeOpt);
+
+    return o;
+  }
+
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteManyCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteManyCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteManyCommand.java
new file mode 100644
index 0000000..7518bf9
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteManyCommand.java
@@ -0,0 +1,82 @@
+/*
+ * 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.accumulo.core.util.shell.commands;
+
+import java.util.concurrent.TimeUnit;
+
+import org.apache.accumulo.core.client.BatchWriter;
+import org.apache.accumulo.core.client.BatchWriterConfig;
+import org.apache.accumulo.core.client.IteratorSetting;
+import org.apache.accumulo.core.client.Scanner;
+import org.apache.accumulo.core.iterators.SortedKeyIterator;
+import org.apache.accumulo.core.security.Authorizations;
+import org.apache.accumulo.core.util.format.DeleterFormatter;
+import org.apache.accumulo.core.util.interpret.ScanInterpreter;
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+
+public class DeleteManyCommand extends ScanCommand {
+  private Option forceOpt;
+  
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    final String tableName = OptUtil.getTableOpt(cl, shellState);
+    
+    final ScanInterpreter interpeter = getInterpreter(cl, tableName, shellState);
+
+    // handle first argument, if present, the authorizations list to
+    // scan with
+    final Authorizations auths = getAuths(cl, shellState);
+    final Scanner scanner = shellState.getConnector().createScanner(tableName, auths);
+    
+    scanner.addScanIterator(new IteratorSetting(Integer.MAX_VALUE, "NOVALUE", SortedKeyIterator.class));
+    
+    // handle session-specific scan iterators
+    addScanIterators(shellState, cl, scanner, tableName);
+    
+    // handle remaining optional arguments
+    scanner.setRange(getRange(cl, interpeter));
+    
+    scanner.setTimeout(getTimeout(cl), TimeUnit.MILLISECONDS);
+
+    // handle columns
+    fetchColumns(cl, scanner, interpeter);
+    
+    // output / delete the records
+    final BatchWriter writer = shellState.getConnector()
+        .createBatchWriter(tableName, new BatchWriterConfig().setTimeout(getTimeout(cl), TimeUnit.MILLISECONDS));
+    shellState.printLines(new DeleterFormatter(writer, scanner, cl.hasOption(timestampOpt.getOpt()), shellState, cl.hasOption(forceOpt.getOpt())), false);
+    
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "scans a table and deletes the resulting records";
+  }
+  
+  @Override
+  public Options getOptions() {
+    forceOpt = new Option("f", "force", false, "force deletion without prompting");
+    final Options opts = super.getOptions();
+    opts.addOption(forceOpt);
+    opts.addOption(OptUtil.tableOpt("table to delete entries from"));
+    return opts;
+  }
+  
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteNamespaceCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteNamespaceCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteNamespaceCommand.java
new file mode 100644
index 0000000..01d7fc0
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteNamespaceCommand.java
@@ -0,0 +1,100 @@
+/*
+ * 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.accumulo.core.util.shell.commands;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.accumulo.core.client.NamespaceNotFoundException;
+import org.apache.accumulo.core.client.impl.Namespaces;
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.core.util.shell.Shell.Command;
+import org.apache.accumulo.core.util.shell.Token;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+
+public class DeleteNamespaceCommand extends Command {
+  private Option forceOpt;
+
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    boolean force = false;
+    boolean operate = true;
+    if (cl.hasOption(forceOpt.getOpt())) {
+      force = true;
+    }
+    String namespace = cl.getArgs()[0];
+
+    if (!force) {
+      shellState.getReader().flush();
+      String line = shellState.getReader().readLine(getName() + " { " + namespace + " } (yes|no)? ");
+      operate = line != null && (line.equalsIgnoreCase("y") || line.equalsIgnoreCase("yes"));
+    }
+    if (operate) {
+      doTableOp(shellState, namespace, force);
+    }
+    return 0;
+  }
+
+  @Override
+  public String description() {
+    return "deletes a namespace";
+  }
+
+  protected void doTableOp(final Shell shellState, final String namespace, boolean force) throws Exception {
+    boolean resetContext = false;
+    String currentTable = shellState.getTableName();
+    if (!Namespaces.getNameToIdMap(shellState.getInstance()).containsKey(namespace)) {
+      throw new NamespaceNotFoundException(null, namespace, null);
+    }
+
+    String namespaceId = Namespaces.getNamespaceId(shellState.getInstance(), namespace);
+    List<String> tables = Namespaces.getTableNames(shellState.getInstance(), namespaceId);
+    resetContext = tables.contains(currentTable);
+
+    if (force)
+      for (String table : shellState.getConnector().tableOperations().list())
+        if (table.startsWith(namespace + "."))
+          shellState.getConnector().tableOperations().delete(table);
+
+    shellState.getConnector().namespaceOperations().delete(namespace);
+    if (resetContext) {
+      shellState.setTableName("");
+    }
+  }
+
+  @Override
+  public Options getOptions() {
+    forceOpt = new Option("f", "force", false, "force deletion without prompting");
+    final Options opts = super.getOptions();
+
+    opts.addOption(forceOpt);
+    return opts;
+  }
+
+  @Override
+  public int numArgs() {
+    return 1;
+  }
+
+  @Override
+  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> special) {
+    registerCompletionForNamespaces(root, special);
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteRowsCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteRowsCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteRowsCommand.java
new file mode 100644
index 0000000..1414b4d
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteRowsCommand.java
@@ -0,0 +1,65 @@
+/*
+ * 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.accumulo.core.util.shell.commands;
+
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.core.util.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+import org.apache.hadoop.io.Text;
+
+public class DeleteRowsCommand extends Command {
+  private Option forceOpt;
+  private Option startRowOptExclusive;
+ 
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    final String tableName = OptUtil.getTableOpt(cl, shellState);
+    final Text startRow = OptUtil.getStartRow(cl);
+    final Text endRow = OptUtil.getEndRow(cl);
+    if (!cl.hasOption(forceOpt.getOpt()) && (startRow == null || endRow == null)) {
+      shellState.getReader().println("Not deleting unbounded range. Specify both ends, or use --force");
+      return 1;
+    }
+    shellState.getConnector().tableOperations().deleteRows(tableName, startRow, endRow);
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "deletes a range of rows in a table.  Note that rows matching the start row ARE NOT deleted, but rows matching the end row ARE deleted.";
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+    forceOpt = new Option("f", "force", false, "delete data even if start or end are not specified");
+    startRowOptExclusive = new Option(OptUtil.START_ROW_OPT, "begin-row", true, "begin row (exclusive)");
+    startRowOptExclusive.setArgName("begin-row");
+    o.addOption(startRowOptExclusive);
+    o.addOption(OptUtil.endRowOpt());
+    o.addOption(OptUtil.tableOpt("table to delete a row range from"));
+    o.addOption(forceOpt);
+    return o;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteScanIterCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteScanIterCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteScanIterCommand.java
new file mode 100644
index 0000000..9b8699b
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteScanIterCommand.java
@@ -0,0 +1,102 @@
+/*
+ * 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.accumulo.core.util.shell.commands;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.accumulo.core.client.IteratorSetting;
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.core.util.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.OptionGroup;
+import org.apache.commons.cli.Options;
+
+public class DeleteScanIterCommand extends Command {
+  private Option nameOpt, allOpt;
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    final String tableName = OptUtil.getTableOpt(cl, shellState);
+    
+    if (cl.hasOption(allOpt.getOpt())) {
+      final List<IteratorSetting> tableScanIterators = shellState.scanIteratorOptions.remove(tableName);
+      if (tableScanIterators == null) {
+        Shell.log.info("No scan iterators set on table " + tableName);
+      } else {
+        Shell.log.info("Removed the following scan iterators from table " + tableName + ":" + tableScanIterators);
+      }
+    } else if (cl.hasOption(nameOpt.getOpt())) {
+      final String name = cl.getOptionValue(nameOpt.getOpt());
+      final List<IteratorSetting> tableScanIterators = shellState.scanIteratorOptions.get(tableName);
+      if (tableScanIterators != null) {
+        boolean found = false;
+        for (Iterator<IteratorSetting> iter = tableScanIterators.iterator(); iter.hasNext();) {
+          if (iter.next().getName().equals(name)) {
+            iter.remove();
+            found = true;
+            break;
+          }
+        }
+        if (!found) {
+          Shell.log.info("No iterator named " + name + " found for table " + tableName);
+        } else {
+          Shell.log.info("Removed scan iterator " + name + " from table " + tableName + " (" + shellState.scanIteratorOptions.get(tableName).size() + " left)");
+          if (shellState.scanIteratorOptions.get(tableName).size() == 0) {
+            shellState.scanIteratorOptions.remove(tableName);
+          }
+        }
+      } else {
+        Shell.log.info("No iterator named " + name + " found for table " + tableName);
+      }
+    }
+    
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "deletes a table-specific scan iterator so it is no longer used during this shell session";
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+    
+    OptionGroup nameGroup = new OptionGroup();
+    
+    nameOpt = new Option("n", "name", true, "iterator to delete");
+    nameOpt.setArgName("itername");
+    
+    allOpt = new Option("a", "all", false, "delete all scan iterators");
+    allOpt.setArgName("all");
+    
+    nameGroup.addOption(nameOpt);
+    nameGroup.addOption(allOpt);
+    nameGroup.setRequired(true);
+    o.addOptionGroup(nameGroup);
+    o.addOption(OptUtil.tableOpt("table to delete scan iterators from"));
+    
+    return o;
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteShellIterCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteShellIterCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteShellIterCommand.java
new file mode 100644
index 0000000..89060c1
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteShellIterCommand.java
@@ -0,0 +1,100 @@
+/*
+ * 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.accumulo.core.util.shell.commands;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.accumulo.core.client.IteratorSetting;
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.core.util.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.OptionGroup;
+import org.apache.commons.cli.Options;
+
+public class DeleteShellIterCommand extends Command {
+  private Option nameOpt, allOpt, profileOpt;
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+
+    String profile = cl.getOptionValue(profileOpt.getOpt());
+    if (shellState.iteratorProfiles.containsKey(profile)) {
+      if (cl.hasOption(allOpt.getOpt())) {
+        shellState.iteratorProfiles.remove(profile);
+        Shell.log.info("Removed profile " + profile);
+      } else {
+        List<IteratorSetting> iterSettings = shellState.iteratorProfiles.get(profile);
+        String name = cl.getOptionValue(nameOpt.getOpt());
+        boolean found = false;
+        for (Iterator<IteratorSetting> iter = iterSettings.iterator(); iter.hasNext();) {
+          if (iter.next().getName().equals(name)) {
+            iter.remove();
+            found = true;
+            break;
+          }
+        }
+        if (!found) {
+          Shell.log.info("No iterator named " + name + " found");
+        } else {
+          Shell.log.info("Removed iterator " + name + " from profile " + profile + " (" + iterSettings.size() + " left)");
+        }
+      }
+      
+    } else {
+      Shell.log.info("No profile named " + profile);
+    }
+    
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "deletes iterators profiles configured in this shell session";
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+    
+    OptionGroup nameGroup = new OptionGroup();
+    
+    nameOpt = new Option("n", "name", true, "iterator to delete");
+    nameOpt.setArgName("itername");
+    
+    allOpt = new Option("a", "all", false, "delete all scan iterators");
+    allOpt.setArgName("all");
+    
+    nameGroup.addOption(nameOpt);
+    nameGroup.addOption(allOpt);
+    nameGroup.setRequired(true);
+    o.addOptionGroup(nameGroup);
+    
+    profileOpt = new Option("pn", "profile", true, "iterator profile name");
+    profileOpt.setRequired(true);
+    profileOpt.setArgName("profile");
+    o.addOption(profileOpt);
+
+    return o;
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteTableCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteTableCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteTableCommand.java
new file mode 100644
index 0000000..a5aa32a
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteTableCommand.java
@@ -0,0 +1,60 @@
+/*
+ * 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.accumulo.core.util.shell.commands;
+
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+
+public class DeleteTableCommand extends TableOperation {
+  private Option forceOpt;
+
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    if (cl.hasOption(forceOpt.getOpt())) {
+      super.force();
+    } else {
+      super.noForce();
+    }
+    return super.execute(fullCommand, cl, shellState);
+  }
+
+  @Override
+  public String description() {
+    return "deletes a table";
+  }
+
+  @Override
+  protected void doTableOp(final Shell shellState, final String tableName) throws Exception {
+    shellState.getConnector().tableOperations().delete(tableName);
+    shellState.getReader().println("Table: [" + tableName + "] has been deleted.");
+
+    if (shellState.getTableName().equals(tableName)) {
+      shellState.setTableName("");
+    }
+  }
+
+  @Override
+  public Options getOptions() {
+    forceOpt = new Option("f", "force", false, "force deletion without prompting");
+    final Options opts = super.getOptions();
+
+    opts.addOption(forceOpt);
+    return opts;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteUserCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteUserCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteUserCommand.java
new file mode 100644
index 0000000..4bc563e
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteUserCommand.java
@@ -0,0 +1,19 @@
+/*
+ * 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.accumulo.core.util.shell.commands;
+
+public class DeleteUserCommand extends DropUserCommand {}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DropTableCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DropTableCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DropTableCommand.java
new file mode 100644
index 0000000..3120d6b
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DropTableCommand.java
@@ -0,0 +1,19 @@
+/*
+ * 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.accumulo.core.util.shell.commands;
+
+public class DropTableCommand extends DeleteTableCommand {}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DropUserCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DropUserCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DropUserCommand.java
new file mode 100644
index 0000000..5aa0fb6
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DropUserCommand.java
@@ -0,0 +1,61 @@
+/*
+ * 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.accumulo.core.util.shell.commands;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.util.BadArgumentException;
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.core.util.shell.Shell.Command;
+import org.apache.accumulo.core.util.shell.Token;
+import org.apache.commons.cli.CommandLine;
+
+public class DropUserCommand extends Command {
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException {
+    final String user = cl.getArgs()[0];
+    if (shellState.getConnector().whoami().equals(user)) {
+      throw new BadArgumentException("You cannot delete yourself", fullCommand, fullCommand.indexOf(user));
+    }
+    shellState.getConnector().securityOperations().dropLocalUser(user);
+    Shell.log.debug("Deleted user " + user);
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "deletes a user";
+  }
+  
+  @Override
+  public String usage() {
+    return getName() + " <username>";
+  }
+  
+  @Override
+  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> completionSet) {
+    registerCompletionForUsers(root, completionSet);
+  }
+  
+  @Override
+  public int numArgs() {
+    return 1;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/EGrepCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/EGrepCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/EGrepCommand.java
new file mode 100644
index 0000000..d63991a
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/EGrepCommand.java
@@ -0,0 +1,59 @@
+/*
+ * 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.accumulo.core.util.shell.commands;
+
+import java.io.IOException;
+
+import org.apache.accumulo.core.client.BatchScanner;
+import org.apache.accumulo.core.client.IteratorSetting;
+import org.apache.accumulo.core.iterators.user.RegExFilter;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+
+public class EGrepCommand extends GrepCommand {
+  
+  private Option matchSubstringOption;
+  
+  @Override
+  protected void setUpIterator(final int prio, final String name, final String term, final BatchScanner scanner, CommandLine cl) throws IOException {
+    if (prio < 0) {
+      throw new IllegalArgumentException("Priority < 0 " + prio);
+    }
+    final IteratorSetting si = new IteratorSetting(prio, name, RegExFilter.class);
+    RegExFilter.setRegexs(si, term, term, term, term, true, cl.hasOption(matchSubstringOption.getOpt()));
+    scanner.addScanIterator(si);
+  }
+  
+  @Override
+  public String description() {
+    return "searches each row, column family, column qualifier and value, in parallel, on the server side (using a java Matcher, so put .* before and after your term if you're not matching the whole element)";
+  }
+  
+  @Override
+  public String usage() {
+    return getName() + " <regex>{ <regex>}";
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options opts = super.getOptions();
+    matchSubstringOption = new Option("g", "global", false, "forces the use of the find() expression matcher, causing substring matches to return true");
+    opts.addOption(matchSubstringOption);
+    return opts;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ExecfileCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ExecfileCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ExecfileCommand.java
new file mode 100644
index 0000000..f4a2632
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ExecfileCommand.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.accumulo.core.util.shell.commands;
+
+import java.io.File;
+import java.nio.charset.StandardCharsets;
+import java.util.Scanner;
+
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.core.util.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+
+public class ExecfileCommand extends Command {
+  private Option verboseOption;
+  
+  @Override
+  public String description() {
+    return "specifies a file containing accumulo commands to execute";
+  }
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    Scanner scanner = new Scanner(new File(cl.getArgs()[0]), StandardCharsets.UTF_8.name());
+    try {
+      while (scanner.hasNextLine()) {
+        shellState.execCommand(scanner.nextLine(), true, cl.hasOption(verboseOption.getOpt()));
+      }
+    } finally {
+      scanner.close();
+    }
+    return 0;
+  }
+  
+  @Override
+  public String usage() {
+    return getName() + " <fileName>";
+  }
+  
+  @Override
+  public int numArgs() {
+    return 1;
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options opts = new Options();
+    verboseOption = new Option("v", "verbose", false, "display command prompt as commands are executed");
+    opts.addOption(verboseOption);
+    return opts;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ExitCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ExitCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ExitCommand.java
new file mode 100644
index 0000000..c78b020
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ExitCommand.java
@@ -0,0 +1,39 @@
+/*
+ * 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.accumulo.core.util.shell.commands;
+
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.core.util.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+
+public class ExitCommand extends Command {
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) {
+    shellState.setExit(true);
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "exits the shell";
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ExportTableCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ExportTableCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ExportTableCommand.java
new file mode 100644
index 0000000..5fd5abb
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ExportTableCommand.java
@@ -0,0 +1,78 @@
+/*
+ * 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.accumulo.core.util.shell.commands;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.TableExistsException;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.core.util.shell.Shell.Command;
+import org.apache.accumulo.core.util.shell.Token;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+
+public class ExportTableCommand extends Command {
+  
+  private Option tableOpt;
+
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException, TableNotFoundException,
+      TableExistsException {
+    
+    final String tableName = OptUtil.getTableOpt(cl, shellState);
+
+    shellState.getConnector().tableOperations().exportTable(tableName, cl.getArgs()[0]);
+    return 0;
+  }
+  
+  @Override
+  public String usage() {
+    return getName() + " <export dir>";
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+    
+    tableOpt = new Option(Shell.tableOption, "table", true, "table to export");
+    
+    tableOpt.setArgName("table");
+    
+    o.addOption(tableOpt);
+
+    return o;
+  }
+  
+  @Override
+  public String description() {
+    return "exports a table";
+  }
+  
+  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> completionSet) {
+    registerCompletionForTables(root, completionSet);
+  }
+  
+  @Override
+  public int numArgs() {
+    return 1;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ExtensionCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ExtensionCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ExtensionCommand.java
new file mode 100644
index 0000000..ab29d19
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ExtensionCommand.java
@@ -0,0 +1,102 @@
+/*
+ * 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.accumulo.core.util.shell.commands;
+
+import java.util.HashSet;
+import java.util.ServiceLoader;
+import java.util.Set;
+import java.util.TreeSet;
+
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.core.util.shell.Shell.Command;
+import org.apache.accumulo.core.util.shell.ShellExtension;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+
+public class ExtensionCommand extends Command {
+  
+  protected Option enable, disable, list;
+  
+  private static ServiceLoader<ShellExtension> extensions = null;
+  
+  private Set<String> loadedHeaders = new HashSet<String>();
+  private Set<String> loadedCommands = new HashSet<String>();
+  private Set<String> loadedExtensions = new TreeSet<String>();
+  
+  public int execute(String fullCommand, CommandLine cl, Shell shellState) throws Exception {
+    if (cl.hasOption(enable.getOpt())) {
+      extensions = ServiceLoader.load(ShellExtension.class);
+      for (ShellExtension se : extensions) {
+        
+        loadedExtensions.add(se.getExtensionName());
+        String header = "-- " + se.getExtensionName() + " Extension Commands ---------";
+        loadedHeaders.add(header);
+        shellState.commandGrouping.put(header, se.getCommands());
+        
+        for (Command cmd : se.getCommands()) {
+          String name = se.getExtensionName() + "::" + cmd.getName();
+          loadedCommands.add(name);
+          shellState.commandFactory.put(name, cmd);
+        }
+      }
+    } else if (cl.hasOption(disable.getOpt())) {
+      //Remove the headers
+      for (String header : loadedHeaders) {
+        shellState.commandGrouping.remove(header);
+      }
+      //remove the commands
+      for (String name : loadedCommands) {
+        shellState.commandFactory.remove(name);
+      }
+      //Reset state
+      loadedExtensions.clear();
+      extensions.reload();
+    } else if (cl.hasOption(list.getOpt())) {
+      shellState.printLines(loadedExtensions.iterator(), true);
+    } else {
+      printHelp(shellState);
+    }
+    return 0;
+  }
+  
+  public String description() {
+    return "Enable, disable, or list shell extensions";
+  }
+  
+  public int numArgs() {
+    return 0;
+  }
+  
+  @Override
+  public String getName() {
+    return "extensions";
+  }
+
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+    enable = new Option("e", "enable", false, "enable shell extensions");
+    disable = new Option("d", "disable", false, "disable shell extensions");
+    list = new Option("l", "list", false, "list shell extensions");
+    o.addOption(enable);
+    o.addOption(disable);
+    o.addOption(list);
+    return o;
+  }
+    
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/FateCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/FateCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/FateCommand.java
new file mode 100644
index 0000000..0196baf
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/FateCommand.java
@@ -0,0 +1,180 @@
+/*
+ * 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.accumulo.core.util.shell.commands;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.Formatter;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.accumulo.core.Constants;
+import org.apache.accumulo.core.client.Instance;
+import org.apache.accumulo.core.conf.AccumuloConfiguration;
+import org.apache.accumulo.core.conf.Property;
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.core.util.shell.Shell.Command;
+import org.apache.accumulo.core.zookeeper.ZooUtil;
+import org.apache.accumulo.fate.AdminUtil;
+import org.apache.accumulo.fate.ReadOnlyTStore.TStatus;
+import org.apache.accumulo.fate.ZooStore;
+import org.apache.accumulo.fate.zookeeper.IZooReaderWriter;
+import org.apache.accumulo.fate.zookeeper.ZooReaderWriter;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+import org.apache.commons.cli.ParseException;
+import org.apache.zookeeper.KeeperException;
+
+/**
+ * Manage FATE transactions
+ * 
+ */
+public class FateCommand extends Command {
+  
+  private static final String SCHEME = "digest";
+  
+  private static final String USER = "accumulo";
+  
+  private Option secretOption;
+  private Option statusOption;
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws ParseException, KeeperException, InterruptedException,
+      IOException {
+    Instance instance = shellState.getInstance();
+    String[] args = cl.getArgs();
+    if (args.length <= 0) {
+      throw new ParseException("Must provide a command to execute");
+    }
+    String cmd = args[0];
+    boolean failedCommand = false;
+    
+    AdminUtil<FateCommand> admin = new AdminUtil<FateCommand>(false);
+    
+    String path = ZooUtil.getRoot(instance) + Constants.ZFATE;
+    String masterPath = ZooUtil.getRoot(instance) + Constants.ZMASTER_LOCK;
+    IZooReaderWriter zk = getZooReaderWriter(shellState.getInstance(), cl.getOptionValue(secretOption.getOpt()));
+    ZooStore<FateCommand> zs = new ZooStore<FateCommand>(path, zk);
+    
+    if ("fail".equals(cmd)) {
+      if (args.length <= 1) {
+        throw new ParseException("Must provide transaction ID");
+      }
+      for (int i = 1; i < args.length; i++) {
+        if (!admin.prepFail(zs, zk, masterPath, args[i])) {
+          System.out.printf("Could not fail transaction: %s%n", args[i]);
+          failedCommand = true;
+        }
+      }
+    } else if ("delete".equals(cmd)) {
+      if (args.length <= 1) {
+        throw new ParseException("Must provide transaction ID");
+      }
+      for (int i = 1; i < args.length; i++) {
+        if (admin.prepDelete(zs, zk, masterPath, args[i])) {
+          admin.deleteLocks(zs, zk, ZooUtil.getRoot(instance) + Constants.ZTABLE_LOCKS, args[i]);
+        } else {
+          System.out.printf("Could not delete transaction: %s%n", args[i]);
+          failedCommand = true;
+        }
+      }
+    } else if ("list".equals(cmd) || "print".equals(cmd)) {
+      // Parse transaction ID filters for print display
+      Set<Long> filterTxid = null;
+      if (args.length >= 2) {
+        filterTxid = new HashSet<Long>(args.length);
+        for (int i = 1; i < args.length; i++) {
+          try {
+            Long val = Long.parseLong(args[i], 16);
+            filterTxid.add(val);
+          } catch (NumberFormatException nfe) {
+            // Failed to parse, will exit instead of displaying everything since the intention was to potentially filter some data
+            System.out.printf("Invalid transaction ID format: %s%n", args[i]);
+            return 1;
+          }
+        }
+      }
+      
+      // Parse TStatus filters for print display
+      EnumSet<TStatus> filterStatus = null;
+      if (cl.hasOption(statusOption.getOpt())) {
+        filterStatus = EnumSet.noneOf(TStatus.class);
+        String[] tstat = cl.getOptionValues(statusOption.getOpt());
+        for (int i = 0; i < tstat.length; i++) {
+          try {
+            filterStatus.add(TStatus.valueOf(tstat[i]));
+          } catch (IllegalArgumentException iae) {
+            System.out.printf("Invalid transaction status name: %s%n", tstat[i]);
+            return 1;
+          }
+        }
+      }
+      
+      StringBuilder buf = new StringBuilder(8096);
+      Formatter fmt = new Formatter(buf);
+      admin.print(zs, zk, ZooUtil.getRoot(instance) + Constants.ZTABLE_LOCKS, fmt, filterTxid, filterStatus);
+      shellState.printLines(Collections.singletonList(buf.toString()).iterator(), true);
+    } else {
+      throw new ParseException("Invalid command option");
+    }
+    
+    return failedCommand ? 1 : 0;
+  }
+  
+  protected synchronized IZooReaderWriter getZooReaderWriter(Instance instance, String secret) {
+    
+    if (secret == null) {
+      @SuppressWarnings("deprecation")
+      AccumuloConfiguration conf = AccumuloConfiguration.getSiteConfiguration();
+      secret = conf.get(Property.INSTANCE_SECRET);
+    }
+    
+    return new ZooReaderWriter(instance.getZooKeepers(), instance.getZooKeepersSessionTimeOut(), SCHEME, (USER + ":" + secret).getBytes());
+  }
+  
+  @Override
+  public String description() {
+    return "manage FATE transactions";
+  }
+  
+  @Override
+  public String usage() {
+    return getName() + " fail <txid>... | delete <txid>... | print [<txid>...]";
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+    secretOption = new Option("s", "secret", true, "specify the instance secret to use");
+    secretOption.setOptionalArg(false);
+    o.addOption(secretOption);
+    statusOption = new Option("t", "status-type", true,
+        "filter 'print' on the transaction status type(s) {NEW, IN_PROGRESS, FAILED_IN_PROGRESS, FAILED, SUCCESSFUL}");
+    statusOption.setArgs(Option.UNLIMITED_VALUES);
+    statusOption.setOptionalArg(false);
+    o.addOption(statusOption);
+    return o;
+  }
+  
+  @Override
+  public int numArgs() {
+    // Arg length varies between 1 to n
+    return -1;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/FlushCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/FlushCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/FlushCommand.java
new file mode 100644
index 0000000..de175eb
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/FlushCommand.java
@@ -0,0 +1,63 @@
+/*
+ * 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.accumulo.core.util.shell.commands;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+import org.apache.hadoop.io.Text;
+
+public class FlushCommand extends TableOperation {
+  private Text startRow;
+  private Text endRow;
+  
+  private boolean wait;
+  private Option waitOpt;
+  
+  @Override
+  public String description() {
+    return "flushes a tables data that is currently in memory to disk";
+  }
+  
+  protected void doTableOp(final Shell shellState, final String tableName) throws AccumuloException, AccumuloSecurityException, TableNotFoundException {
+    shellState.getConnector().tableOperations().flush(tableName, startRow, endRow, wait);
+    Shell.log.info("Flush of table " + tableName + (wait ? " completed." : " initiated..."));
+  }
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    wait = cl.hasOption(waitOpt.getLongOpt());
+    startRow = OptUtil.getStartRow(cl);
+    endRow = OptUtil.getEndRow(cl);
+    return super.execute(fullCommand, cl, shellState);
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options opts = super.getOptions();
+    waitOpt = new Option("w", "wait", false, "wait for flush to finish");
+    opts.addOption(waitOpt);
+    opts.addOption(OptUtil.startRowOpt());
+    opts.addOption(OptUtil.endRowOpt());
+    
+    return opts;
+  }
+}


[45/53] [abbrv] ACCUMULO-1879 Move shell into new package and module

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/ShellOptionsJC.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/ShellOptionsJC.java b/core/src/main/java/org/apache/accumulo/core/util/shell/ShellOptionsJC.java
deleted file mode 100644
index 38692a0..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/ShellOptionsJC.java
+++ /dev/null
@@ -1,280 +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.accumulo.core.util.shell;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Scanner;
-import java.util.TreeMap;
-
-import org.apache.accumulo.core.client.ClientConfiguration;
-import org.apache.accumulo.core.client.ClientConfiguration.ClientProperty;
-import org.apache.accumulo.core.client.security.tokens.AuthenticationToken;
-import org.apache.commons.configuration.ConfigurationException;
-import org.apache.commons.configuration.PropertiesConfiguration;
-import org.apache.log4j.Logger;
-
-import com.beust.jcommander.DynamicParameter;
-import com.beust.jcommander.IStringConverter;
-import com.beust.jcommander.Parameter;
-import com.beust.jcommander.ParameterException;
-import com.beust.jcommander.converters.FileConverter;
-
-public class ShellOptionsJC {
-  // Use the Shell logger because this is really just an extension.
-  public static final Logger log = Logger.getLogger(Shell.class);
-
-  @Parameter(names = {"-u", "--user"}, description = "username (defaults to your OS user)")
-  private String username = System.getProperty("user.name", "root");
-
-  public static class PasswordConverter implements IStringConverter<String> {
-    public static final String STDIN = "stdin";
-
-    private enum KeyType {
-      PASS("pass:"), ENV("env:") {
-        @Override
-        String process(String value) {
-          return System.getenv(value);
-        }
-      },
-      FILE("file:") {
-        @Override
-        String process(String value) {
-          Scanner scanner = null;
-          try {
-            scanner = new Scanner(new File(value));
-            return scanner.nextLine();
-          } catch (FileNotFoundException e) {
-            throw new ParameterException(e);
-          } finally {
-            if (scanner != null) {
-              scanner.close();
-            }
-          }
-        }
-      },
-      STDIN(PasswordConverter.STDIN) {
-        @Override
-        public boolean matches(String value) {
-          return prefix.equals(value);
-        }
-
-        @Override
-        public String convert(String value) {
-          // Will check for this later
-          return prefix;
-        }
-      };
-
-      String prefix;
-
-      private KeyType(String prefix) {
-        this.prefix = prefix;
-      }
-
-      public boolean matches(String value) {
-        return value.startsWith(prefix);
-      }
-
-      public String convert(String value) {
-        return process(value.substring(prefix.length()));
-      }
-
-      String process(String value) {
-        return value;
-      }
-    };
-
-    @Override
-    public String convert(String value) {
-      for (KeyType keyType : KeyType.values()) {
-        if (keyType.matches(value)) {
-          return keyType.convert(value);
-        }
-      }
-
-      return value;
-    }
-  }
-
-  // Note: Don't use "password = true" because then it will prompt even if we have a token
-  @Parameter(names = {"-p", "--password"}, description = "password (can be specified as 'pass:<password>', 'file:<local file containing the password>', "
-      + "'env:<variable containing the pass>', or stdin)", converter = PasswordConverter.class)
-  private String password;
-
-  public static class TokenConverter implements IStringConverter<AuthenticationToken> {
-    @Override
-    public AuthenticationToken convert(String value) {
-      try {
-        return Class.forName(value).asSubclass(AuthenticationToken.class).newInstance();
-      } catch (Exception e) {
-        // Catching ClassNotFoundException, ClassCastException, InstantiationException and IllegalAccessException
-        throw new ParameterException(e);
-      }
-    }
-  }
-
-  @Parameter(names = {"-tc", "--tokenClass"}, description = "token type to create, use the -l to pass options", converter = TokenConverter.class)
-  private AuthenticationToken authenticationToken;
-
-  @DynamicParameter(names = {"-l", "--tokenProperty"}, description = "login properties in the format key=value. Reuse -l for each property")
-  private Map<String,String> tokenProperties = new TreeMap<String,String>();
-
-  @Parameter(names = "--disable-tab-completion", description = "disables tab completion (for less overhead when scripting)")
-  private boolean tabCompletionDisabled;
-
-  @Parameter(names = "--debug", description = "enables client debugging")
-  private boolean debugEnabled;
-
-  @Parameter(names = "--fake", description = "fake a connection to accumulo")
-  private boolean fake;
-
-  @Parameter(names = {"-?", "--help"}, help = true, description = "display this help")
-  private boolean helpEnabled;
-
-  @Parameter(names = {"-e", "--execute-command"}, description = "executes a command, and then exits")
-  private String execCommand;
-
-  @Parameter(names = {"-f", "--execute-file"}, description = "executes commands from a file at startup", converter = FileConverter.class)
-  private File execFile;
-
-  @Parameter(names = {"-fv", "--execute-file-verbose"}, description = "executes commands from a file at startup, with commands shown",
-      converter = FileConverter.class)
-  private File execFileVerbose;
-
-  @Parameter(names = {"-h", "--hdfsZooInstance"}, description = "use hdfs zoo instance")
-  private boolean hdfsZooInstance;
-
-  @Parameter(names = {"-z", "--zooKeeperInstance"}, description = "use a zookeeper instance with the given instance name and list of zoo hosts", arity = 2)
-  private List<String> zooKeeperInstance = new ArrayList<String>();
-
-  @Parameter(names = {"--ssl"}, description = "use ssl to connect to accumulo")
-  private boolean useSsl = false;
-
-  @Parameter(
-      names = "--config-file",
-      description = "read the given client config file.  If omitted, the path searched can be specified with $ACCUMULO_CLIENT_CONF_PATH, which defaults to ~/.accumulo/config:$ACCUMULO_CONF_DIR/client.conf:/etc/accumulo/client.conf")
-  private String clientConfigFile = null;
-
-  @Parameter(names = {"-zi", "--zooKeeperInstanceName"}, description = "use a zookeeper instance with the given instance name")
-  private String zooKeeperInstanceName;
-
-  @Parameter(names = {"-zh", "--zooKeeperHosts"}, description = "use a zookeeper instance with the given list of zoo hosts")
-  private String zooKeeperHosts;
-
-  @Parameter(names = "--auth-timeout", description = "minutes the shell can be idle without re-entering a password")
-  private int authTimeout = 60; // TODO Add validator for positive number
-
-  @Parameter(names = "--disable-auth-timeout", description = "disables requiring the user to re-type a password after being idle")
-  private boolean authTimeoutDisabled;
-
-  @Parameter(hidden = true)
-  private List<String> unrecognizedOptions;
-
-  public String getUsername() {
-    return username;
-  }
-
-  public String getPassword() {
-    return password;
-  }
-
-  public AuthenticationToken getAuthenticationToken() {
-    return authenticationToken;
-  }
-
-  public Map<String,String> getTokenProperties() {
-    return tokenProperties;
-  }
-
-  public boolean isTabCompletionDisabled() {
-    return tabCompletionDisabled;
-  }
-
-  public boolean isDebugEnabled() {
-    return debugEnabled;
-  }
-
-  public boolean isFake() {
-    return fake;
-  }
-
-  public boolean isHelpEnabled() {
-    return helpEnabled;
-  }
-
-  public String getExecCommand() {
-    return execCommand;
-  }
-
-  public File getExecFile() {
-    return execFile;
-  }
-
-  public File getExecFileVerbose() {
-    return execFileVerbose;
-  }
-
-  public boolean isHdfsZooInstance() {
-    return hdfsZooInstance;
-  }
-
-  public List<String> getZooKeeperInstance() {
-    return zooKeeperInstance;
-  }
-
-  public String getZooKeeperInstanceName() {
-    return zooKeeperInstanceName;
-  }
-
-  public String getZooKeeperHosts() {
-    return zooKeeperHosts;
-  }
-
-  public int getAuthTimeout() {
-    return authTimeout;
-  }
-
-  public boolean isAuthTimeoutDisabled() {
-    return authTimeoutDisabled;
-  }
-
-  public List<String> getUnrecognizedOptions() {
-    return unrecognizedOptions;
-  }
-
-  public boolean useSsl() {
-    return useSsl;
-  }
-
-  public String getClientConfigFile() {
-    return clientConfigFile;
-  }
-
-  public ClientConfiguration getClientConfiguration() throws ConfigurationException, FileNotFoundException {
-    ClientConfiguration clientConfig = clientConfigFile == null ? ClientConfiguration.loadDefault() : new ClientConfiguration(new PropertiesConfiguration(
-        getClientConfigFile()));
-    if (useSsl()) {
-      clientConfig.setProperty(ClientProperty.INSTANCE_RPC_SSL_ENABLED, "true");
-    }
-    return clientConfig;
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/ShellUtil.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/ShellUtil.java b/core/src/main/java/org/apache/accumulo/core/util/shell/ShellUtil.java
deleted file mode 100644
index f0dd505..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/ShellUtil.java
+++ /dev/null
@@ -1,60 +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.accumulo.core.util.shell;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.nio.charset.StandardCharsets;
-import java.util.List;
-import java.util.Scanner;
-
-import org.apache.commons.codec.binary.Base64;
-import org.apache.hadoop.io.Text;
-
-import com.google.common.collect.Lists;
-
-public class ShellUtil {
-
-  /**
-   * Scans the given file line-by-line (ignoring empty lines) and returns a list containing those lines. If decode is set to true, every line is decoded using
-   * {@link Base64#decodeBase64(byte[])} from the UTF-8 bytes of that line before inserting in the list.
-   * 
-   * @param filename
-   *          Path to the file that needs to be scanned
-   * @param decode
-   *          Whether to decode lines in the file
-   * @return List of {@link Text} objects containing data in the given file
-   * @throws FileNotFoundException
-   *           if the given file doesn't exist
-   */
-  public static List<Text> scanFile(String filename, boolean decode) throws FileNotFoundException {
-    String line;
-    Scanner file = new Scanner(new File(filename), StandardCharsets.UTF_8.name());
-    List<Text> result = Lists.newArrayList();
-    try {
-      while (file.hasNextLine()) {
-        line = file.nextLine();
-        if (!line.isEmpty()) {
-          result.add(decode ? new Text(Base64.decodeBase64(line.getBytes(StandardCharsets.UTF_8))) : new Text(line));
-        }
-      }
-    } finally {
-      file.close();
-    }
-    return result;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/Token.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/Token.java b/core/src/main/java/org/apache/accumulo/core/util/shell/Token.java
deleted file mode 100644
index b6c5869..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/Token.java
+++ /dev/null
@@ -1,137 +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.accumulo.core.util.shell;
-
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Set;
-
-/*
- * A token is a word in a command in the shell.  The tree that this builds is used for
- * tab-completion of tables, users, commands and certain other parts of the shell that
- * can be realistically and quickly gathered. Tokens can have multiple commands grouped 
- * together and many possible subcommands, although they are stored in a set so duplicates
- * aren't allowed.
- */
-
-public class Token {
-  private Set<String> command = new HashSet<String>();
-  private Set<Token> subcommands = new HashSet<Token>();
-  private boolean caseSensitive = false;
-  
-  public Token() {}
-  
-  public Token(String commandName) {
-    this();
-    command.add(commandName);
-  }
-  
-  public Token(Collection<String> commandNames) {
-    this();
-    command.addAll(commandNames);
-  }
-  
-  public Token(Set<String> commandNames, Set<Token> subCommandNames) {
-    this();
-    command.addAll(commandNames);
-    subcommands.addAll(subCommandNames);
-  }
-  
-  public void setCaseSensitive(boolean cs) {
-    caseSensitive = cs;
-  }
-  
-  public boolean getCaseSensitive() {
-    return caseSensitive;
-  }
-  
-  public Set<String> getCommandNames() {
-    return command;
-  }
-  
-  public Set<Token> getSubcommandList() {
-    return subcommands;
-  }
-  
-  public Token getSubcommand(String name) {
-    Iterator<Token> iter = subcommands.iterator();
-    while (iter.hasNext()) {
-      Token t = iter.next();
-      if (t.containsCommand(name))
-        return t;
-    }
-    return null;
-  }
-  
-  public Set<String> getSubcommandNames() {
-    HashSet<String> set = new HashSet<String>();
-    for (Token t : subcommands)
-      set.addAll(t.getCommandNames());
-    return set;
-  }
-  
-  public Set<String> getSubcommandNames(String startsWith) {
-    Iterator<Token> iter = subcommands.iterator();
-    HashSet<String> set = new HashSet<String>();
-    while (iter.hasNext()) {
-      Token t = iter.next();
-      Set<String> subset = t.getCommandNames();
-      for (String s : subset) {
-        if (!t.getCaseSensitive()) {
-          if (s.toLowerCase().startsWith(startsWith.toLowerCase())) {
-            set.add(s);
-          }
-        } else {
-          if (s.startsWith(startsWith)) {
-            set.add(s);
-          }
-        }
-      }
-    }
-    return set;
-  }
-  
-  public boolean containsCommand(String match) {
-    Iterator<String> iter = command.iterator();
-    while (iter.hasNext()) {
-      String t = iter.next();
-      if (caseSensitive) {
-        if (t.equals(match))
-          return true;
-      } else {
-        if (t.equalsIgnoreCase(match))
-          return true;
-      }
-    }
-    return false;
-  }
-  
-  public void addSubcommand(Token t) {
-    subcommands.add(t);
-  }
-  
-  public void addSubcommand(Collection<String> t) {
-    for (String a : t) {
-      addSubcommand(new Token(a));
-    }
-  }
-  
-  public String toString() {
-    return this.command.toString();
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/AboutCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/AboutCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/AboutCommand.java
deleted file mode 100644
index a0a73e4..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/AboutCommand.java
+++ /dev/null
@@ -1,56 +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.accumulo.core.util.shell.commands;
-
-import java.io.IOException;
-
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-
-public class AboutCommand extends Command {
-  private Option verboseOption;
-  
-  @Override
-  public String description() {
-    return "displays information about this program";
-  }
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws IOException {
-    shellState.printInfo();
-    if (cl.hasOption(verboseOption.getOpt())) {
-      shellState.printVerboseInfo();
-    }
-    return 0;
-  }
-  
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options opts = new Options();
-    verboseOption = new Option("v", "verbose", false, "display detailed session information");
-    opts.addOption(verboseOption);
-    return opts;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ActiveCompactionIterator.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ActiveCompactionIterator.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ActiveCompactionIterator.java
deleted file mode 100644
index bd7d9b2..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ActiveCompactionIterator.java
+++ /dev/null
@@ -1,136 +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.accumulo.core.util.shell.commands;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.accumulo.core.client.IteratorSetting;
-import org.apache.accumulo.core.client.admin.ActiveCompaction;
-import org.apache.accumulo.core.client.admin.InstanceOperations;
-import org.apache.accumulo.core.util.Duration;
-
-class ActiveCompactionIterator implements Iterator<String> {
-  
-  private InstanceOperations instanceOps;
-  private Iterator<String> tsIter;
-  private Iterator<String> compactionIter;
-  
-  private static String maxDecimal(double count) {
-    if (count < 9.995)
-      return String.format("%.2f", count);
-    if (count < 99.95)
-      return String.format("%.1f", count);
-    return String.format("%.0f", count);
-  }
-
-  private static String shortenCount(long count) {
-    if (count < 1000)
-      return count + "";
-    if (count < 1000000)
-      return maxDecimal(count / 1000.0) + "K";
-    if (count < 1000000000)
-      return maxDecimal(count / 1000000.0) + "M";
-    return maxDecimal(count / 1000000000.0) + "B";
-  }
-
-  private void readNext() {
-    final List<String> compactions = new ArrayList<String>();
-    
-    while (tsIter.hasNext()) {
-      
-      final String tserver = tsIter.next();
-      try {
-        List<ActiveCompaction> acl = instanceOps.getActiveCompactions(tserver);
-        
-        acl = new ArrayList<ActiveCompaction>(acl);
-        
-        Collections.sort(acl, new Comparator<ActiveCompaction>() {
-          @Override
-          public int compare(ActiveCompaction o1, ActiveCompaction o2) {
-            return (int) (o2.getAge() - o1.getAge());
-          }
-        });
-
-        for (ActiveCompaction ac : acl) {
-          String output = ac.getOutputFile();
-          int index = output.indexOf("tables");
-          if (index > 0) {
-            output = output.substring(index + 6);
-          }
-          
-          ac.getIterators();
-          
-          List<String> iterList = new ArrayList<String>();
-          Map<String,Map<String,String>> iterOpts = new HashMap<String,Map<String,String>>();
-          for (IteratorSetting is : ac.getIterators()) {
-            iterList.add(is.getName() + "=" + is.getPriority() + "," + is.getIteratorClass());
-            iterOpts.put(is.getName(), is.getOptions());
-          }
-
-          compactions.add(String.format("%21s | %9s | %5s | %6s | %5s | %5s | %15s | %-40s | %5s | %35s | %9s | %s", tserver,
-              Duration.format(ac.getAge(), "", "-"), ac.getType(), ac.getReason(), shortenCount(ac.getEntriesRead()), shortenCount(ac.getEntriesWritten()),
-              ac.getTable(), ac.getExtent(), ac.getInputFiles().size(), output, iterList, iterOpts));
-        }
-      } catch (Exception e) {
-        compactions.add(tserver + " ERROR " + e.getMessage());
-      }
-      
-      if (compactions.size() > 0) {
-        break;
-      }
-    }
-    
-    compactionIter = compactions.iterator();
-  }
-  
-  ActiveCompactionIterator(List<String> tservers, InstanceOperations instanceOps) {
-    this.instanceOps = instanceOps;
-    this.tsIter = tservers.iterator();
-    
-    final String header = String.format(" %-21s| %-9s | %-5s | %-6s | %-5s | %-5s | %-15s | %-40s | %-5s | %-35s | %-9s | %s", "TABLET SERVER", "AGE", "TYPE",
-        "REASON", "READ", "WROTE", "TABLE", "TABLET", "INPUT", "OUTPUT", "ITERATORS", "ITERATOR OPTIONS");
-    
-    compactionIter = Collections.singletonList(header).iterator();
-  }
-  
-  @Override
-  public boolean hasNext() {
-    return compactionIter.hasNext();
-  }
-  
-  @Override
-  public String next() {
-    final String next = compactionIter.next();
-    
-    if (!compactionIter.hasNext())
-      readNext();
-    
-    return next;
-  }
-  
-  @Override
-  public void remove() {
-    throw new UnsupportedOperationException();
-  }
-  
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ActiveScanIterator.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ActiveScanIterator.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ActiveScanIterator.java
deleted file mode 100644
index f1e736f..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ActiveScanIterator.java
+++ /dev/null
@@ -1,91 +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.accumulo.core.util.shell.commands;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-
-import org.apache.accumulo.core.client.admin.ActiveScan;
-import org.apache.accumulo.core.client.admin.InstanceOperations;
-import org.apache.accumulo.core.client.admin.ScanType;
-import org.apache.accumulo.core.util.Duration;
-
-class ActiveScanIterator implements Iterator<String> {
-  
-  private InstanceOperations instanceOps;
-  private Iterator<String> tsIter;
-  private Iterator<String> scansIter;
-  
-  private void readNext() {
-    final List<String> scans = new ArrayList<String>();
-    
-    while (tsIter.hasNext()) {
-      
-      final String tserver = tsIter.next();
-      try {
-        final List<ActiveScan> asl = instanceOps.getActiveScans(tserver);
-        
-        for (ActiveScan as : asl) {
-          scans.add(String.format("%21s |%21s |%9s |%9s |%7s |%6s |%8s |%8s |%10s |%20s |%10s |%10s | %s", tserver, as.getClient(),
-              Duration.format(as.getAge(), "", "-"), Duration.format(as.getLastContactTime(), "", "-"), as.getState(), as.getType(), as.getUser(),
-              as.getTable(), as.getColumns(), as.getAuthorizations(), (as.getType() == ScanType.SINGLE ? as.getExtent() : "N/A"), as.getSsiList(), as.getSsio()));
-        }
-      } catch (Exception e) {
-        scans.add(tserver + " ERROR " + e.getMessage());
-      }
-      
-      if (scans.size() > 0) {
-        break;
-      }
-    }
-    
-    scansIter = scans.iterator();
-  }
-  
-  ActiveScanIterator(List<String> tservers, InstanceOperations instanceOps) {
-    this.instanceOps = instanceOps;
-    this.tsIter = tservers.iterator();
-    
-    final String header = String.format(" %-21s| %-21s| %-9s| %-9s| %-7s| %-6s| %-8s| %-8s| %-10s| %-20s| %-10s| %-10s | %s", "TABLET SERVER", "CLIENT", "AGE",
-        "LAST", "STATE", "TYPE", "USER", "TABLE", "COLUMNS", "AUTHORIZATIONS", "TABLET", "ITERATORS", "ITERATOR OPTIONS");
-    
-    scansIter = Collections.singletonList(header).iterator();
-  }
-  
-  @Override
-  public boolean hasNext() {
-    return scansIter.hasNext();
-  }
-  
-  @Override
-  public String next() {
-    final String next = scansIter.next();
-    
-    if (!scansIter.hasNext())
-      readNext();
-    
-    return next;
-  }
-  
-  @Override
-  public void remove() {
-    throw new UnsupportedOperationException();
-  }
-  
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/AddAuthsCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/AddAuthsCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/AddAuthsCommand.java
deleted file mode 100644
index bd478de..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/AddAuthsCommand.java
+++ /dev/null
@@ -1,82 +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.accumulo.core.util.shell.commands;
-
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.security.Authorizations;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.accumulo.core.util.shell.Token;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.OptionGroup;
-import org.apache.commons.cli.Options;
-
-public class AddAuthsCommand extends Command {
-  private Option userOpt;
-  private Option scanOptAuths;
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException {
-    final String user = cl.getOptionValue(userOpt.getOpt(), shellState.getConnector().whoami());
-    final String scanOpts = cl.getOptionValue(scanOptAuths.getOpt());
-    Authorizations auths = shellState.getConnector().securityOperations().getUserAuthorizations(user);
-    StringBuilder userAuths = new StringBuilder();
-    if (!auths.isEmpty()) {
-      userAuths.append(auths.toString());
-      userAuths.append(",");
-    }
-    userAuths.append(scanOpts);
-    shellState.getConnector().securityOperations().changeUserAuthorizations(user, ScanCommand.parseAuthorizations(userAuths.toString()));
-    Shell.log.debug("Changed record-level authorizations for user " + user);
-    return 0;
-  }
-  
-  @Override
-  public String description() {
-    return "adds authorizations to the maximum scan authorizations for a user";
-  }
-  
-  @Override
-  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> completionSet) {
-    registerCompletionForUsers(root, completionSet);
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-    final OptionGroup setOrClear = new OptionGroup();
-    scanOptAuths = new Option("s", "scan-authorizations", true, "scan authorizations to set");
-    scanOptAuths.setArgName("comma-separated-authorizations");
-    setOrClear.addOption(scanOptAuths);
-    setOrClear.setRequired(true);
-    o.addOptionGroup(setOrClear);
-    userOpt = new Option(Shell.userOption, "user", true, "user to operate on");
-    userOpt.setArgName("user");
-    o.addOption(userOpt);
-    return o;
-  }
-  
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/AddSplitsCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/AddSplitsCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/AddSplitsCommand.java
deleted file mode 100644
index b8ba621..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/AddSplitsCommand.java
+++ /dev/null
@@ -1,88 +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.accumulo.core.util.shell.commands;
-
-import java.util.TreeSet;
-
-import org.apache.accumulo.core.client.TableNotFoundException;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.accumulo.core.util.shell.ShellUtil;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.MissingArgumentException;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-import org.apache.hadoop.io.Text;
-
-public class AddSplitsCommand extends Command {
-  private Option optSplitsFile, base64Opt;
-  
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    final String tableName = OptUtil.getTableOpt(cl, shellState);
-    final boolean decode = cl.hasOption(base64Opt.getOpt());
-    
-    final TreeSet<Text> splits = new TreeSet<Text>();
-    
-    if (cl.hasOption(optSplitsFile.getOpt())) {
-      splits.addAll(ShellUtil.scanFile(cl.getOptionValue(optSplitsFile.getOpt()), decode));
-    } else {
-      if (cl.getArgList().isEmpty()) {
-        throw new MissingArgumentException("No split points specified");
-      }
-      for (String s : cl.getArgs()) {
-        splits.add(new Text(s.getBytes(Shell.CHARSET)));
-      }
-    }
-    
-    if (!shellState.getConnector().tableOperations().exists(tableName)) {
-      throw new TableNotFoundException(null, tableName, null);
-    }
-    shellState.getConnector().tableOperations().addSplits(tableName, splits);
-    
-    return 0;
-  }
-  
-  @Override
-  public String description() {
-    return "adds split points to an existing table";
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-    
-    optSplitsFile = new Option("sf", "splits-file", true, "file with a newline-separated list of rows to split the table with");
-    optSplitsFile.setArgName("filename");
-    
-    base64Opt = new Option("b64", "base64encoded", false, "decode encoded split points (splits file only)");
-    
-    o.addOption(OptUtil.tableOpt("name of the table to add split points to"));
-    o.addOption(optSplitsFile);
-    o.addOption(base64Opt);
-    return o;
-  }
-  
-  @Override
-  public String usage() {
-    return getName() + " [<split>{ <split>} ]";
-  }
-  
-  @Override
-  public int numArgs() {
-    return Shell.NO_FIXED_ARG_LENGTH_CHECK;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/AuthenticateCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/AuthenticateCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/AuthenticateCommand.java
deleted file mode 100644
index 8ebdae8..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/AuthenticateCommand.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.accumulo.core.util.shell.commands;
-
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.security.tokens.PasswordToken;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.accumulo.core.util.shell.Token;
-import org.apache.commons.cli.CommandLine;
-
-public class AuthenticateCommand extends Command {
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException, IOException {
-    final String user = cl.getArgs()[0];
-    final String p = shellState.readMaskedLine("Enter current password for '" + user + "': ", '*');
-    if (p == null) {
-      shellState.getReader().println();
-      return 0;
-    } // user canceled
-    final byte[] password = p.getBytes(StandardCharsets.UTF_8);
-    final boolean valid = shellState.getConnector().securityOperations().authenticateUser(user, new PasswordToken(password));
-    shellState.getReader().println((valid ? "V" : "Not v") + "alid");
-    return 0;
-  }
-  
-  @Override
-  public String description() {
-    return "verifies a user's credentials";
-  }
-  
-  @Override
-  public String usage() {
-    return getName() + " <username>";
-  }
-  
-  @Override
-  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> completionSet) {
-    registerCompletionForUsers(root, completionSet);
-  }
-  
-  @Override
-  public int numArgs() {
-    return 1;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ByeCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ByeCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ByeCommand.java
deleted file mode 100644
index f0c9d24..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ByeCommand.java
+++ /dev/null
@@ -1,19 +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.accumulo.core.util.shell.commands;
-
-public class ByeCommand extends ExitCommand {}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ClasspathCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ClasspathCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ClasspathCommand.java
deleted file mode 100644
index b2fe300..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ClasspathCommand.java
+++ /dev/null
@@ -1,55 +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.accumulo.core.util.shell.commands;
-
-import java.io.IOException;
-
-import jline.console.ConsoleReader;
-
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.accumulo.start.classloader.vfs.AccumuloVFSClassLoader;
-import org.apache.accumulo.start.classloader.vfs.AccumuloVFSClassLoader.Printer;
-import org.apache.commons.cli.CommandLine;
-
-public class ClasspathCommand extends Command {
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) {
-    final ConsoleReader reader = shellState.getReader();
-    AccumuloVFSClassLoader.printClassPath(new Printer() {
-      @Override
-      public void print(String s) {
-        try {
-          reader.println(s);
-        } catch (IOException ex) {
-          throw new RuntimeException(ex);
-        }
-      }
-    });
-    return 0;
-  }
-  
-  @Override
-  public String description() {
-    return "lists the current files on the classpath";
-  }
-  
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ClearCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ClearCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ClearCommand.java
deleted file mode 100644
index 4f15650..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ClearCommand.java
+++ /dev/null
@@ -1,52 +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.accumulo.core.util.shell.commands;
-
-import java.io.IOException;
-
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-
-public class ClearCommand extends Command {
-  @Override
-  public String description() {
-    return "clears the screen";
-  }
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws IOException {
-    // custom clear screen, so I don't have to redraw the prompt twice
-    if (!shellState.getReader().getTerminal().isAnsiSupported()) {
-      throw new IOException("Terminal does not support ANSI commands");
-    }
-    // send the ANSI code to clear the screen
-    shellState.getReader().print(((char) 27) + "[2J");
-    shellState.getReader().flush();
-    
-    // then send the ANSI code to go to position 1,1
-    shellState.getReader().print(((char) 27) + "[1;1H");
-    shellState.getReader().flush();
-    
-    return 0;
-  }
-  
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/CloneTableCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/CloneTableCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/CloneTableCommand.java
deleted file mode 100644
index 207e530..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/CloneTableCommand.java
+++ /dev/null
@@ -1,102 +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.accumulo.core.util.shell.commands;
-
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.TableExistsException;
-import org.apache.accumulo.core.client.TableNotFoundException;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.accumulo.core.util.shell.Token;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-
-public class CloneTableCommand extends Command {
-  
-  private Option setPropsOption;
-  private Option excludePropsOption;
-  private Option noFlushOption;
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException, TableNotFoundException,
-      TableExistsException {
-    
-    final HashMap<String,String> props = new HashMap<String,String>();
-    final HashSet<String> exclude = new HashSet<String>();
-    boolean flush = true;
-    
-    if (cl.hasOption(setPropsOption.getOpt())) {
-      String[] keyVals = cl.getOptionValue(setPropsOption.getOpt()).split(",");
-      for (String keyVal : keyVals) {
-        String[] sa = keyVal.split("=");
-        props.put(sa[0], sa[1]);
-      }
-    }
-    
-    if (cl.hasOption(excludePropsOption.getOpt())) {
-      String[] keys = cl.getOptionValue(excludePropsOption.getOpt()).split(",");
-      for (String key : keys) {
-        exclude.add(key);
-      }
-    }
-    
-    if (cl.hasOption(noFlushOption.getOpt())) {
-      flush = false;
-    }
-    
-    shellState.getConnector().tableOperations().clone(cl.getArgs()[0], cl.getArgs()[1], flush, props, exclude);
-    return 0;
-  }
-  
-  @Override
-  public String usage() {
-    return getName() + " <current table name> <new table name>";
-  }
-  
-  @Override
-  public String description() {
-    return "clones a table";
-  }
-  
-  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> completionSet) {
-    registerCompletionForTables(root, completionSet);
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-    setPropsOption = new Option("s", "set", true, "set initial properties before the table comes online. Expects <prop>=<value>{,<prop>=<value>}");
-    o.addOption(setPropsOption);
-    excludePropsOption = new Option("e", "exclude", true, "exclude properties that should not be copied from source table. Expects <prop>{,<prop>}");
-    o.addOption(excludePropsOption);
-    noFlushOption = new Option("nf", "noFlush", false, "do not flush table data in memory before cloning.");
-    o.addOption(noFlushOption);
-    return o;
-  }
-  
-  @Override
-  public int numArgs() {
-    return 2;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ClsCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ClsCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ClsCommand.java
deleted file mode 100644
index cef6098..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ClsCommand.java
+++ /dev/null
@@ -1,19 +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.accumulo.core.util.shell.commands;
-
-public class ClsCommand extends ClearCommand {}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/CompactCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/CompactCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/CompactCommand.java
deleted file mode 100644
index 55e9395..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/CompactCommand.java
+++ /dev/null
@@ -1,129 +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.accumulo.core.util.shell.commands;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.IteratorSetting;
-import org.apache.accumulo.core.client.TableNotFoundException;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-import org.apache.hadoop.io.Text;
-
-public class CompactCommand extends TableOperation {
-  private Option noFlushOption, waitOpt, profileOpt, cancelOpt;
-  private boolean flush;
-  private Text startRow;
-  private Text endRow;
-  private List<IteratorSetting> iterators;
-  
-  boolean override = false;
-  private boolean wait;
-  
-  private boolean cancel = false;
-
-  @Override
-  public String description() {
-    return "sets all tablets for a table to major compact as soon as possible (based on current time)";
-  }
-  
-  protected void doTableOp(final Shell shellState, final String tableName) throws AccumuloException, AccumuloSecurityException {
-    // compact the tables
-    
-    if (cancel) {
-      try {
-        shellState.getConnector().tableOperations().cancelCompaction(tableName);
-        Shell.log.info("Compaction canceled for table " + tableName);
-      } catch (TableNotFoundException e) {
-        throw new AccumuloException(e);
-      }
-    } else {
-      try {
-        if (wait) {
-          Shell.log.info("Compacting table ...");
-        }
-        
-        shellState.getConnector().tableOperations().compact(tableName, startRow, endRow, iterators, flush, wait);
-        
-        Shell.log.info("Compaction of table " + tableName + " " + (wait ? "completed" : "started") + " for given range");
-      } catch (Exception ex) {
-        throw new AccumuloException(ex);
-      }
-    }
-  }
-  
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    
-    if (cl.hasOption(cancelOpt.getLongOpt())) {
-      cancel = true;
-      
-      if (cl.getOptions().length > 2) {
-        throw new IllegalArgumentException("Can not specify other options with cancel");
-      }
-    } else {
-      cancel = false;
-    }
-
-    flush = !cl.hasOption(noFlushOption.getOpt());
-    startRow = OptUtil.getStartRow(cl);
-    endRow = OptUtil.getEndRow(cl);
-    wait = cl.hasOption(waitOpt.getOpt());
-    
-    if (cl.hasOption(profileOpt.getOpt())) {
-      List<IteratorSetting> iterators = shellState.iteratorProfiles.get(cl.getOptionValue(profileOpt.getOpt()));
-      if (iterators == null) {
-        Shell.log.error("Profile " + cl.getOptionValue(profileOpt.getOpt()) + " does not exist");
-        return -1;
-      }
-      
-      this.iterators = new ArrayList<IteratorSetting>(iterators);
-    } else {
-      this.iterators = Collections.emptyList();
-    }
-
-
-    return super.execute(fullCommand, cl, shellState);
-  }
-  
-  @Override
-  public Options getOptions() {
-    final Options opts = super.getOptions();
-    
-    opts.addOption(OptUtil.startRowOpt());
-    opts.addOption(OptUtil.endRowOpt());
-    noFlushOption = new Option("nf", "noFlush", false, "do not flush table data in memory before compacting.");
-    opts.addOption(noFlushOption);
-    waitOpt = new Option("w", "wait", false, "wait for compact to finish");
-    opts.addOption(waitOpt);
-    
-    profileOpt = new Option("pn", "profile", true, "iterator profile name");
-    profileOpt.setArgName("profile");
-    opts.addOption(profileOpt);
-
-    cancelOpt = new Option(null, "cancel", false, "cancel user initiated compactions");
-    opts.addOption(cancelOpt);
-
-    return opts;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ConfigCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ConfigCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ConfigCommand.java
deleted file mode 100644
index c76a51f..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ConfigCommand.java
+++ /dev/null
@@ -1,315 +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.accumulo.core.util.shell.commands;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.TreeMap;
-
-import jline.console.ConsoleReader;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.NamespaceNotFoundException;
-import org.apache.accumulo.core.client.TableNotFoundException;
-import org.apache.accumulo.core.client.impl.Namespaces;
-import org.apache.accumulo.core.client.impl.Tables;
-import org.apache.accumulo.core.conf.AccumuloConfiguration;
-import org.apache.accumulo.core.conf.Property;
-import org.apache.accumulo.core.security.ColumnVisibility;
-import org.apache.accumulo.core.util.BadArgumentException;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.accumulo.core.util.shell.Shell.PrintFile;
-import org.apache.accumulo.core.util.shell.Token;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.OptionGroup;
-import org.apache.commons.cli.Options;
-
-public class ConfigCommand extends Command {
-  private Option tableOpt, deleteOpt, setOpt, filterOpt, disablePaginationOpt, outputFileOpt, namespaceOpt;
-
-  private int COL1 = 10, COL2 = 7;
-  private ConsoleReader reader;
-
-  @Override
-  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> completionSet) {
-    final Token cmd = new Token(getName());
-    final Token sub = new Token("-" + setOpt.getOpt());
-    for (Property p : Property.values()) {
-      if (!(p.getKey().endsWith(".")) && !p.isExperimental()) {
-        sub.addSubcommand(new Token(p.toString()));
-      }
-    }
-    cmd.addSubcommand(sub);
-    root.addSubcommand(cmd);
-  }
-
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException,
-      TableNotFoundException, IOException, ClassNotFoundException, NamespaceNotFoundException {
-    reader = shellState.getReader();
-
-    final String tableName = cl.getOptionValue(tableOpt.getOpt());
-    if (tableName != null && !shellState.getConnector().tableOperations().exists(tableName)) {
-      throw new TableNotFoundException(null, tableName, null);
-    }
-    final String namespace = cl.getOptionValue(namespaceOpt.getOpt());
-    if (namespace != null && !shellState.getConnector().namespaceOperations().exists(namespace)) {
-      throw new NamespaceNotFoundException(null, namespace, null);
-    }
-    if (cl.hasOption(deleteOpt.getOpt())) {
-      // delete property from table
-      String property = cl.getOptionValue(deleteOpt.getOpt());
-      if (property.contains("=")) {
-        throw new BadArgumentException("Invalid '=' operator in delete operation.", fullCommand, fullCommand.indexOf('='));
-      }
-      if (tableName != null) {
-        if (!Property.isValidTablePropertyKey(property)) {
-          Shell.log.warn("Invalid per-table property : " + property + ", still removing from zookeeper if it's there.");
-        }
-        shellState.getConnector().tableOperations().removeProperty(tableName, property);
-        Shell.log.debug("Successfully deleted table configuration option.");
-      } else if (namespace != null) {
-        if (!Property.isValidTablePropertyKey(property)) {
-          Shell.log.warn("Invalid per-table property : " + property + ", still removing from zookeeper if it's there.");
-        }
-        shellState.getConnector().namespaceOperations().removeProperty(namespace, property);
-        Shell.log.debug("Successfully deleted namespace configuration option.");
-      } else {
-        if (!Property.isValidZooPropertyKey(property)) {
-          Shell.log.warn("Invalid per-table property : " + property + ", still removing from zookeeper if it's there.");
-        }
-        shellState.getConnector().instanceOperations().removeProperty(property);
-        Shell.log.debug("Successfully deleted system configuration option");
-      }
-    } else if (cl.hasOption(setOpt.getOpt())) {
-      // set property on table
-      String property = cl.getOptionValue(setOpt.getOpt()), value = null;
-      if (!property.contains("=")) {
-        throw new BadArgumentException("Missing '=' operator in set operation.", fullCommand, fullCommand.indexOf(property));
-      }
-      final String pair[] = property.split("=", 2);
-      property = pair[0];
-      value = pair[1];
-
-      if (tableName != null) {
-        if (!Property.isValidTablePropertyKey(property)) {
-          throw new BadArgumentException("Invalid per-table property.", fullCommand, fullCommand.indexOf(property));
-        }
-        if (property.equals(Property.TABLE_DEFAULT_SCANTIME_VISIBILITY.getKey())) {
-          new ColumnVisibility(value); // validate that it is a valid expression
-        }
-        shellState.getConnector().tableOperations().setProperty(tableName, property, value);
-        Shell.log.debug("Successfully set table configuration option.");
-      } else if (namespace != null) {
-        if (!Property.isValidTablePropertyKey(property)) {
-          throw new BadArgumentException("Invalid per-table property.", fullCommand, fullCommand.indexOf(property));
-        }
-        if (property.equals(Property.TABLE_DEFAULT_SCANTIME_VISIBILITY.getKey())) {
-          new ColumnVisibility(value); // validate that it is a valid expression
-        }
-        shellState.getConnector().namespaceOperations().setProperty(namespace, property, value);
-        Shell.log.debug("Successfully set table configuration option.");
-      } else {
-        if (!Property.isValidZooPropertyKey(property)) {
-          throw new BadArgumentException("Property cannot be modified in zookeeper", fullCommand, fullCommand.indexOf(property));
-        }
-        shellState.getConnector().instanceOperations().setProperty(property, value);
-        Shell.log.debug("Successfully set system configuration option");
-      }
-    } else {
-      // display properties
-      final TreeMap<String,String> systemConfig = new TreeMap<String,String>();
-      systemConfig.putAll(shellState.getConnector().instanceOperations().getSystemConfiguration());
-
-      final String outputFile = cl.getOptionValue(outputFileOpt.getOpt());
-      final PrintFile printFile = outputFile == null ? null : new PrintFile(outputFile);
-
-      final TreeMap<String,String> siteConfig = new TreeMap<String,String>();
-      siteConfig.putAll(shellState.getConnector().instanceOperations().getSiteConfiguration());
-
-      final TreeMap<String,String> defaults = new TreeMap<String,String>();
-      for (Entry<String,String> defaultEntry : AccumuloConfiguration.getDefaultConfiguration()) {
-        defaults.put(defaultEntry.getKey(), defaultEntry.getValue());
-      }
-
-      final TreeMap<String,String> namespaceConfig = new TreeMap<String,String>();
-      if (tableName != null) {
-        String n = Namespaces.getNamespaceName(shellState.getInstance(),
-            Tables.getNamespaceId(shellState.getInstance(), Tables.getTableId(shellState.getInstance(), tableName)));
-        for (Entry<String,String> e : shellState.getConnector().namespaceOperations().getProperties(n)) {
-          namespaceConfig.put(e.getKey(), e.getValue());
-        }
-      }
-
-      Iterable<Entry<String,String>> acuconf = shellState.getConnector().instanceOperations().getSystemConfiguration().entrySet();
-      if (tableName != null) {
-        acuconf = shellState.getConnector().tableOperations().getProperties(tableName);
-      } else if (namespace != null) {
-        acuconf = shellState.getConnector().namespaceOperations().getProperties(namespace);
-      }
-      final TreeMap<String,String> sortedConf = new TreeMap<String,String>();
-      for (Entry<String,String> propEntry : acuconf) {
-        sortedConf.put(propEntry.getKey(), propEntry.getValue());
-      }
-
-      for (Entry<String,String> propEntry : acuconf) {
-        final String key = propEntry.getKey();
-        // only show properties with similar names to that
-        // specified, or all of them if none specified
-        if (cl.hasOption(filterOpt.getOpt()) && !key.contains(cl.getOptionValue(filterOpt.getOpt()))) {
-          continue;
-        }
-        if ((tableName != null || namespace != null) && !Property.isValidTablePropertyKey(key)) {
-          continue;
-        }
-        COL2 = Math.max(COL2, propEntry.getKey().length() + 3);
-      }
-
-      final ArrayList<String> output = new ArrayList<String>();
-      printConfHeader(output);
-
-      for (Entry<String,String> propEntry : sortedConf.entrySet()) {
-        final String key = propEntry.getKey();
-
-        // only show properties with similar names to that
-        // specified, or all of them if none specified
-        if (cl.hasOption(filterOpt.getOpt()) && !key.contains(cl.getOptionValue(filterOpt.getOpt()))) {
-          continue;
-        }
-        if ((tableName != null || namespace != null) && !Property.isValidTablePropertyKey(key)) {
-          continue;
-        }
-        String siteVal = siteConfig.get(key);
-        String sysVal = systemConfig.get(key);
-        String curVal = propEntry.getValue();
-        String dfault = defaults.get(key);
-        String nspVal = namespaceConfig.get(key);
-        boolean printed = false;
-
-        if (dfault != null && key.toLowerCase().contains("password")) {
-          siteVal = sysVal = dfault = curVal = curVal.replaceAll(".", "*");
-        }
-        if (sysVal != null) {
-          if (defaults.containsKey(key) && !Property.getPropertyByKey(key).isExperimental()) {
-            printConfLine(output, "default", key, dfault);
-            printed = true;
-          }
-          if (!defaults.containsKey(key) || !defaults.get(key).equals(siteVal)) {
-            printConfLine(output, "site", printed ? "   @override" : key, siteVal == null ? "" : siteVal);
-            printed = true;
-          }
-          if (!siteConfig.containsKey(key) || !siteVal.equals(sysVal)) {
-            printConfLine(output, "system", printed ? "   @override" : key, sysVal == null ? "" : sysVal);
-            printed = true;
-          }
-
-        }
-        if (nspVal != null) {
-          if (!systemConfig.containsKey(key) || !sysVal.equals(nspVal)) {
-            printConfLine(output, "namespace", printed ? "   @override" : key, nspVal == null ? "" : nspVal);
-            printed = true;
-          }
-        }
-
-        // show per-table value only if it is different (overridden)
-        if (tableName != null && !curVal.equals(nspVal)) {
-          printConfLine(output, "table", printed ? "   @override" : key, curVal);
-        } else if (namespace != null && !curVal.equals(sysVal)) {
-          printConfLine(output, "namespace", printed ? "   @override" : key, curVal);
-        }
-      }
-      printConfFooter(output);
-      shellState.printLines(output.iterator(), !cl.hasOption(disablePaginationOpt.getOpt()), printFile);
-      if (printFile != null) {
-        printFile.close();
-      }
-    }
-    return 0;
-  }
-
-  private void printConfHeader(List<String> output) {
-    printConfFooter(output);
-    output.add(String.format("%-" + COL1 + "s | %-" + COL2 + "s | %s", "SCOPE", "NAME", "VALUE"));
-    printConfFooter(output);
-  }
-
-  private void printConfLine(List<String> output, String s1, String s2, String s3) {
-    if (s2.length() < COL2) {
-      s2 += " " + Shell.repeat(".", COL2 - s2.length() - 1);
-    }
-    output.add(String.format("%-" + COL1 + "s | %-" + COL2 + "s | %s", s1, s2,
-        s3.replace("\n", "\n" + Shell.repeat(" ", COL1 + 1) + "|" + Shell.repeat(" ", COL2 + 2) + "|" + " ")));
-  }
-
-  private void printConfFooter(List<String> output) {
-    int col3 = Math.max(1, Math.min(Integer.MAX_VALUE, reader.getTerminal().getWidth() - COL1 - COL2 - 6));
-    output.add(String.format("%" + COL1 + "s-+-%" + COL2 + "s-+-%-" + col3 + "s", Shell.repeat("-", COL1), Shell.repeat("-", COL2), Shell.repeat("-", col3)));
-  }
-
-  @Override
-  public String description() {
-    return "prints system properties and table specific properties";
-  }
-
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-    final OptionGroup og = new OptionGroup();
-    final OptionGroup tgroup = new OptionGroup();
-
-    tableOpt = new Option(Shell.tableOption, "table", true, "table to display/set/delete properties for");
-    deleteOpt = new Option("d", "delete", true, "delete a per-table property");
-    setOpt = new Option("s", "set", true, "set a per-table property");
-    filterOpt = new Option("f", "filter", true, "show only properties that contain this string");
-    disablePaginationOpt = new Option("np", "no-pagination", false, "disables pagination of output");
-    outputFileOpt = new Option("o", "output", true, "local file to write the scan output to");
-    namespaceOpt = new Option(Shell.namespaceOption, "namespace", true, "namespace to display/set/delete properties for");
-
-    tableOpt.setArgName("table");
-    deleteOpt.setArgName("property");
-    setOpt.setArgName("property=value");
-    filterOpt.setArgName("string");
-    outputFileOpt.setArgName("file");
-    namespaceOpt.setArgName("namespace");
-
-    og.addOption(deleteOpt);
-    og.addOption(setOpt);
-    og.addOption(filterOpt);
-
-    tgroup.addOption(tableOpt);
-    tgroup.addOption(namespaceOpt);
-
-    o.addOptionGroup(tgroup);
-    o.addOptionGroup(og);
-    o.addOption(disablePaginationOpt);
-    o.addOption(outputFileOpt);
-
-    return o;
-  }
-
-  @Override
-  public int numArgs() {
-    return 0;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ConstraintCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ConstraintCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ConstraintCommand.java
deleted file mode 100644
index 208ac4a..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ConstraintCommand.java
+++ /dev/null
@@ -1,134 +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.accumulo.core.util.shell.commands;
-
-import java.util.Map.Entry;
-
-import org.apache.accumulo.core.constraints.Constraint;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.accumulo.core.util.shell.ShellCommandException;
-import org.apache.accumulo.core.util.shell.ShellCommandException.ErrorCode;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.OptionGroup;
-import org.apache.commons.cli.Options;
-
-public class ConstraintCommand extends Command {
-  protected Option namespaceOpt;
-
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
-    final String tableName;
-    final String namespace;
-
-    if (cl.hasOption(namespaceOpt.getOpt())) {
-      namespace = cl.getOptionValue(namespaceOpt.getOpt());
-    } else {
-      namespace = null;
-    }
-
-    if (cl.hasOption(OptUtil.tableOpt().getOpt()) || !shellState.getTableName().isEmpty()) {
-      tableName = OptUtil.getTableOpt(cl, shellState);
-    } else {
-      tableName = null;
-    }
-
-    int i;
-    switch (OptUtil.getAldOpt(cl)) {
-      case ADD:
-        for (String constraint : cl.getArgs()) {
-          if (namespace != null) {
-            if (!shellState.getConnector().namespaceOperations().testClassLoad(namespace, constraint, Constraint.class.getName())) {
-              throw new ShellCommandException(ErrorCode.INITIALIZATION_FAILURE, "Servers are unable to load " + constraint + " as type "
-                  + Constraint.class.getName());
-            }
-            i = shellState.getConnector().namespaceOperations().addConstraint(namespace, constraint);
-            shellState.getReader().println("Added constraint " + constraint + " to namespace " + namespace + " with number " + i);
-          } else if (tableName != null && !tableName.isEmpty()) {
-            if (!shellState.getConnector().tableOperations().testClassLoad(tableName, constraint, Constraint.class.getName())) {
-              throw new ShellCommandException(ErrorCode.INITIALIZATION_FAILURE, "Servers are unable to load " + constraint + " as type "
-                  + Constraint.class.getName());
-            }
-            i = shellState.getConnector().tableOperations().addConstraint(tableName, constraint);
-            shellState.getReader().println("Added constraint " + constraint + " to table " + tableName + " with number " + i);
-          } else {
-            throw new IllegalArgumentException("Please specify either a table or a namespace");
-          }
-        }
-        break;
-      case DELETE:
-        for (String constraint : cl.getArgs()) {
-          i = Integer.parseInt(constraint);
-          if (namespace != null) {
-            shellState.getConnector().namespaceOperations().removeConstraint(namespace, i);
-            shellState.getReader().println("Removed constraint " + i + " from namespace " + namespace);
-          } else if (tableName != null) {
-            shellState.getConnector().tableOperations().removeConstraint(tableName, i);
-            shellState.getReader().println("Removed constraint " + i + " from table " + tableName);
-          } else {
-            throw new IllegalArgumentException("Please specify either a table or a namespace");
-          }
-        }
-        break;
-      case LIST:
-        if (namespace != null) {
-          for (Entry<String,Integer> property : shellState.getConnector().namespaceOperations().listConstraints(namespace).entrySet()) {
-            shellState.getReader().println(property.toString());
-          }
-        } else if (tableName != null) {
-          for (Entry<String,Integer> property : shellState.getConnector().tableOperations().listConstraints(tableName).entrySet()) {
-            shellState.getReader().println(property.toString());
-          }
-        } else {
-          throw new IllegalArgumentException("Please specify either a table or a namespace");
-        }
-    }
-
-    return 0;
-  }
-
-  @Override
-  public String description() {
-    return "adds, deletes, or lists constraints for a table";
-  }
-
-  @Override
-  public int numArgs() {
-    return Shell.NO_FIXED_ARG_LENGTH_CHECK;
-  }
-
-  @Override
-  public String usage() {
-    return getName() + " <constraint>{ <constraint>}";
-  }
-
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-    o.addOptionGroup(OptUtil.addListDeleteGroup("constraint"));
-
-    OptionGroup grp = new OptionGroup();
-    grp.addOption(OptUtil.tableOpt("table to add, delete, or list constraints for"));
-    namespaceOpt = new Option(Shell.namespaceOption, "namespace", true, "name of a namespace to operate on");
-    namespaceOpt.setArgName("namespace");
-    grp.addOption(namespaceOpt);
-
-    o.addOptionGroup(grp);
-    return o;
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/main/java/org/apache/accumulo/core/util/shell/commands/CreateNamespaceCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/CreateNamespaceCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/CreateNamespaceCommand.java
deleted file mode 100644
index a9f3deb..0000000
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/CreateNamespaceCommand.java
+++ /dev/null
@@ -1,99 +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.accumulo.core.util.shell.commands;
-
-import java.io.IOException;
-import java.util.Map.Entry;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.NamespaceExistsException;
-import org.apache.accumulo.core.client.NamespaceNotFoundException;
-import org.apache.accumulo.core.client.TableExistsException;
-import org.apache.accumulo.core.client.TableNotFoundException;
-import org.apache.accumulo.core.conf.Property;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.OptionGroup;
-import org.apache.commons.cli.Options;
-
-public class CreateNamespaceCommand extends Command {
-  private Option createNamespaceOptCopyConfig;
-
-  @Override
-  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException,
-      TableExistsException, TableNotFoundException, IOException, ClassNotFoundException, NamespaceExistsException, NamespaceNotFoundException {
-
-    if (createNamespaceOptCopyConfig == null) {
-      getOptions();
-    }
-
-    String namespace = cl.getArgs()[0];
-
-    shellState.getConnector().namespaceOperations().create(namespace);
-
-    // Copy options if flag was set
-    Iterable<Entry<String,String>> configuration = null;
-    if (cl.hasOption(createNamespaceOptCopyConfig.getOpt())) {
-      String copy = cl.getOptionValue(createNamespaceOptCopyConfig.getOpt());
-      if (shellState.getConnector().namespaceOperations().exists(namespace)) {
-        configuration = shellState.getConnector().namespaceOperations().getProperties(copy);
-      }
-    } 
-    if (configuration != null) {
-      for (Entry<String,String> entry : configuration) {
-        if (Property.isValidTablePropertyKey(entry.getKey())) {
-          shellState.getConnector().namespaceOperations().setProperty(namespace, entry.getKey(), entry.getValue());
-        }
-      }
-    }
-
-    return 0;
-  }
-
-  @Override
-  public String description() {
-    return "creates a new namespace";
-  }
-
-  @Override
-  public String usage() {
-    return getName() + " <namespaceName>";
-  }
-
-  @Override
-  public Options getOptions() {
-    final Options o = new Options();
-
-    createNamespaceOptCopyConfig = new Option("cc", "copy-config", true, "namespace to copy configuration from");
-    createNamespaceOptCopyConfig.setArgName("namespace");
-
-    OptionGroup ogp = new OptionGroup();
-    ogp.addOption(createNamespaceOptCopyConfig);
-
-    o.addOptionGroup(ogp);
-
-    return o;
-  }
-
-  @Override
-  public int numArgs() {
-    return 1;
-  }
-}


[40/53] [abbrv] ACCUMULO-1879 Move shell into new package and module

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/test/java/org/apache/accumulo/core/util/shell/ShellConfigTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/accumulo/core/util/shell/ShellConfigTest.java b/core/src/test/java/org/apache/accumulo/core/util/shell/ShellConfigTest.java
deleted file mode 100644
index 43d2e12..0000000
--- a/core/src/test/java/org/apache/accumulo/core/util/shell/ShellConfigTest.java
+++ /dev/null
@@ -1,90 +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.accumulo.core.util.shell;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import java.io.FileDescriptor;
-import java.io.FileInputStream;
-import java.io.PrintStream;
-import java.io.PrintWriter;
-
-import jline.console.ConsoleReader;
-
-import org.apache.accumulo.core.client.security.tokens.PasswordToken;
-import org.apache.accumulo.core.util.shell.ShellTest.TestOutputStream;
-import org.apache.log4j.Level;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-import com.beust.jcommander.ParameterException;
-
-public class ShellConfigTest {
-  TestOutputStream output;
-  Shell shell;
-  PrintStream out;
-  
-  @Before
-  public void setUp() throws Exception {
-    Shell.log.setLevel(Level.ERROR);
-    
-    out = System.out;
-    output = new TestOutputStream();
-    System.setOut(new PrintStream(output));
-
-    shell = new Shell(new ConsoleReader(new FileInputStream(FileDescriptor.in), output), new PrintWriter(output));
-    shell.setLogErrorsToConsole();
-  }
-  
-  @After
-  public void teardown() throws Exception {
-    shell.shutdown();
-    output.clear();
-    System.setOut(out);
-  }
-  
-  @Test
-  public void testHelp() {
-    assertTrue(shell.config("--help"));
-    assertTrue("Did not print usage", output.get().startsWith("Usage"));
-  }
-  
-  @Test
-  public void testBadArg() {
-    assertTrue(shell.config("--bogus"));
-    assertTrue("Did not print usage", output.get().startsWith("Usage"));
-  }
-  
-  @Test
-  public void testToken() {
-    assertTrue(shell.config("--fake", "-tc", PasswordToken.class.getCanonicalName()));
-    assertTrue(output.get().contains(ParameterException.class.getCanonicalName()));
-  }
-  
-  @Test
-  public void testTokenAndOption() {
-    assertFalse(shell.config("--fake", "-tc", PasswordToken.class.getCanonicalName(), "-u", "foo", "-l", "password=foo"));
-  }
-  
-  @Test
-  public void testTokenAndOptionAndPassword() {
-    assertTrue(shell.config("--fake", "-tc", PasswordToken.class.getCanonicalName(), "-l", "password=foo", "-p", "bar"));
-    assertTrue(output.get().contains(ParameterException.class.getCanonicalName()));
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/test/java/org/apache/accumulo/core/util/shell/ShellSetInstanceTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/accumulo/core/util/shell/ShellSetInstanceTest.java b/core/src/test/java/org/apache/accumulo/core/util/shell/ShellSetInstanceTest.java
deleted file mode 100644
index d4c0aea..0000000
--- a/core/src/test/java/org/apache/accumulo/core/util/shell/ShellSetInstanceTest.java
+++ /dev/null
@@ -1,242 +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.accumulo.core.util.shell;
-
-import static org.easymock.EasyMock.anyObject;
-import static org.easymock.EasyMock.expect;
-import static org.powermock.api.easymock.PowerMock.createMock;
-import static org.powermock.api.easymock.PowerMock.expectLastCall;
-import static org.powermock.api.easymock.PowerMock.expectNew;
-import static org.powermock.api.easymock.PowerMock.mockStatic;
-import static org.powermock.api.easymock.PowerMock.replay;
-import static org.powermock.api.easymock.PowerMock.verify;
-
-import java.io.FileDescriptor;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.PrintWriter;
-import java.util.Collections;
-import java.util.List;
-import java.util.UUID;
-
-import jline.console.ConsoleReader;
-
-import org.apache.accumulo.core.client.ClientConfiguration;
-import org.apache.accumulo.core.client.ClientConfiguration.ClientProperty;
-import org.apache.accumulo.core.client.ZooKeeperInstance;
-import org.apache.accumulo.core.client.mock.MockInstance;
-import org.apache.accumulo.core.conf.AccumuloConfiguration;
-import org.apache.accumulo.core.conf.ConfigSanityCheck;
-import org.apache.accumulo.core.conf.Property;
-import org.apache.accumulo.core.conf.SiteConfiguration;
-import org.apache.accumulo.core.zookeeper.ZooUtil;
-import org.apache.hadoop.fs.Path;
-import org.apache.log4j.Level;
-import org.easymock.EasyMock;
-import org.junit.After;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
-
-@RunWith(PowerMockRunner.class)
-@PrepareForTest({Shell.class, ZooUtil.class, ConfigSanityCheck.class})
-public class ShellSetInstanceTest {
-  public static class TestOutputStream extends OutputStream {
-    StringBuilder sb = new StringBuilder();
-
-    @Override
-    public void write(int b) throws IOException {
-      sb.append((char) (0xff & b));
-    }
-
-    public String get() {
-      return sb.toString();
-    }
-
-    public void clear() {
-      sb.setLength(0);
-    }
-  }
-
-  @BeforeClass
-  public static void setupClass() {
-    // This is necessary because PowerMock messes with Hadoop's ability to
-    // determine the current user (see security.UserGroupInformation).
-    System.setProperty("HADOOP_USER_NAME", "test");
-  }
-  @AfterClass
-  public static void teardownClass() {
-    System.clearProperty("HADOOP_USER_NAME");
-  }
-
-  private TestOutputStream output;
-  private Shell shell;
-
-  @Before
-  public void setup() throws IOException {
-    Shell.log.setLevel(Level.OFF);
-    output = new TestOutputStream();
-    shell = new Shell(new ConsoleReader(new FileInputStream(FileDescriptor.in), output), new PrintWriter(output));
-    shell.setLogErrorsToConsole();
-  }
-  @After
-  public void tearDown() {
-    shell.shutdown();
-    SiteConfiguration.clearInstance();
-  }
-
-  @Test
-  public void testSetInstance_Fake() throws Exception {
-    ShellOptionsJC opts = createMock(ShellOptionsJC.class);
-    expect(opts.isFake()).andReturn(true);
-    replay(opts);
-    MockInstance theInstance = createMock(MockInstance.class);
-    expectNew(MockInstance.class, "fake").andReturn(theInstance);
-    replay(theInstance, MockInstance.class);
-
-    shell.setInstance(opts);
-    verify(theInstance, MockInstance.class);
-  }
-  @Test
-  public void testSetInstance_HdfsZooInstance_Explicit() throws Exception {
-    testSetInstance_HdfsZooInstance(true, false, false);
-  }
-  @Test
-  public void testSetInstance_HdfsZooInstance_InstanceGiven() throws Exception {
-    testSetInstance_HdfsZooInstance(false, true, false);
-  }
-  @Test
-  public void testSetInstance_HdfsZooInstance_HostsGiven() throws Exception {
-    testSetInstance_HdfsZooInstance(false, false, true);
-  }
-  @Test
-  public void testSetInstance_HdfsZooInstance_Implicit() throws Exception {
-    testSetInstance_HdfsZooInstance(false, false, false);
-  }
-  
-  @SuppressWarnings("deprecation")
-  private void testSetInstance_HdfsZooInstance(boolean explicitHdfs, boolean onlyInstance, boolean onlyHosts)
-    throws Exception {
-    ClientConfiguration clientConf = createMock(ClientConfiguration.class);
-    ShellOptionsJC opts = createMock(ShellOptionsJC.class);
-    expect(opts.isFake()).andReturn(false);
-    expect(opts.getClientConfiguration()).andReturn(clientConf);
-    expect(opts.isHdfsZooInstance()).andReturn(explicitHdfs);
-    if (!explicitHdfs) {
-      expect(opts.getZooKeeperInstance())
-        .andReturn(Collections.<String>emptyList());
-      if (onlyInstance) {
-        expect(opts.getZooKeeperInstanceName()).andReturn("instance");
-        expect(clientConf.withInstance("instance")).andReturn(clientConf);
-      } else {
-        expect(opts.getZooKeeperInstanceName()).andReturn(null);
-      }
-      if (onlyHosts) {
-        expect(opts.getZooKeeperHosts()).andReturn("host3,host4");
-        expect(clientConf.withZkHosts("host3,host4")).andReturn(clientConf);
-      } else {
-        expect(opts.getZooKeeperHosts()).andReturn(null);
-      }
-    }
-    replay(opts);
-
-    if (!onlyInstance) {
-      expect(clientConf.get(ClientProperty.INSTANCE_NAME)).andReturn(null);
-    }
-
-    mockStatic(ConfigSanityCheck.class);
-    ConfigSanityCheck.validate(EasyMock.<AccumuloConfiguration>anyObject());
-    expectLastCall().atLeastOnce();
-    replay(ConfigSanityCheck.class);
-
-    if (!onlyHosts) {
-      expect(clientConf.containsKey(Property.INSTANCE_ZK_HOST.getKey())).andReturn(true).atLeastOnce();
-      expect(clientConf.getString(Property.INSTANCE_ZK_HOST.getKey())).andReturn("host1,host2").atLeastOnce();
-      expect(clientConf.withZkHosts("host1,host2")).andReturn(clientConf);
-    }
-    if (!onlyInstance) {
-      expect(clientConf.containsKey(Property.INSTANCE_VOLUMES.getKey())).andReturn(false).atLeastOnce();
-      expect(clientConf.containsKey(Property.INSTANCE_DFS_DIR.getKey())).andReturn(true).atLeastOnce();
-      expect(clientConf.containsKey(Property.INSTANCE_DFS_URI.getKey())).andReturn(true).atLeastOnce();
-      expect(clientConf.getString(Property.INSTANCE_DFS_URI.getKey())).andReturn("hdfs://nn1").atLeastOnce();
-      expect(clientConf.getString(Property.INSTANCE_DFS_DIR.getKey())).andReturn("/dfs").atLeastOnce();
-    }
-
-    UUID randomUUID = null;
-    if (!onlyInstance) {
-      mockStatic(ZooUtil.class);
-      randomUUID = UUID.randomUUID();
-      expect(ZooUtil.getInstanceIDFromHdfs(anyObject(Path.class), anyObject(AccumuloConfiguration.class)))
-        .andReturn(randomUUID.toString());
-      replay(ZooUtil.class);
-      expect(clientConf.withInstance(randomUUID)).andReturn(clientConf);
-    }
-    replay(clientConf);
-
-    ZooKeeperInstance theInstance = createMock(ZooKeeperInstance.class);
-    
-    expectNew(ZooKeeperInstance.class, clientConf).andReturn(theInstance);
-    replay(theInstance, ZooKeeperInstance.class);
-
-    shell.setInstance(opts);
-    verify(theInstance, ZooKeeperInstance.class);
-  }
-  @Test
-  public void testSetInstance_ZKInstance_DashZ() throws Exception {
-    testSetInstance_ZKInstance(true);
-  }
-  @Test
-  public void testSetInstance_ZKInstance_DashZIandZH() throws Exception {
-    testSetInstance_ZKInstance(false);
-  }
-  private void testSetInstance_ZKInstance(boolean dashZ) throws Exception {
-    ClientConfiguration clientConf = createMock(ClientConfiguration.class);
-    ShellOptionsJC opts = createMock(ShellOptionsJC.class);
-    expect(opts.isFake()).andReturn(false);
-    expect(opts.getClientConfiguration()).andReturn(clientConf);
-    expect(opts.isHdfsZooInstance()).andReturn(false);
-    if (dashZ) {
-      expect(clientConf.withInstance("foo")).andReturn(clientConf);
-      expect(clientConf.withZkHosts("host1,host2")).andReturn(clientConf);
-      List<String> zl = new java.util.ArrayList<String>();
-      zl.add("foo");
-      zl.add("host1,host2");
-      expect(opts.getZooKeeperInstance()).andReturn(zl);
-      expectLastCall().anyTimes();
-    } else {
-      expect(clientConf.withInstance("bar")).andReturn(clientConf);
-      expect(clientConf.withZkHosts("host3,host4")).andReturn(clientConf);
-      expect(opts.getZooKeeperInstance()).andReturn(Collections.<String>emptyList());
-      expect(opts.getZooKeeperInstanceName()).andReturn("bar");
-      expect(opts.getZooKeeperHosts()).andReturn("host3,host4");
-    }
-    replay(clientConf);
-    replay(opts);
-
-    ZooKeeperInstance theInstance = createMock(ZooKeeperInstance.class);
-    expectNew(ZooKeeperInstance.class, clientConf).andReturn(theInstance);
-    replay(theInstance, ZooKeeperInstance.class);
-
-    shell.setInstance(opts);
-    verify(theInstance, ZooKeeperInstance.class);
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/test/java/org/apache/accumulo/core/util/shell/ShellTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/accumulo/core/util/shell/ShellTest.java b/core/src/test/java/org/apache/accumulo/core/util/shell/ShellTest.java
deleted file mode 100644
index 3d9b89e..0000000
--- a/core/src/test/java/org/apache/accumulo/core/util/shell/ShellTest.java
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.accumulo.core.util.shell;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.io.PrintWriter;
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.TimeZone;
-
-import jline.console.ConsoleReader;
-
-import org.apache.accumulo.core.util.format.DateStringFormatter;
-import org.apache.log4j.Level;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-public class ShellTest {
-  public static class TestOutputStream extends OutputStream {
-    StringBuilder sb = new StringBuilder();
-
-    @Override
-    public void write(int b) throws IOException {
-      sb.append((char) (0xff & b));
-    }
-
-    public String get() {
-      return sb.toString();
-    }
-
-    public void clear() {
-      sb.setLength(0);
-    }
-  }
-
-  public static class StringInputStream extends InputStream {
-    private String source = "";
-    private int offset = 0;
-
-    @Override
-    public int read() throws IOException {
-      if (offset == source.length())
-        return '\n';
-      else
-        return source.charAt(offset++);
-    }
-
-    public void set(String other) {
-      source = other;
-      offset = 0;
-    }
-  }
-
-  private StringInputStream input;
-  private TestOutputStream output;
-  private Shell shell;
-
-  void exec(String cmd) throws IOException {
-    output.clear();
-    shell.execCommand(cmd, true, true);
-  }
-
-  void exec(String cmd, boolean expectGoodExit) throws IOException {
-    exec(cmd);
-    if (expectGoodExit)
-      assertGoodExit("", true);
-    else
-      assertBadExit("", true);
-  }
-
-  void exec(String cmd, boolean expectGoodExit, String expectString) throws IOException {
-    exec(cmd, expectGoodExit, expectString, true);
-  }
-
-  void exec(String cmd, boolean expectGoodExit, String expectString, boolean stringPresent) throws IOException {
-    exec(cmd);
-    if (expectGoodExit)
-      assertGoodExit(expectString, stringPresent);
-    else
-      assertBadExit(expectString, stringPresent);
-  }
-
-  @Before
-  public void setup() throws IOException {
-    TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
-    Shell.log.setLevel(Level.OFF);
-    output = new TestOutputStream();
-    input = new StringInputStream();
-    PrintWriter pw = new PrintWriter(new OutputStreamWriter(output));
-    shell = new Shell(new ConsoleReader(input, output), pw);
-    shell.setLogErrorsToConsole();
-    shell.config("--fake", "-u", "test", "-p", "secret");
-  }
-
-  @After
-  public void teardown() {
-    shell.shutdown();
-  }
-
-  void assertGoodExit(String s, boolean stringPresent) {
-    Shell.log.debug(output.get());
-    assertEquals(shell.getExitCode(), 0);
-    if (s.length() > 0)
-      assertEquals(s + " present in " + output.get() + " was not " + stringPresent, stringPresent, output.get().contains(s));
-  }
-
-  void assertBadExit(String s, boolean stringPresent) {
-    Shell.log.debug(output.get());
-    assertTrue(shell.getExitCode() > 0);
-    if (s.length() > 0)
-      assertEquals(s + " present in " + output.get() + " was not " + stringPresent, stringPresent, output.get().contains(s));
-    shell.resetExitCode();
-  }
-
-  @Test
-  public void aboutTest() throws IOException {
-    Shell.log.debug("Starting about test -----------------------------------");
-    exec("about", true, "Shell - Apache Accumulo Interactive Shell");
-    exec("about -v", true, "Current user:");
-    exec("about arg", false, "java.lang.IllegalArgumentException: Expected 0 arguments");
-  }
-
-  @Test
-  public void addGetSplitsTest() throws IOException {
-    Shell.log.debug("Starting addGetSplits test ----------------------------");
-    exec("addsplits arg", false, "java.lang.IllegalStateException: Not in a table context");
-    exec("createtable test", true);
-    exec("addsplits 1 \\x80", true);
-    exec("getsplits", true, "1\n\\x80");
-    exec("deletetable test -f", true, "Table: [test] has been deleted");
-  }
-
-  @Test
-  public void insertDeleteScanTest() throws IOException {
-    Shell.log.debug("Starting insertDeleteScan test ------------------------");
-    exec("insert r f q v", false, "java.lang.IllegalStateException: Not in a table context");
-    exec("delete r f q", false, "java.lang.IllegalStateException: Not in a table context");
-    exec("createtable test", true);
-    exec("insert r f q v", true);
-    exec("scan", true, "r f:q []    v");
-    exec("delete r f q", true);
-    exec("scan", true, "r f:q []    v", false);
-    exec("insert \\x90 \\xa0 \\xb0 \\xc0\\xd0\\xe0\\xf0", true);
-    exec("scan", true, "\\x90 \\xA0:\\xB0 []    \\xC0\\xD0");
-    exec("scan -f 2", true, "\\x90 \\xA0:\\xB0 []    \\xC0\\xD0");
-    exec("scan -f 2", true, "\\x90 \\xA0:\\xB0 []    \\xC0\\xD0\\xE0", false);
-    exec("scan -b \\x90 -e \\x90 -c \\xA0", true, "\\x90 \\xA0:\\xB0 []    \\xC0");
-    exec("scan -b \\x90 -e \\x90 -c \\xA0:\\xB0", true, "\\x90 \\xA0:\\xB0 []    \\xC0");
-    exec("scan -b \\x90 -be", true, "\\x90 \\xA0:\\xB0 []    \\xC0", false);
-    exec("scan -e \\x90 -ee", true, "\\x90 \\xA0:\\xB0 []    \\xC0", false);
-    exec("scan -b \\x90\\x00", true, "\\x90 \\xA0:\\xB0 []    \\xC0", false);
-    exec("scan -e \\x8f", true, "\\x90 \\xA0:\\xB0 []    \\xC0", false);
-    exec("delete \\x90 \\xa0 \\xb0", true);
-    exec("scan", true, "\\x90 \\xA0:\\xB0 []    \\xC0", false);
-    exec("deletetable test -f", true, "Table: [test] has been deleted");
-  }
-
-  @Test
-  public void authsTest() throws Exception {
-    Shell.log.debug("Starting auths test --------------------------");
-    exec("setauths x,y,z", false, "Missing required option");
-    exec("setauths -s x,y,z -u notauser", false, "user does not exist");
-    exec("setauths -s y,z,x", true);
-    exec("getauths -u notauser", false, "user does not exist");
-    exec("getauths", true, "x,y,z");
-    exec("addauths -u notauser", false, "Missing required option");
-    exec("addauths -u notauser -s foo", false, "user does not exist");
-    exec("addauths -s a", true);
-    exec("getauths", true, "a,x,y,z");
-    exec("setauths -c", true);
-  }
-
-  @Test
-  public void userTest() throws Exception {
-    Shell.log.debug("Starting user test --------------------------");
-    // Test cannot be done via junit because createuser only prompts for password
-    // exec("createuser root", false, "user exists");
-  }
-
-  @Test
-  public void duContextTest() throws Exception {
-    Shell.log.debug("Starting du context test --------------------------");
-    exec("createtable t", true);
-    exec("du", true, "0 [t]");
-    exec("deletetable t -f", true, "Table: [t] has been deleted");
-  }
-
-  @Test
-  public void duTest() throws IOException {
-    Shell.log.debug("Starting DU test --------------------------");
-    exec("createtable t", true);
-    exec("du t", true, "0 [t]");
-    exec("deletetable t -f", true, "Table: [t] has been deleted");
-  }
-
-  @Test
-  public void duPatternTest() throws IOException {
-    Shell.log.debug("Starting DU with pattern test --------------------------");
-    exec("createtable t", true);
-    exec("createtable tt", true);
-    exec("du -p t.*", true, "0 [t, tt]");
-    exec("deletetable t -f", true, "Table: [t] has been deleted");
-    exec("deletetable tt -f", true, "Table: [tt] has been deleted");
-  }
-
-  @Test
-  public void scanDateStringFormatterTest() throws IOException {
-    Shell.log.debug("Starting scan dateStringFormatter test --------------------------");
-    exec("createtable t", true);
-    exec("insert r f q v -ts 0", true);
-    DateFormat dateFormat = new SimpleDateFormat(DateStringFormatter.DATE_FORMAT);
-    String expected = String.format("r f:q [] %s    v", dateFormat.format(new Date(0)));
-    exec("scan -fm org.apache.accumulo.core.util.format.DateStringFormatter -st", true, expected);
-    exec("deletetable t -f", true, "Table: [t] has been deleted");
-  }
-
-  @Test
-  public void commentTest() throws IOException {
-    Shell.log.debug("Starting comment test --------------------------");
-    exec("#", true, "Unknown command", false);
-    exec("# foo", true, "Unknown command", false);
-    exec("- foo", true, "Unknown command", true);
-  }
-
-  @Test
-  public void execFileTest() throws IOException {
-    Shell.log.debug("Starting exec file test --------------------------");
-    shell.config("--fake", "-u", "test", "-p", "secret", "-f", "src/test/resources/shelltest.txt");
-    assertEquals(0, shell.start());
-    assertGoodExit("Unknown command", false);
-  }
-
-  @Test
-  public void setIterTest() throws IOException {
-    Shell.log.debug("Starting setiter test --------------------------");
-    exec("createtable t", true);
-
-    String cmdJustClass = "setiter -class VersioningIterator -p 1";
-    exec(cmdJustClass, false, "java.lang.IllegalArgumentException", false);
-    exec(cmdJustClass, false, "fully qualified package name", true);
-
-    String cmdFullPackage = "setiter -class o.a.a.foo -p 1";
-    exec(cmdFullPackage, false, "java.lang.IllegalArgumentException", false);
-    exec(cmdFullPackage, false, "class not found", true);
-
-    String cmdNoOption = "setiter -class java.lang.String -p 1";
-    exec(cmdNoOption, false, "loaded successfully but does not implement SortedKeyValueIterator", true);
-
-    input.set("\n\n");
-    exec("setiter -scan -class org.apache.accumulo.core.iterators.ColumnFamilyCounter -p 30 -name foo", true);
-    
-    input.set("bar\nname value\n");
-    exec("setiter -scan -class org.apache.accumulo.core.iterators.ColumnFamilyCounter -p 31", true);
-    
-    //TODO can't verify this as config -t fails, functionality verified in ShellServerIT
-    
-    exec("deletetable t -f", true, "Table: [t] has been deleted");
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/test/java/org/apache/accumulo/core/util/shell/ShellUtilTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/accumulo/core/util/shell/ShellUtilTest.java b/core/src/test/java/org/apache/accumulo/core/util/shell/ShellUtilTest.java
deleted file mode 100644
index a5fd179..0000000
--- a/core/src/test/java/org/apache/accumulo/core/util/shell/ShellUtilTest.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.accumulo.core.util.shell;
-
-import static org.junit.Assert.*;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-import java.util.List;
-
-import org.apache.commons.codec.binary.Base64;
-import org.apache.commons.io.FileUtils;
-import org.apache.hadoop.io.Text;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-
-import com.google.common.collect.ImmutableList;
-
-public class ShellUtilTest {
-
-  @Rule
-  public TemporaryFolder folder = new TemporaryFolder(new File(System.getProperty("user.dir") + "/target"));
-
-  // String with 3 lines, with one empty line
-  private static final String FILEDATA = "line1\n\nline2";
-
-  @Test
-  public void testWithoutDecode() throws IOException {
-    File testFile = new File(folder.getRoot(), "testFileNoDecode.txt");
-    FileUtils.writeStringToFile(testFile, FILEDATA);
-    List<Text> output = ShellUtil.scanFile(testFile.getAbsolutePath(), false);
-    assertEquals(ImmutableList.of(new Text("line1"), new Text("line2")), output);
-  }
-
-  @Test
-  public void testWithDecode() throws IOException {
-    File testFile = new File(folder.getRoot(), "testFileWithDecode.txt");
-    FileUtils.writeStringToFile(testFile, FILEDATA);
-    List<Text> output = ShellUtil.scanFile(testFile.getAbsolutePath(), true);
-    assertEquals(
-        ImmutableList.of(new Text(Base64.decodeBase64("line1".getBytes(StandardCharsets.UTF_8))), new Text(Base64.decodeBase64("line2".getBytes(StandardCharsets.UTF_8)))),
-        output);
-  }
-
-  @Test(expected = FileNotFoundException.class)
-  public void testWithMissingFile() throws FileNotFoundException {
-    ShellUtil.scanFile("missingFile.txt", false);
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/test/java/org/apache/accumulo/core/util/shell/command/FormatterCommandTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/accumulo/core/util/shell/command/FormatterCommandTest.java b/core/src/test/java/org/apache/accumulo/core/util/shell/command/FormatterCommandTest.java
deleted file mode 100644
index 091ef75..0000000
--- a/core/src/test/java/org/apache/accumulo/core/util/shell/command/FormatterCommandTest.java
+++ /dev/null
@@ -1,184 +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.accumulo.core.util.shell.command;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Iterator;
-import java.util.Map.Entry;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.TableExistsException;
-import org.apache.accumulo.core.client.mock.MockShell;
-import org.apache.accumulo.core.data.Key;
-import org.apache.accumulo.core.data.Value;
-import org.apache.accumulo.core.util.format.Formatter;
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.log4j.Level;
-import org.apache.log4j.Logger;
-import org.junit.Assert;
-import org.junit.Test;
-
-/**
- * Uses the MockShell to test the shell output with Formatters
- */
-public class FormatterCommandTest {
-  ByteArrayOutputStream out = null;
-  InputStream in = null;
-  
-  @Test
-  public void test() throws IOException, AccumuloException, AccumuloSecurityException, TableExistsException, ClassNotFoundException {
-    // Keep the Shell AUDIT log off the test output
-    Logger.getLogger(Shell.class).setLevel(Level.WARN);
-    
-    final String[] args = new String[] {"--fake", "-u", "root", "-p", ""};
-    
-    final String[] commands = createCommands();
-    
-    in = MockShell.makeCommands(commands);
-    out = new ByteArrayOutputStream();
-    
-    final MockShell shell = new MockShell(in, out);
-    shell.config(args);
-    
-    // Can't call createtable in the shell with MockAccumulo
-    shell.getConnector().tableOperations().create("test");
-    
-    try {
-      shell.start();
-    } catch (Exception e) {
-      Assert.fail("Exception while running commands: " + e.getMessage());
-    }
-    
-    shell.getReader().flush();
-    
-    final String[] output = new String(out.toByteArray()).split("\n\r");
-    
-    boolean formatterOn = false;
-    
-    final String[] expectedDefault = new String[] {"row cf:cq []    1234abcd", "row cf1:cq1 []    9876fedc", "row2 cf:cq []    13579bdf",
-        "row2 cf1:cq []    2468ace"};
-    
-    final String[] expectedFormatted = new String[] {"row cf:cq []    0x31 0x32 0x33 0x34 0x61 0x62 0x63 0x64",
-        "row cf1:cq1 []    0x39 0x38 0x37 0x36 0x66 0x65 0x64 0x63", "row2 cf:cq []    0x31 0x33 0x35 0x37 0x39 0x62 0x64 0x66",
-        "row2 cf1:cq []    0x32 0x34 0x36 0x38 0x61 0x63 0x65"};
-    
-    int outputIndex = 0;
-    while (outputIndex < output.length) {
-      final String line = output[outputIndex];
-      
-      if (line.startsWith("root@mock-instance")) {
-        if (line.contains("formatter")) {
-          formatterOn = true;
-        }
-        
-        outputIndex++;
-      } else if (line.startsWith("row")) {
-        int expectedIndex = 0;
-        String[] comparisonData;
-        
-        // Pick the type of data we expect (formatted or default)
-        if (formatterOn) {
-          comparisonData = expectedFormatted;
-        } else {
-          comparisonData = expectedDefault;
-        }
-        
-        // Ensure each output is what we expected
-        while (expectedIndex + outputIndex < output.length && expectedIndex < expectedFormatted.length) {
-          Assert.assertEquals(comparisonData[expectedIndex].trim(), output[expectedIndex + outputIndex].trim());
-          expectedIndex++;
-        }
-        
-        outputIndex += expectedIndex;
-      }
-    }
-  }
-  
-  private String[] createCommands() {
-    return new String[] {"table test", "insert row cf cq 1234abcd", "insert row cf1 cq1 9876fedc", "insert row2 cf cq 13579bdf", "insert row2 cf1 cq 2468ace",
-        "scan", "formatter -t test -f org.apache.accumulo.core.util.shell.command.FormatterCommandTest$HexFormatter", "scan"};
-  }
-  
-  /**
-   * <p>
-   * Simple <code>Formatter</code> that will convert each character in the Value from decimal to hexadecimal. Will automatically skip over characters in the
-   * value which do not fall within the [0-9,a-f] range.
-   * </p>
-   * 
-   * <p>
-   * Example: <code>'0'</code> will be displayed as <code>'0x30'</code>
-   * </p>
-   */
-  public static class HexFormatter implements Formatter {
-    private Iterator<Entry<Key,Value>> iter = null;
-    private boolean printTs = false;
-    
-    private final static String tab = "\t";
-    private final static String newline = "\n";
-    
-    public HexFormatter() {}
-    
-    @Override
-    public boolean hasNext() {
-      return this.iter.hasNext();
-    }
-    
-    @Override
-    public String next() {
-      final Entry<Key,Value> entry = iter.next();
-      
-      String key;
-      
-      // Observe the timestamps
-      if (printTs) {
-        key = entry.getKey().toString();
-      } else {
-        key = entry.getKey().toStringNoTime();
-      }
-      
-      final Value v = entry.getValue();
-      
-      // Approximate how much space we'll need
-      final StringBuilder sb = new StringBuilder(key.length() + v.getSize() * 5);
-      
-      sb.append(key).append(tab);
-      
-      for (byte b : v.get()) {
-        if ((b >= 48 && b <= 57) || (b >= 97 || b <= 102)) {
-          sb.append(String.format("0x%x ", Integer.valueOf(b)));
-        }
-      }
-      
-      sb.append(newline);
-      
-      return sb.toString();
-    }
-    
-    @Override
-    public void remove() {}
-    
-    @Override
-    public void initialize(final Iterable<Entry<Key,Value>> scanner, final boolean printTimestamps) {
-      this.iter = scanner.iterator();
-      this.printTs = printTimestamps;
-    }
-  }
-  
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/core/src/test/resources/shelltest.txt
----------------------------------------------------------------------
diff --git a/core/src/test/resources/shelltest.txt b/core/src/test/resources/shelltest.txt
deleted file mode 100644
index 19b6f61..0000000
--- a/core/src/test/resources/shelltest.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-# 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.
-exit
-foo

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/examples/simple/pom.xml
----------------------------------------------------------------------
diff --git a/examples/simple/pom.xml b/examples/simple/pom.xml
index 752d952..8390d01 100644
--- a/examples/simple/pom.xml
+++ b/examples/simple/pom.xml
@@ -61,6 +61,10 @@
     </dependency>
     <dependency>
       <groupId>org.apache.accumulo</groupId>
+      <artifactId>accumulo-shell</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.accumulo</groupId>
       <artifactId>accumulo-trace</artifactId>
     </dependency>
     <dependency>

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/examples/simple/src/main/java/org/apache/accumulo/examples/simple/shell/DebugCommand.java
----------------------------------------------------------------------
diff --git a/examples/simple/src/main/java/org/apache/accumulo/examples/simple/shell/DebugCommand.java b/examples/simple/src/main/java/org/apache/accumulo/examples/simple/shell/DebugCommand.java
index cab78bd..6960898 100644
--- a/examples/simple/src/main/java/org/apache/accumulo/examples/simple/shell/DebugCommand.java
+++ b/examples/simple/src/main/java/org/apache/accumulo/examples/simple/shell/DebugCommand.java
@@ -19,8 +19,8 @@ package org.apache.accumulo.examples.simple.shell;
 import java.util.Set;
 import java.util.TreeSet;
 
-import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
 import org.apache.commons.cli.CommandLine;
 
 public class DebugCommand extends Command {

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/examples/simple/src/main/java/org/apache/accumulo/examples/simple/shell/MyAppShellExtension.java
----------------------------------------------------------------------
diff --git a/examples/simple/src/main/java/org/apache/accumulo/examples/simple/shell/MyAppShellExtension.java b/examples/simple/src/main/java/org/apache/accumulo/examples/simple/shell/MyAppShellExtension.java
index 3a22f7b..1ba5ad3 100644
--- a/examples/simple/src/main/java/org/apache/accumulo/examples/simple/shell/MyAppShellExtension.java
+++ b/examples/simple/src/main/java/org/apache/accumulo/examples/simple/shell/MyAppShellExtension.java
@@ -16,8 +16,8 @@
  */
 package org.apache.accumulo.examples.simple.shell;
 
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.accumulo.core.util.shell.ShellExtension;
+import org.apache.accumulo.shell.ShellExtension;
+import org.apache.accumulo.shell.Shell.Command;
 
 public class MyAppShellExtension extends ShellExtension {
   

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index a829ba3..d6a552d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -74,6 +74,7 @@
   <modules>
     <module>trace</module>
     <module>core</module>
+    <module>shell</module>
     <module>fate</module>
     <module>start</module>
     <module>examples/simple</module>
@@ -283,6 +284,11 @@
       </dependency>
       <dependency>
         <groupId>org.apache.accumulo</groupId>
+        <artifactId>accumulo-shell</artifactId>
+        <version>${project.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.accumulo</groupId>
         <artifactId>accumulo-start</artifactId>
         <version>${project.version}</version>
       </dependency>

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/server/monitor/pom.xml
----------------------------------------------------------------------
diff --git a/server/monitor/pom.xml b/server/monitor/pom.xml
index 10586f1..411812c 100644
--- a/server/monitor/pom.xml
+++ b/server/monitor/pom.xml
@@ -65,6 +65,10 @@
     </dependency>
     <dependency>
       <groupId>org.apache.accumulo</groupId>
+      <artifactId>accumulo-shell</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.accumulo</groupId>
       <artifactId>accumulo-trace</artifactId>
     </dependency>
     <dependency>

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/server/monitor/src/main/java/org/apache/accumulo/monitor/servlets/ShellServlet.java
----------------------------------------------------------------------
diff --git a/server/monitor/src/main/java/org/apache/accumulo/monitor/servlets/ShellServlet.java b/server/monitor/src/main/java/org/apache/accumulo/monitor/servlets/ShellServlet.java
index 1824840..25e9e33 100644
--- a/server/monitor/src/main/java/org/apache/accumulo/monitor/servlets/ShellServlet.java
+++ b/server/monitor/src/main/java/org/apache/accumulo/monitor/servlets/ShellServlet.java
@@ -34,7 +34,7 @@ import javax.servlet.http.HttpSession;
 
 import jline.console.ConsoleReader;
 
-import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.shell.Shell;
 
 public class ShellServlet extends BasicServlet {
   private static final long serialVersionUID = 1L;

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/pom.xml
----------------------------------------------------------------------
diff --git a/shell/pom.xml b/shell/pom.xml
new file mode 100644
index 0000000..a5af4b8
--- /dev/null
+++ b/shell/pom.xml
@@ -0,0 +1,123 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.apache.accumulo</groupId>
+    <artifactId>accumulo-project</artifactId>
+    <version>1.7.0-SNAPSHOT</version>
+  </parent>
+  <artifactId>accumulo-shell</artifactId>
+  <name>Shell</name>
+  <description>An interactive shell for accessing Apache Accumulo via a command line interface.</description>
+  <dependencies>
+    <dependency>
+      <groupId>com.beust</groupId>
+      <artifactId>jcommander</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>com.google.guava</groupId>
+      <artifactId>guava</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>commons-cli</groupId>
+      <artifactId>commons-cli</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>commons-codec</groupId>
+      <artifactId>commons-codec</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>commons-collections</groupId>
+      <artifactId>commons-collections</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>commons-configuration</groupId>
+      <artifactId>commons-configuration</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>commons-io</groupId>
+      <artifactId>commons-io</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>commons-lang</groupId>
+      <artifactId>commons-lang</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>jline</groupId>
+      <artifactId>jline</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>log4j</groupId>
+      <artifactId>log4j</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.accumulo</groupId>
+      <artifactId>accumulo-core</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.accumulo</groupId>
+      <artifactId>accumulo-fate</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.accumulo</groupId>
+      <artifactId>accumulo-start</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.accumulo</groupId>
+      <artifactId>accumulo-trace</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.commons</groupId>
+      <artifactId>commons-vfs2</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.hadoop</groupId>
+      <artifactId>hadoop-client</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.thrift</groupId>
+      <artifactId>libthrift</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.easymock</groupId>
+      <artifactId>easymock</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.powermock</groupId>
+      <artifactId>powermock-api-easymock</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.powermock</groupId>
+      <artifactId>powermock-core</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.powermock</groupId>
+      <artifactId>powermock-module-junit4</artifactId>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+</project>


[37/53] [abbrv] ACCUMULO-1879 Move shell into new package and module

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteNamespaceCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteNamespaceCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteNamespaceCommand.java
new file mode 100644
index 0000000..faf1147
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteNamespaceCommand.java
@@ -0,0 +1,100 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.accumulo.core.client.NamespaceNotFoundException;
+import org.apache.accumulo.core.client.impl.Namespaces;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Token;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+
+public class DeleteNamespaceCommand extends Command {
+  private Option forceOpt;
+
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    boolean force = false;
+    boolean operate = true;
+    if (cl.hasOption(forceOpt.getOpt())) {
+      force = true;
+    }
+    String namespace = cl.getArgs()[0];
+
+    if (!force) {
+      shellState.getReader().flush();
+      String line = shellState.getReader().readLine(getName() + " { " + namespace + " } (yes|no)? ");
+      operate = line != null && (line.equalsIgnoreCase("y") || line.equalsIgnoreCase("yes"));
+    }
+    if (operate) {
+      doTableOp(shellState, namespace, force);
+    }
+    return 0;
+  }
+
+  @Override
+  public String description() {
+    return "deletes a namespace";
+  }
+
+  protected void doTableOp(final Shell shellState, final String namespace, boolean force) throws Exception {
+    boolean resetContext = false;
+    String currentTable = shellState.getTableName();
+    if (!Namespaces.getNameToIdMap(shellState.getInstance()).containsKey(namespace)) {
+      throw new NamespaceNotFoundException(null, namespace, null);
+    }
+
+    String namespaceId = Namespaces.getNamespaceId(shellState.getInstance(), namespace);
+    List<String> tables = Namespaces.getTableNames(shellState.getInstance(), namespaceId);
+    resetContext = tables.contains(currentTable);
+
+    if (force)
+      for (String table : shellState.getConnector().tableOperations().list())
+        if (table.startsWith(namespace + "."))
+          shellState.getConnector().tableOperations().delete(table);
+
+    shellState.getConnector().namespaceOperations().delete(namespace);
+    if (resetContext) {
+      shellState.setTableName("");
+    }
+  }
+
+  @Override
+  public Options getOptions() {
+    forceOpt = new Option("f", "force", false, "force deletion without prompting");
+    final Options opts = super.getOptions();
+
+    opts.addOption(forceOpt);
+    return opts;
+  }
+
+  @Override
+  public int numArgs() {
+    return 1;
+  }
+
+  @Override
+  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> special) {
+    registerCompletionForNamespaces(root, special);
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteRowsCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteRowsCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteRowsCommand.java
new file mode 100644
index 0000000..09f2938
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteRowsCommand.java
@@ -0,0 +1,65 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+import org.apache.hadoop.io.Text;
+
+public class DeleteRowsCommand extends Command {
+  private Option forceOpt;
+  private Option startRowOptExclusive;
+ 
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    final String tableName = OptUtil.getTableOpt(cl, shellState);
+    final Text startRow = OptUtil.getStartRow(cl);
+    final Text endRow = OptUtil.getEndRow(cl);
+    if (!cl.hasOption(forceOpt.getOpt()) && (startRow == null || endRow == null)) {
+      shellState.getReader().println("Not deleting unbounded range. Specify both ends, or use --force");
+      return 1;
+    }
+    shellState.getConnector().tableOperations().deleteRows(tableName, startRow, endRow);
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "deletes a range of rows in a table.  Note that rows matching the start row ARE NOT deleted, but rows matching the end row ARE deleted.";
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+    forceOpt = new Option("f", "force", false, "delete data even if start or end are not specified");
+    startRowOptExclusive = new Option(OptUtil.START_ROW_OPT, "begin-row", true, "begin row (exclusive)");
+    startRowOptExclusive.setArgName("begin-row");
+    o.addOption(startRowOptExclusive);
+    o.addOption(OptUtil.endRowOpt());
+    o.addOption(OptUtil.tableOpt("table to delete a row range from"));
+    o.addOption(forceOpt);
+    return o;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteScanIterCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteScanIterCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteScanIterCommand.java
new file mode 100644
index 0000000..f3c9823
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteScanIterCommand.java
@@ -0,0 +1,102 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.accumulo.core.client.IteratorSetting;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.OptionGroup;
+import org.apache.commons.cli.Options;
+
+public class DeleteScanIterCommand extends Command {
+  private Option nameOpt, allOpt;
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    final String tableName = OptUtil.getTableOpt(cl, shellState);
+    
+    if (cl.hasOption(allOpt.getOpt())) {
+      final List<IteratorSetting> tableScanIterators = shellState.scanIteratorOptions.remove(tableName);
+      if (tableScanIterators == null) {
+        Shell.log.info("No scan iterators set on table " + tableName);
+      } else {
+        Shell.log.info("Removed the following scan iterators from table " + tableName + ":" + tableScanIterators);
+      }
+    } else if (cl.hasOption(nameOpt.getOpt())) {
+      final String name = cl.getOptionValue(nameOpt.getOpt());
+      final List<IteratorSetting> tableScanIterators = shellState.scanIteratorOptions.get(tableName);
+      if (tableScanIterators != null) {
+        boolean found = false;
+        for (Iterator<IteratorSetting> iter = tableScanIterators.iterator(); iter.hasNext();) {
+          if (iter.next().getName().equals(name)) {
+            iter.remove();
+            found = true;
+            break;
+          }
+        }
+        if (!found) {
+          Shell.log.info("No iterator named " + name + " found for table " + tableName);
+        } else {
+          Shell.log.info("Removed scan iterator " + name + " from table " + tableName + " (" + shellState.scanIteratorOptions.get(tableName).size() + " left)");
+          if (shellState.scanIteratorOptions.get(tableName).size() == 0) {
+            shellState.scanIteratorOptions.remove(tableName);
+          }
+        }
+      } else {
+        Shell.log.info("No iterator named " + name + " found for table " + tableName);
+      }
+    }
+    
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "deletes a table-specific scan iterator so it is no longer used during this shell session";
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+    
+    OptionGroup nameGroup = new OptionGroup();
+    
+    nameOpt = new Option("n", "name", true, "iterator to delete");
+    nameOpt.setArgName("itername");
+    
+    allOpt = new Option("a", "all", false, "delete all scan iterators");
+    allOpt.setArgName("all");
+    
+    nameGroup.addOption(nameOpt);
+    nameGroup.addOption(allOpt);
+    nameGroup.setRequired(true);
+    o.addOptionGroup(nameGroup);
+    o.addOption(OptUtil.tableOpt("table to delete scan iterators from"));
+    
+    return o;
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteShellIterCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteShellIterCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteShellIterCommand.java
new file mode 100644
index 0000000..3010f0b
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteShellIterCommand.java
@@ -0,0 +1,100 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.accumulo.core.client.IteratorSetting;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.OptionGroup;
+import org.apache.commons.cli.Options;
+
+public class DeleteShellIterCommand extends Command {
+  private Option nameOpt, allOpt, profileOpt;
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+
+    String profile = cl.getOptionValue(profileOpt.getOpt());
+    if (shellState.iteratorProfiles.containsKey(profile)) {
+      if (cl.hasOption(allOpt.getOpt())) {
+        shellState.iteratorProfiles.remove(profile);
+        Shell.log.info("Removed profile " + profile);
+      } else {
+        List<IteratorSetting> iterSettings = shellState.iteratorProfiles.get(profile);
+        String name = cl.getOptionValue(nameOpt.getOpt());
+        boolean found = false;
+        for (Iterator<IteratorSetting> iter = iterSettings.iterator(); iter.hasNext();) {
+          if (iter.next().getName().equals(name)) {
+            iter.remove();
+            found = true;
+            break;
+          }
+        }
+        if (!found) {
+          Shell.log.info("No iterator named " + name + " found");
+        } else {
+          Shell.log.info("Removed iterator " + name + " from profile " + profile + " (" + iterSettings.size() + " left)");
+        }
+      }
+      
+    } else {
+      Shell.log.info("No profile named " + profile);
+    }
+    
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "deletes iterators profiles configured in this shell session";
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+    
+    OptionGroup nameGroup = new OptionGroup();
+    
+    nameOpt = new Option("n", "name", true, "iterator to delete");
+    nameOpt.setArgName("itername");
+    
+    allOpt = new Option("a", "all", false, "delete all scan iterators");
+    allOpt.setArgName("all");
+    
+    nameGroup.addOption(nameOpt);
+    nameGroup.addOption(allOpt);
+    nameGroup.setRequired(true);
+    o.addOptionGroup(nameGroup);
+    
+    profileOpt = new Option("pn", "profile", true, "iterator profile name");
+    profileOpt.setRequired(true);
+    profileOpt.setArgName("profile");
+    o.addOption(profileOpt);
+
+    return o;
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteTableCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteTableCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteTableCommand.java
new file mode 100644
index 0000000..827a8ec
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteTableCommand.java
@@ -0,0 +1,60 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import org.apache.accumulo.shell.Shell;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+
+public class DeleteTableCommand extends TableOperation {
+  private Option forceOpt;
+
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    if (cl.hasOption(forceOpt.getOpt())) {
+      super.force();
+    } else {
+      super.noForce();
+    }
+    return super.execute(fullCommand, cl, shellState);
+  }
+
+  @Override
+  public String description() {
+    return "deletes a table";
+  }
+
+  @Override
+  protected void doTableOp(final Shell shellState, final String tableName) throws Exception {
+    shellState.getConnector().tableOperations().delete(tableName);
+    shellState.getReader().println("Table: [" + tableName + "] has been deleted.");
+
+    if (shellState.getTableName().equals(tableName)) {
+      shellState.setTableName("");
+    }
+  }
+
+  @Override
+  public Options getOptions() {
+    forceOpt = new Option("f", "force", false, "force deletion without prompting");
+    final Options opts = super.getOptions();
+
+    opts.addOption(forceOpt);
+    return opts;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteUserCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteUserCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteUserCommand.java
new file mode 100644
index 0000000..22d072a
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteUserCommand.java
@@ -0,0 +1,19 @@
+/*
+ * 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.accumulo.shell.commands;
+
+public class DeleteUserCommand extends DropUserCommand {}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/DropTableCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/DropTableCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/DropTableCommand.java
new file mode 100644
index 0000000..45b40dd
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/DropTableCommand.java
@@ -0,0 +1,19 @@
+/*
+ * 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.accumulo.shell.commands;
+
+public class DropTableCommand extends DeleteTableCommand {}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/DropUserCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/DropUserCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/DropUserCommand.java
new file mode 100644
index 0000000..7de216d
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/DropUserCommand.java
@@ -0,0 +1,61 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.util.BadArgumentException;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Token;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+
+public class DropUserCommand extends Command {
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException {
+    final String user = cl.getArgs()[0];
+    if (shellState.getConnector().whoami().equals(user)) {
+      throw new BadArgumentException("You cannot delete yourself", fullCommand, fullCommand.indexOf(user));
+    }
+    shellState.getConnector().securityOperations().dropLocalUser(user);
+    Shell.log.debug("Deleted user " + user);
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "deletes a user";
+  }
+  
+  @Override
+  public String usage() {
+    return getName() + " <username>";
+  }
+  
+  @Override
+  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> completionSet) {
+    registerCompletionForUsers(root, completionSet);
+  }
+  
+  @Override
+  public int numArgs() {
+    return 1;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/EGrepCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/EGrepCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/EGrepCommand.java
new file mode 100644
index 0000000..958f5eb
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/EGrepCommand.java
@@ -0,0 +1,59 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.io.IOException;
+
+import org.apache.accumulo.core.client.BatchScanner;
+import org.apache.accumulo.core.client.IteratorSetting;
+import org.apache.accumulo.core.iterators.user.RegExFilter;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+
+public class EGrepCommand extends GrepCommand {
+  
+  private Option matchSubstringOption;
+  
+  @Override
+  protected void setUpIterator(final int prio, final String name, final String term, final BatchScanner scanner, CommandLine cl) throws IOException {
+    if (prio < 0) {
+      throw new IllegalArgumentException("Priority < 0 " + prio);
+    }
+    final IteratorSetting si = new IteratorSetting(prio, name, RegExFilter.class);
+    RegExFilter.setRegexs(si, term, term, term, term, true, cl.hasOption(matchSubstringOption.getOpt()));
+    scanner.addScanIterator(si);
+  }
+  
+  @Override
+  public String description() {
+    return "searches each row, column family, column qualifier and value, in parallel, on the server side (using a java Matcher, so put .* before and after your term if you're not matching the whole element)";
+  }
+  
+  @Override
+  public String usage() {
+    return getName() + " <regex>{ <regex>}";
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options opts = super.getOptions();
+    matchSubstringOption = new Option("g", "global", false, "forces the use of the find() expression matcher, causing substring matches to return true");
+    opts.addOption(matchSubstringOption);
+    return opts;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/ExecfileCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/ExecfileCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/ExecfileCommand.java
new file mode 100644
index 0000000..b384d5c
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/ExecfileCommand.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.accumulo.shell.commands;
+
+import java.io.File;
+import java.nio.charset.StandardCharsets;
+import java.util.Scanner;
+
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+
+public class ExecfileCommand extends Command {
+  private Option verboseOption;
+  
+  @Override
+  public String description() {
+    return "specifies a file containing accumulo commands to execute";
+  }
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    Scanner scanner = new Scanner(new File(cl.getArgs()[0]), StandardCharsets.UTF_8.name());
+    try {
+      while (scanner.hasNextLine()) {
+        shellState.execCommand(scanner.nextLine(), true, cl.hasOption(verboseOption.getOpt()));
+      }
+    } finally {
+      scanner.close();
+    }
+    return 0;
+  }
+  
+  @Override
+  public String usage() {
+    return getName() + " <fileName>";
+  }
+  
+  @Override
+  public int numArgs() {
+    return 1;
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options opts = new Options();
+    verboseOption = new Option("v", "verbose", false, "display command prompt as commands are executed");
+    opts.addOption(verboseOption);
+    return opts;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/ExitCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/ExitCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/ExitCommand.java
new file mode 100644
index 0000000..1d44409
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/ExitCommand.java
@@ -0,0 +1,39 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+
+public class ExitCommand extends Command {
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) {
+    shellState.setExit(true);
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "exits the shell";
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/ExportTableCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/ExportTableCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/ExportTableCommand.java
new file mode 100644
index 0000000..d8d358c
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/ExportTableCommand.java
@@ -0,0 +1,78 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.TableExistsException;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Token;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+
+public class ExportTableCommand extends Command {
+  
+  private Option tableOpt;
+
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException, TableNotFoundException,
+      TableExistsException {
+    
+    final String tableName = OptUtil.getTableOpt(cl, shellState);
+
+    shellState.getConnector().tableOperations().exportTable(tableName, cl.getArgs()[0]);
+    return 0;
+  }
+  
+  @Override
+  public String usage() {
+    return getName() + " <export dir>";
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+    
+    tableOpt = new Option(Shell.tableOption, "table", true, "table to export");
+    
+    tableOpt.setArgName("table");
+    
+    o.addOption(tableOpt);
+
+    return o;
+  }
+  
+  @Override
+  public String description() {
+    return "exports a table";
+  }
+  
+  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> completionSet) {
+    registerCompletionForTables(root, completionSet);
+  }
+  
+  @Override
+  public int numArgs() {
+    return 1;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/ExtensionCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/ExtensionCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/ExtensionCommand.java
new file mode 100644
index 0000000..fbc1833
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/ExtensionCommand.java
@@ -0,0 +1,102 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.util.HashSet;
+import java.util.ServiceLoader;
+import java.util.Set;
+import java.util.TreeSet;
+
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.ShellExtension;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+
+public class ExtensionCommand extends Command {
+  
+  protected Option enable, disable, list;
+  
+  private static ServiceLoader<ShellExtension> extensions = null;
+  
+  private Set<String> loadedHeaders = new HashSet<String>();
+  private Set<String> loadedCommands = new HashSet<String>();
+  private Set<String> loadedExtensions = new TreeSet<String>();
+  
+  public int execute(String fullCommand, CommandLine cl, Shell shellState) throws Exception {
+    if (cl.hasOption(enable.getOpt())) {
+      extensions = ServiceLoader.load(ShellExtension.class);
+      for (ShellExtension se : extensions) {
+        
+        loadedExtensions.add(se.getExtensionName());
+        String header = "-- " + se.getExtensionName() + " Extension Commands ---------";
+        loadedHeaders.add(header);
+        shellState.commandGrouping.put(header, se.getCommands());
+        
+        for (Command cmd : se.getCommands()) {
+          String name = se.getExtensionName() + "::" + cmd.getName();
+          loadedCommands.add(name);
+          shellState.commandFactory.put(name, cmd);
+        }
+      }
+    } else if (cl.hasOption(disable.getOpt())) {
+      //Remove the headers
+      for (String header : loadedHeaders) {
+        shellState.commandGrouping.remove(header);
+      }
+      //remove the commands
+      for (String name : loadedCommands) {
+        shellState.commandFactory.remove(name);
+      }
+      //Reset state
+      loadedExtensions.clear();
+      extensions.reload();
+    } else if (cl.hasOption(list.getOpt())) {
+      shellState.printLines(loadedExtensions.iterator(), true);
+    } else {
+      printHelp(shellState);
+    }
+    return 0;
+  }
+  
+  public String description() {
+    return "Enable, disable, or list shell extensions";
+  }
+  
+  public int numArgs() {
+    return 0;
+  }
+  
+  @Override
+  public String getName() {
+    return "extensions";
+  }
+
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+    enable = new Option("e", "enable", false, "enable shell extensions");
+    disable = new Option("d", "disable", false, "disable shell extensions");
+    list = new Option("l", "list", false, "list shell extensions");
+    o.addOption(enable);
+    o.addOption(disable);
+    o.addOption(list);
+    return o;
+  }
+    
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/FateCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/FateCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/FateCommand.java
new file mode 100644
index 0000000..eae1ec8
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/FateCommand.java
@@ -0,0 +1,180 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.Formatter;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.accumulo.core.Constants;
+import org.apache.accumulo.core.client.Instance;
+import org.apache.accumulo.core.conf.AccumuloConfiguration;
+import org.apache.accumulo.core.conf.Property;
+import org.apache.accumulo.core.zookeeper.ZooUtil;
+import org.apache.accumulo.fate.AdminUtil;
+import org.apache.accumulo.fate.ReadOnlyTStore.TStatus;
+import org.apache.accumulo.fate.ZooStore;
+import org.apache.accumulo.fate.zookeeper.IZooReaderWriter;
+import org.apache.accumulo.fate.zookeeper.ZooReaderWriter;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+import org.apache.commons.cli.ParseException;
+import org.apache.zookeeper.KeeperException;
+
+/**
+ * Manage FATE transactions
+ * 
+ */
+public class FateCommand extends Command {
+  
+  private static final String SCHEME = "digest";
+  
+  private static final String USER = "accumulo";
+  
+  private Option secretOption;
+  private Option statusOption;
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws ParseException, KeeperException, InterruptedException,
+      IOException {
+    Instance instance = shellState.getInstance();
+    String[] args = cl.getArgs();
+    if (args.length <= 0) {
+      throw new ParseException("Must provide a command to execute");
+    }
+    String cmd = args[0];
+    boolean failedCommand = false;
+    
+    AdminUtil<FateCommand> admin = new AdminUtil<FateCommand>(false);
+    
+    String path = ZooUtil.getRoot(instance) + Constants.ZFATE;
+    String masterPath = ZooUtil.getRoot(instance) + Constants.ZMASTER_LOCK;
+    IZooReaderWriter zk = getZooReaderWriter(shellState.getInstance(), cl.getOptionValue(secretOption.getOpt()));
+    ZooStore<FateCommand> zs = new ZooStore<FateCommand>(path, zk);
+    
+    if ("fail".equals(cmd)) {
+      if (args.length <= 1) {
+        throw new ParseException("Must provide transaction ID");
+      }
+      for (int i = 1; i < args.length; i++) {
+        if (!admin.prepFail(zs, zk, masterPath, args[i])) {
+          System.out.printf("Could not fail transaction: %s%n", args[i]);
+          failedCommand = true;
+        }
+      }
+    } else if ("delete".equals(cmd)) {
+      if (args.length <= 1) {
+        throw new ParseException("Must provide transaction ID");
+      }
+      for (int i = 1; i < args.length; i++) {
+        if (admin.prepDelete(zs, zk, masterPath, args[i])) {
+          admin.deleteLocks(zs, zk, ZooUtil.getRoot(instance) + Constants.ZTABLE_LOCKS, args[i]);
+        } else {
+          System.out.printf("Could not delete transaction: %s%n", args[i]);
+          failedCommand = true;
+        }
+      }
+    } else if ("list".equals(cmd) || "print".equals(cmd)) {
+      // Parse transaction ID filters for print display
+      Set<Long> filterTxid = null;
+      if (args.length >= 2) {
+        filterTxid = new HashSet<Long>(args.length);
+        for (int i = 1; i < args.length; i++) {
+          try {
+            Long val = Long.parseLong(args[i], 16);
+            filterTxid.add(val);
+          } catch (NumberFormatException nfe) {
+            // Failed to parse, will exit instead of displaying everything since the intention was to potentially filter some data
+            System.out.printf("Invalid transaction ID format: %s%n", args[i]);
+            return 1;
+          }
+        }
+      }
+      
+      // Parse TStatus filters for print display
+      EnumSet<TStatus> filterStatus = null;
+      if (cl.hasOption(statusOption.getOpt())) {
+        filterStatus = EnumSet.noneOf(TStatus.class);
+        String[] tstat = cl.getOptionValues(statusOption.getOpt());
+        for (int i = 0; i < tstat.length; i++) {
+          try {
+            filterStatus.add(TStatus.valueOf(tstat[i]));
+          } catch (IllegalArgumentException iae) {
+            System.out.printf("Invalid transaction status name: %s%n", tstat[i]);
+            return 1;
+          }
+        }
+      }
+      
+      StringBuilder buf = new StringBuilder(8096);
+      Formatter fmt = new Formatter(buf);
+      admin.print(zs, zk, ZooUtil.getRoot(instance) + Constants.ZTABLE_LOCKS, fmt, filterTxid, filterStatus);
+      shellState.printLines(Collections.singletonList(buf.toString()).iterator(), true);
+    } else {
+      throw new ParseException("Invalid command option");
+    }
+    
+    return failedCommand ? 1 : 0;
+  }
+  
+  protected synchronized IZooReaderWriter getZooReaderWriter(Instance instance, String secret) {
+    
+    if (secret == null) {
+      @SuppressWarnings("deprecation")
+      AccumuloConfiguration conf = AccumuloConfiguration.getSiteConfiguration();
+      secret = conf.get(Property.INSTANCE_SECRET);
+    }
+    
+    return new ZooReaderWriter(instance.getZooKeepers(), instance.getZooKeepersSessionTimeOut(), SCHEME, (USER + ":" + secret).getBytes());
+  }
+  
+  @Override
+  public String description() {
+    return "manage FATE transactions";
+  }
+  
+  @Override
+  public String usage() {
+    return getName() + " fail <txid>... | delete <txid>... | print [<txid>...]";
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+    secretOption = new Option("s", "secret", true, "specify the instance secret to use");
+    secretOption.setOptionalArg(false);
+    o.addOption(secretOption);
+    statusOption = new Option("t", "status-type", true,
+        "filter 'print' on the transaction status type(s) {NEW, IN_PROGRESS, FAILED_IN_PROGRESS, FAILED, SUCCESSFUL}");
+    statusOption.setArgs(Option.UNLIMITED_VALUES);
+    statusOption.setOptionalArg(false);
+    o.addOption(statusOption);
+    return o;
+  }
+  
+  @Override
+  public int numArgs() {
+    // Arg length varies between 1 to n
+    return -1;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/FlushCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/FlushCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/FlushCommand.java
new file mode 100644
index 0000000..34e22a5
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/FlushCommand.java
@@ -0,0 +1,63 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.shell.Shell;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+import org.apache.hadoop.io.Text;
+
+public class FlushCommand extends TableOperation {
+  private Text startRow;
+  private Text endRow;
+  
+  private boolean wait;
+  private Option waitOpt;
+  
+  @Override
+  public String description() {
+    return "flushes a tables data that is currently in memory to disk";
+  }
+  
+  protected void doTableOp(final Shell shellState, final String tableName) throws AccumuloException, AccumuloSecurityException, TableNotFoundException {
+    shellState.getConnector().tableOperations().flush(tableName, startRow, endRow, wait);
+    Shell.log.info("Flush of table " + tableName + (wait ? " completed." : " initiated..."));
+  }
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    wait = cl.hasOption(waitOpt.getLongOpt());
+    startRow = OptUtil.getStartRow(cl);
+    endRow = OptUtil.getEndRow(cl);
+    return super.execute(fullCommand, cl, shellState);
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options opts = super.getOptions();
+    waitOpt = new Option("w", "wait", false, "wait for flush to finish");
+    opts.addOption(waitOpt);
+    opts.addOption(OptUtil.startRowOpt());
+    opts.addOption(OptUtil.endRowOpt());
+    
+    return opts;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/FormatterCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/FormatterCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/FormatterCommand.java
new file mode 100644
index 0000000..e416699
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/FormatterCommand.java
@@ -0,0 +1,69 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.conf.Property;
+import org.apache.accumulo.core.util.format.Formatter;
+import org.apache.accumulo.shell.Shell;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+
+public class FormatterCommand extends ShellPluginConfigurationCommand {
+  
+  private Option interpeterOption;
+
+  public FormatterCommand() {
+    super("formatter", Property.TABLE_FORMATTER_CLASS, "f");
+  }
+
+  @Override
+  public String description() {
+    return "specifies a formatter to use for displaying table entries";
+  }
+
+  public static Class<? extends Formatter> getCurrentFormatter(final String tableName, final Shell shellState) {
+    return ShellPluginConfigurationCommand.getPluginClass(tableName, shellState, Formatter.class, Property.TABLE_FORMATTER_CLASS);
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options options = super.getOptions();
+    
+    interpeterOption = new Option("i", "interpeter", false, "configure class as interpreter also");
+    
+    options.addOption(interpeterOption);
+    
+    return options;
+  }
+  
+  protected void setPlugin(final CommandLine cl, final Shell shellState, final String tableName, final String className) throws AccumuloException, AccumuloSecurityException {
+    super.setPlugin(cl, shellState, tableName, className);
+    if (cl.hasOption(interpeterOption.getOpt())) {
+      shellState.getConnector().tableOperations().setProperty(tableName, Property.TABLE_INTERPRETER_CLASS.toString(), className);
+    }
+  }
+  
+  protected void removePlugin(final CommandLine cl, final Shell shellState, final String tableName) throws AccumuloException, AccumuloSecurityException {
+    super.removePlugin(cl, shellState, tableName);
+    if (cl.hasOption(interpeterOption.getOpt())) {
+      shellState.getConnector().tableOperations().removeProperty(tableName, Property.TABLE_INTERPRETER_CLASS.toString());
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/GetAuthsCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/GetAuthsCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/GetAuthsCommand.java
new file mode 100644
index 0000000..0156d44
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/GetAuthsCommand.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.accumulo.shell.commands;
+
+import java.io.IOException;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.security.Authorizations;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+import org.apache.commons.lang.StringUtils;
+
+public class GetAuthsCommand extends Command {
+  private Option userOpt;
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException, IOException {
+    final String user = cl.getOptionValue(userOpt.getOpt(), shellState.getConnector().whoami());
+    // Sort authorizations
+    Authorizations auths = shellState.getConnector().securityOperations().getUserAuthorizations(user);
+    SortedSet<String> set = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
+    for (byte[] auth : auths) {
+      set.add(new String(auth));
+    }
+    shellState.getReader().println(StringUtils.join(set, ','));
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "displays the maximum scan authorizations for a user";
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+    userOpt = new Option(Shell.userOption, "user", true, "user to operate on");
+    userOpt.setArgName("user");
+    o.addOption(userOpt);
+    return o;
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/GetGroupsCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/GetGroupsCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/GetGroupsCommand.java
new file mode 100644
index 0000000..6cae7e0
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/GetGroupsCommand.java
@@ -0,0 +1,60 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import org.apache.accumulo.core.util.LocalityGroupUtil;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Options;
+import org.apache.hadoop.io.Text;
+
+public class GetGroupsCommand extends Command {
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    final String tableName = OptUtil.getTableOpt(cl, shellState);
+    
+    final Map<String,Set<Text>> groups = shellState.getConnector().tableOperations().getLocalityGroups(tableName);
+    
+    for (Entry<String,Set<Text>> entry : groups.entrySet()) {
+      shellState.getReader().println(entry.getKey() + "=" + LocalityGroupUtil.encodeColumnFamilies(entry.getValue()));
+    }
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "gets the locality groups for a given table";
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options opts = new Options();
+    opts.addOption(OptUtil.tableOpt("table to fetch locality groups from"));
+    return opts;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/GetSplitsCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/GetSplitsCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/GetSplitsCommand.java
new file mode 100644
index 0000000..f275c39
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/GetSplitsCommand.java
@@ -0,0 +1,155 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.accumulo.shell.commands;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.Iterator;
+import java.util.Map.Entry;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.Scanner;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.core.data.Key;
+import org.apache.accumulo.core.data.KeyExtent;
+import org.apache.accumulo.core.data.Range;
+import org.apache.accumulo.core.data.Value;
+import org.apache.accumulo.core.metadata.MetadataTable;
+import org.apache.accumulo.core.metadata.RootTable;
+import org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection;
+import org.apache.accumulo.core.security.Authorizations;
+import org.apache.accumulo.core.util.TextUtil;
+import org.apache.accumulo.core.util.format.BinaryFormatter;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.accumulo.shell.Shell.PrintFile;
+import org.apache.accumulo.shell.Shell.PrintLine;
+import org.apache.accumulo.shell.Shell.PrintShell;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+import org.apache.commons.codec.binary.Base64;
+import org.apache.hadoop.io.Text;
+
+public class GetSplitsCommand extends Command {
+  
+  private Option outputFileOpt, maxSplitsOpt, base64Opt, verboseOpt;
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws IOException, AccumuloException, AccumuloSecurityException,
+      TableNotFoundException {
+    final String tableName = OptUtil.getTableOpt(cl, shellState);
+    
+    final String outputFile = cl.getOptionValue(outputFileOpt.getOpt());
+    final String m = cl.getOptionValue(maxSplitsOpt.getOpt());
+    final int maxSplits = m == null ? 0 : Integer.parseInt(m);
+    final boolean encode = cl.hasOption(base64Opt.getOpt());
+    final boolean verbose = cl.hasOption(verboseOpt.getOpt());
+    
+    final PrintLine p = outputFile == null ? new PrintShell(shellState.getReader()) : new PrintFile(outputFile);
+    
+    try {
+      if (!verbose) {
+        for (Text row : maxSplits > 0 ? shellState.getConnector().tableOperations().listSplits(tableName, maxSplits) : shellState.getConnector()
+            .tableOperations().listSplits(tableName)) {
+          p.print(encode(encode, row));
+        }
+      } else {
+        String systemTableToCheck = MetadataTable.NAME.equals(tableName) ? RootTable.NAME : MetadataTable.NAME;
+        final Scanner scanner = shellState.getConnector().createScanner(systemTableToCheck, Authorizations.EMPTY);
+        TabletsSection.TabletColumnFamily.PREV_ROW_COLUMN.fetch(scanner);
+        final Text start = new Text(shellState.getConnector().tableOperations().tableIdMap().get(tableName));
+        final Text end = new Text(start);
+        end.append(new byte[] {'<'}, 0, 1);
+        scanner.setRange(new Range(start, end));
+        for (Iterator<Entry<Key,Value>> iterator = scanner.iterator(); iterator.hasNext();) {
+          final Entry<Key,Value> next = iterator.next();
+          if (TabletsSection.TabletColumnFamily.PREV_ROW_COLUMN.hasColumns(next.getKey())) {
+            KeyExtent extent = new KeyExtent(next.getKey().getRow(), next.getValue());
+            final String pr = encode(encode, extent.getPrevEndRow());
+            final String er = encode(encode, extent.getEndRow());
+            final String line = String.format("%-26s (%s, %s%s", obscuredTabletName(extent), pr == null ? "-inf" : pr, er == null ? "+inf" : er,
+                er == null ? ") Default Tablet " : "]");
+            p.print(line);
+          }
+        }
+      }
+      
+    } finally {
+      p.close();
+    }
+    
+    return 0;
+  }
+  
+  private static String encode(final boolean encode, final Text text) {
+    if (text == null) {
+      return null;
+    }
+    BinaryFormatter.getlength(text.getLength());
+    return encode ? new String(Base64.encodeBase64(TextUtil.getBytes(text)), StandardCharsets.UTF_8) : BinaryFormatter.appendText(new StringBuilder(), text).toString();
+  }
+  
+  private static String obscuredTabletName(final KeyExtent extent) {
+    MessageDigest digester;
+    try {
+      digester = MessageDigest.getInstance("MD5");
+    } catch (NoSuchAlgorithmException e) {
+      throw new RuntimeException(e);
+    }
+    if (extent.getEndRow() != null && extent.getEndRow().getLength() > 0) {
+      digester.update(extent.getEndRow().getBytes(), 0, extent.getEndRow().getLength());
+    }
+    return new String(Base64.encodeBase64(digester.digest()), StandardCharsets.UTF_8);
+  }
+  
+  @Override
+  public String description() {
+    return "retrieves the current split points for tablets in the current table";
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options opts = new Options();
+    
+    outputFileOpt = new Option("o", "output", true, "local file to write the splits to");
+    outputFileOpt.setArgName("file");
+    
+    maxSplitsOpt = new Option("m", "max", true, "maximum number of splits to return (evenly spaced)");
+    maxSplitsOpt.setArgName("num");
+    
+    base64Opt = new Option("b64", "base64encoded", false, "encode the split points");
+    
+    verboseOpt = new Option("v", "verbose", false, "print out the tablet information with start/end rows");
+    
+    opts.addOption(outputFileOpt);
+    opts.addOption(maxSplitsOpt);
+    opts.addOption(base64Opt);
+    opts.addOption(verboseOpt);
+    opts.addOption(OptUtil.tableOpt("table to get splits for"));
+    
+    return opts;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/GrantCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/GrantCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/GrantCommand.java
new file mode 100644
index 0000000..8f4448f
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/GrantCommand.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.accumulo.shell.commands;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.accumulo.core.security.NamespacePermission;
+import org.apache.accumulo.core.security.SystemPermission;
+import org.apache.accumulo.core.security.TablePermission;
+import org.apache.accumulo.core.util.BadArgumentException;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Token;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.OptionGroup;
+import org.apache.commons.cli.Options;
+
+public class GrantCommand extends TableOperation {
+  {
+    disableUnflaggedTableOptions();
+  }
+
+  private Option systemOpt, userOpt;
+  private String user;
+  private String[] permission;
+
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    user = cl.hasOption(userOpt.getOpt()) ? cl.getOptionValue(userOpt.getOpt()) : shellState.getConnector().whoami();
+
+    permission = cl.getArgs()[0].split("\\.", 2);
+    if (cl.hasOption(systemOpt.getOpt()) && permission[0].equalsIgnoreCase("System")) {
+      try {
+        shellState.getConnector().securityOperations().grantSystemPermission(user, SystemPermission.valueOf(permission[1]));
+        Shell.log.debug("Granted " + user + " the " + permission[1] + " permission");
+      } catch (IllegalArgumentException e) {
+        throw new BadArgumentException("No such system permission", fullCommand, fullCommand.indexOf(cl.getArgs()[0]));
+      }
+    } else if (permission[0].equalsIgnoreCase("Table")) {
+      super.execute(fullCommand, cl, shellState);
+    } else if (permission[0].equalsIgnoreCase("Namespace")) {
+      if (cl.hasOption(optNamespace.getOpt())) {
+        try {
+          shellState.getConnector().securityOperations()
+              .grantNamespacePermission(user, cl.getOptionValue(optNamespace.getOpt()), NamespacePermission.valueOf(permission[1]));
+        } catch (IllegalArgumentException e) {
+          throw new BadArgumentException("No such namespace permission", fullCommand, fullCommand.indexOf(cl.getArgs()[0]));
+        }
+      } else {
+        throw new BadArgumentException("No namespace specified to apply permission to", fullCommand, fullCommand.indexOf(cl.getArgs()[0]));
+      }
+    } else {
+      throw new BadArgumentException("Unrecognized permission", fullCommand, fullCommand.indexOf(cl.getArgs()[0]));
+    }
+    return 0;
+  }
+
+  @Override
+  protected void doTableOp(final Shell shellState, final String tableName) throws Exception {
+    try {
+      shellState.getConnector().securityOperations().grantTablePermission(user, tableName, TablePermission.valueOf(permission[1]));
+      Shell.log.debug("Granted " + user + " the " + permission[1] + " permission on table " + tableName);
+    } catch (IllegalArgumentException e) {
+      throw new IllegalArgumentException("No such table permission", e);
+    }
+  }
+
+  @Override
+  public String description() {
+    return "grants system, table, or namespace permissions for a user";
+  }
+
+  @Override
+  public String usage() {
+    return getName() + " <permission>";
+  }
+
+  @Override
+  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> completionSet) {
+    final Token cmd = new Token(getName());
+    cmd.addSubcommand(new Token(TablePermission.printableValues()));
+    cmd.addSubcommand(new Token(SystemPermission.printableValues()));
+    cmd.addSubcommand(new Token(NamespacePermission.printableValues()));
+    root.addSubcommand(cmd);
+  }
+
+  @Override
+  public Options getOptions() {
+    super.getOptions();
+    final Options o = new Options();
+
+    final OptionGroup group = new OptionGroup();
+
+    systemOpt = new Option("s", "system", false, "grant a system permission");
+
+    optNamespace = new Option(Shell.namespaceOption, "namespace", true, "name of a namespace to operate on");
+    optNamespace.setArgName("namespace");
+
+    group.addOption(systemOpt);
+    group.addOption(optTableName);
+    group.addOption(optTablePattern);
+    group.addOption(optNamespace);
+
+    o.addOptionGroup(group);
+    userOpt = new Option(Shell.userOption, "user", true, "user to operate on");
+    userOpt.setArgName("username");
+    userOpt.setRequired(true);
+    o.addOption(userOpt);
+
+    return o;
+  }
+
+  @Override
+  public int numArgs() {
+    return 1;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/GrepCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/GrepCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/GrepCommand.java
new file mode 100644
index 0000000..1a3c484
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/GrepCommand.java
@@ -0,0 +1,111 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.accumulo.core.client.BatchScanner;
+import org.apache.accumulo.core.client.IteratorSetting;
+import org.apache.accumulo.core.iterators.user.GrepIterator;
+import org.apache.accumulo.core.security.Authorizations;
+import org.apache.accumulo.core.util.format.Formatter;
+import org.apache.accumulo.core.util.interpret.ScanInterpreter;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.PrintFile;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.MissingArgumentException;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+
+public class GrepCommand extends ScanCommand {
+  
+  private Option numThreadsOpt;
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    final PrintFile printFile = getOutputFile(cl);
+    
+    final String tableName = OptUtil.getTableOpt(cl, shellState);
+    
+    if (cl.getArgList().isEmpty()) {
+      throw new MissingArgumentException("No terms specified");
+    }
+    final Class<? extends Formatter> formatter = getFormatter(cl, tableName, shellState);
+    final ScanInterpreter interpeter = getInterpreter(cl, tableName, shellState);
+    
+    // handle first argument, if present, the authorizations list to
+    // scan with
+    int numThreads = 20;
+    if (cl.hasOption(numThreadsOpt.getOpt())) {
+      numThreads = Integer.parseInt(cl.getOptionValue(numThreadsOpt.getOpt()));
+    }
+    final Authorizations auths = getAuths(cl, shellState);
+    final BatchScanner scanner = shellState.getConnector().createBatchScanner(tableName, auths, numThreads);
+    scanner.setRanges(Collections.singletonList(getRange(cl, interpeter)));
+    
+    scanner.setTimeout(getTimeout(cl), TimeUnit.MILLISECONDS);
+    
+    for (int i = 0; i < cl.getArgs().length; i++) {
+      setUpIterator(Integer.MAX_VALUE - cl.getArgs().length + i, "grep" + i, cl.getArgs()[i], scanner, cl);
+    }
+    try {
+      // handle columns
+      fetchColumns(cl, scanner, interpeter);
+      
+      // output the records
+      printRecords(cl, shellState, scanner, formatter, printFile);
+    } finally {
+      scanner.close();
+    }
+    
+    return 0;
+  }
+  
+  protected void setUpIterator(final int prio, final String name, final String term, final BatchScanner scanner, CommandLine cl) throws IOException {
+    if (prio < 0) {
+      throw new IllegalArgumentException("Priority < 0 " + prio);
+    }
+    final IteratorSetting grep = new IteratorSetting(prio, name, GrepIterator.class);
+    GrepIterator.setTerm(grep, term);
+    scanner.addScanIterator(grep);
+  }
+  
+  @Override
+  public String description() {
+    return "searches each row, column family, column qualifier and value in a table for a substring (not a regular expression), in parallel, on the server side";
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options opts = super.getOptions();
+    numThreadsOpt = new Option("nt", "num-threads", true, "number of threads to use");
+    opts.addOption(numThreadsOpt);
+    return opts;
+  }
+  
+  @Override
+  public String usage() {
+    return getName() + " <term>{ <term>}";
+  }
+  
+  @Override
+  public int numArgs() {
+    return Shell.NO_FIXED_ARG_LENGTH_CHECK;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/HelpCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/HelpCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/HelpCommand.java
new file mode 100644
index 0000000..90e8c4f
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/HelpCommand.java
@@ -0,0 +1,129 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.ShellCommandException;
+import org.apache.accumulo.shell.Token;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+
+public class HelpCommand extends Command {
+  private Option disablePaginationOpt;
+  private Option noWrapOpt;
+  
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws ShellCommandException, IOException {
+    int numColumns = shellState.getReader().getTerminal().getWidth();
+    if (cl.hasOption(noWrapOpt.getOpt())) {
+      numColumns = Integer.MAX_VALUE;
+    }
+    // print help summary
+    if (cl.getArgs().length == 0) {
+      int i = 0;
+      for (String cmd : shellState.commandFactory.keySet()) {
+        i = Math.max(i, cmd.length());
+      }
+      if (numColumns < 40) {
+        throw new IllegalArgumentException("numColumns must be at least 40 (was " + numColumns + ")");
+      }
+      final ArrayList<String> output = new ArrayList<String>();
+      for (Entry<String,Command[]> cmdGroup : shellState.commandGrouping.entrySet()) {
+        output.add(cmdGroup.getKey());
+        for (Command c : cmdGroup.getValue()) {
+          String n = c.getName();
+          String s = c.description();
+          if (s == null) {
+            s = "";
+          }
+          int beginIndex = 0;
+          int endIndex = s.length();
+          while (beginIndex < endIndex && s.charAt(beginIndex) == ' ')
+            beginIndex++;
+          String dash = "-";
+          while (endIndex > beginIndex && endIndex - beginIndex + i + 5 > numColumns) {
+            endIndex = s.lastIndexOf(" ", numColumns + beginIndex - i - 5);
+            if (endIndex == -1 || endIndex < beginIndex) {
+              endIndex = numColumns + beginIndex - i - 5 - 1;
+              output.add(String.format("%-" + i + "s  %s  %s-", n, dash, s.substring(beginIndex, endIndex)));
+              dash = " ";
+              beginIndex = endIndex;
+            } else {
+              output.add(String.format("%-" + i + "s  %s  %s", n, dash, s.substring(beginIndex, endIndex)));
+              dash = " ";
+              beginIndex = endIndex + 1;
+            }
+            n = "";
+            endIndex = s.length();
+            while (beginIndex < endIndex && s.charAt(beginIndex) == ' ') {
+              beginIndex++;
+            }
+          }
+          output.add(String.format("%-" + i + "s  %s  %s", n, dash, s.substring(beginIndex, endIndex)));
+        }
+        output.add("");
+      }
+      shellState.printLines(output.iterator(), !cl.hasOption(disablePaginationOpt.getOpt()));
+    }
+    
+    // print help for every command on command line
+    for (String cmd : cl.getArgs()) {
+      final Command c = shellState.commandFactory.get(cmd);
+      if (c == null) {
+        shellState.getReader().println(String.format("Unknown command \"%s\".  Enter \"help\" for a list possible commands.", cmd));
+      } else {
+        c.printHelp(shellState, numColumns);
+      }
+    }
+    return 0;
+  }
+  
+  public String description() {
+    return "provides information about the available commands";
+  }
+  
+  public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> special) {
+    registerCompletionForCommands(root, special);
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+    disablePaginationOpt = new Option("np", "no-pagination", false, "disable pagination of output");
+    o.addOption(disablePaginationOpt);
+    noWrapOpt = new Option("nw", "no-wrap", false, "disable wrapping of output");
+    o.addOption(noWrapOpt);
+    return o;
+  }
+  
+  @Override
+  public String usage() {
+    return getName() + " [ <command>{ <command>} ]";
+  }
+  
+  @Override
+  public int numArgs() {
+    return Shell.NO_FIXED_ARG_LENGTH_CHECK;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/HiddenCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/HiddenCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/HiddenCommand.java
new file mode 100644
index 0000000..824517d
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/HiddenCommand.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.accumulo.shell.commands;
+
+import java.nio.charset.StandardCharsets;
+import java.security.SecureRandom;
+import java.util.Random;
+
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.ShellCommandException;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.accumulo.shell.ShellCommandException.ErrorCode;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.codec.binary.Base64;
+
+public class HiddenCommand extends Command {
+  private static Random rand = new SecureRandom();
+  
+  @Override
+  public String description() {
+    return "The first rule of Accumulo is: \"You don't talk about Accumulo.\"";
+  }
+  
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+    if (rand.nextInt(10) == 0) {
+      shellState.getReader().beep();
+      shellState.getReader().println();
+      shellState.getReader().println(
+          new String(Base64.decodeBase64(("ICAgICAgIC4tLS4KICAgICAgLyAvXCBcCiAgICAgKCAvLS1cICkKICAgICAuPl8gIF88LgogICAgLyB8ICd8ICcgXAog"
+              + "ICAvICB8Xy58Xy4gIFwKICAvIC98ICAgICAgfFwgXAogfCB8IHwgfFwvfCB8IHwgfAogfF98IHwgfCAgfCB8IHxffAogICAgIC8gIF9fICBcCiAgICAvICAv"
+              + "ICBcICBcCiAgIC8gIC8gICAgXCAgXF8KIHwvICAvICAgICAgXCB8IHwKIHxfXy8gICAgICAgIFx8X3wK").getBytes(StandardCharsets.UTF_8)), StandardCharsets.UTF_8));
+    } else {
+      throw new ShellCommandException(ErrorCode.UNRECOGNIZED_COMMAND, getName());
+    }
+    return 0;
+  }
+  
+  @Override
+  public int numArgs() {
+    return Shell.NO_FIXED_ARG_LENGTH_CHECK;
+  }
+  
+  @Override
+  public String getName() {
+    return "accvmvlo";
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/066043d4/shell/src/main/java/org/apache/accumulo/shell/commands/HistoryCommand.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/HistoryCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/HistoryCommand.java
new file mode 100644
index 0000000..1c1314a
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/HistoryCommand.java
@@ -0,0 +1,82 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.ListIterator;
+
+import jline.console.history.History.Entry;
+
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+import org.apache.commons.collections.iterators.AbstractIteratorDecorator;
+
+public class HistoryCommand extends Command {
+  private Option clearHist;
+  private Option disablePaginationOpt;
+  
+  @SuppressWarnings("unchecked")
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws IOException {
+    if (cl.hasOption(clearHist.getOpt())) {
+      shellState.getReader().getHistory().clear();
+    } else {
+      ListIterator<Entry> it = shellState.getReader().getHistory().entries();
+      shellState.printLines(new HistoryLineIterator(it), !cl.hasOption(disablePaginationOpt.getOpt()));
+    }
+    
+    return 0;
+  }
+  
+  /**
+   * Decorator that converts an Iterator<History.Entry> to an Iterator<String>.
+   */
+  private static class HistoryLineIterator extends AbstractIteratorDecorator {
+    public HistoryLineIterator(Iterator<Entry> iterator) {
+      super(iterator);
+    }
+    
+    @Override
+    public String next() {
+      return super.next().toString();
+    }
+  }
+  
+  @Override
+  public String description() {
+    return ("generates a list of commands previously executed");
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+  
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+    clearHist = new Option("c", "clear", false, "clear history file");
+    o.addOption(clearHist);
+    disablePaginationOpt = new Option("np", "no-pagination", false, "disable pagination of output");
+    o.addOption(disablePaginationOpt);
+    return o;
+  }
+}