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:03:34 UTC

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

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;
+  }
+  
+}