You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@accumulo.apache.org by ct...@apache.org on 2014/03/27 20:07:57 UTC

[3/4] git commit: ACCUMULO-1517 Generate LaTeX appendix for config

ACCUMULO-1517 Generate LaTeX appendix for config

Includes improvements to user manual in many areas, where text was too wide for
the page. Improved some Property.java formatting (mainly line length). Update
version number for user manual. Escape many LaTeX reserved characters, such as
tilde. Fix named anchor bug in html output for HTML5.


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

Branch: refs/heads/master
Commit: 40299f89a3aa6a45101cb993df89c9551529b8dc
Parents: a8572fe
Author: Christopher Tubbs <ct...@apache.org>
Authored: Wed Mar 19 17:19:17 2014 -0400
Committer: Christopher Tubbs <ct...@apache.org>
Committed: Thu Mar 27 14:42:08 2014 -0400

----------------------------------------------------------------------
 .../accumulo/core/conf/ConfigurationDocGen.java | 341 +++++++++++++++++++
 .../core/conf/DefaultConfiguration.java         | 132 +------
 .../org/apache/accumulo/core/conf/Property.java | 140 ++++----
 .../apache/accumulo/core/conf/PropertyType.java |  68 ++--
 .../accumulo/core/conf/config-header.html       |  90 +++++
 .../apache/accumulo/core/conf/config-header.tex |  99 ++++++
 .../org/apache/accumulo/core/conf/config.html   |  90 -----
 .../apache/accumulo/core/conf/PropertyTest.java |  49 +--
 docs/pom.xml                                    |  41 +++
 .../accumulo_user_manual.tex                    |   8 +-
 .../chapters/administration.tex                 |  70 ++--
 .../accumulo_user_manual/chapters/analytics.tex |  88 ++---
 .../accumulo_user_manual/chapters/clients.tex   |  92 ++---
 .../chapters/development_clients.tex            |  44 +--
 .../chapters/high_speed_ingest.tex              |  18 +-
 .../chapters/multivolume.tex                    |  12 +-
 .../accumulo_user_manual/chapters/security.tex  |  30 +-
 .../accumulo_user_manual/chapters/shell.tex     |  43 +--
 .../chapters/table_configuration.tex            | 219 +++++-------
 .../chapters/table_design.tex                   |  60 ++--
 .../chapters/troubleshooting.tex                | 215 ++++++------
 .../impl/MiniAccumuloConfigImpl.java            |   6 +-
 .../accumulo/monitor/servlets/trace/Basic.java  |   2 +-
 .../org/apache/accumulo/tracer/TraceServer.java |  58 ++--
 .../classloader/vfs/AccumuloVFSClassLoader.java | 115 +++----
 25 files changed, 1158 insertions(+), 972 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/accumulo/blob/40299f89/core/src/main/java/org/apache/accumulo/core/conf/ConfigurationDocGen.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/conf/ConfigurationDocGen.java b/core/src/main/java/org/apache/accumulo/core/conf/ConfigurationDocGen.java
new file mode 100644
index 0000000..ca57372
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/conf/ConfigurationDocGen.java
@@ -0,0 +1,341 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.accumulo.core.conf;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.TreeMap;
+
+import org.apache.accumulo.core.Constants;
+import org.apache.log4j.Logger;
+
+/**
+ * This class generates documentation to inform users of the available configuration properties in a presentable form.
+ */
+class ConfigurationDocGen {
+  private abstract class Format {
+
+    abstract void beginSection(String section);
+
+    void endSection() {}
+
+    void generate() {
+      pageHeader();
+
+      beginSection("Available Properties");
+      for (Property prefix : prefixes) {
+        if (!prefix.isExperimental()) {
+          prefixSection(prefix);
+          for (Property prop : sortedProps.values()) {
+            if (!prop.isExperimental()) {
+              property(prefix, prop);
+            }
+          }
+        }
+      }
+      endSection();
+
+      beginSection("Property Types");
+      propertyTypeDescriptions();
+      endSection();
+
+      pageFooter();
+      doc.close();
+    }
+
+    abstract String getExt();
+
+    void pageFooter() {}
+
+    // read static header content from resources and output
+    void pageHeader() {
+      appendResource("config-header." + getExt());
+      doc.println();
+    }
+
+    abstract void prefixSection(Property prefix);
+
+    abstract void property(Property prefix, Property prop);
+
+    abstract void propertyTypeDescriptions();
+
+    abstract String sanitize(String str);
+
+  }
+
+  private class HTML extends Format {
+    private boolean highlight;
+
+    private void beginRow() {
+      doc.println(startTag("tr", highlight ? "class='highlight'" : null));
+      highlight = !highlight;
+    }
+
+    @Override
+    void beginSection(String section) {
+      doc.println(t("h1", section, null));
+      highlight = true;
+      doc.println("<table>");
+    }
+
+    private String t(String tag, String cell, String options) {
+      return startTag(tag, options) + cell + "</" + tag + ">";
+    }
+
+    private void cellData(String cell, String options) {
+      doc.println(t("td", cell, options));
+    }
+
+    private void columnNames(String... names) {
+      beginRow();
+      for (String s : names)
+        doc.println(t("th", s, null));
+      endRow();
+    }
+
+    private void endRow() {
+      doc.println("</tr>");
+    }
+
+    @Override
+    void endSection() {
+      doc.println("</table>");
+    }
+
+    @Override
+    String getExt() {
+      return "html";
+    }
+
+    @Override
+    void pageFooter() {
+      doc.println("</body>");
+      doc.println("</html>");
+    }
+
+    @Override
+    void pageHeader() {
+      super.pageHeader();
+      doc.println("<p>Jump to: ");
+      String delimiter = "";
+      for (Property prefix : prefixes) {
+        if (!prefix.isExperimental()) {
+          doc.print(delimiter + "<a href='#" + prefix.name() + "'>" + prefix.getKey() + "*</a>");
+          delimiter = "&nbsp;|&nbsp;";
+        }
+      }
+      doc.println("</p>");
+    }
+
+    @Override
+    void prefixSection(Property prefix) {
+      beginRow();
+      doc.println(t("td", t("span", prefix.getKey() + '*', "id='" + prefix.name() + "' class='large'"), "colspan='5'"
+          + (prefix.isDeprecated() ? " class='deprecated'" : "")));
+      endRow();
+      beginRow();
+      doc.println(t("td", (prefix.isDeprecated() ? t("b", t("i", "Deprecated. ", null), null) : "") + sanitize(prefix.getDescription()), "colspan='5'"
+          + (prefix.isDeprecated() ? " class='deprecated'" : "")));
+      endRow();
+
+      switch (prefix) {
+        case TABLE_CONSTRAINT_PREFIX:
+          break;
+        case TABLE_ITERATOR_PREFIX:
+          break;
+        case TABLE_LOCALITY_GROUP_PREFIX:
+          break;
+        case TABLE_COMPACTION_STRATEGY_PREFIX:
+          break;
+        default:
+          columnNames("Property", "Type", "ZooKeeper Mutable", "Default Value", "Description");
+          break;
+      }
+    }
+
+    @Override
+    void property(Property prefix, Property prop) {
+      boolean isDeprecated = prefix.isDeprecated() || prop.isDeprecated();
+      if (prop.getKey().startsWith(prefix.getKey())) {
+        beginRow();
+        cellData(prop.getKey(), isDeprecated ? "class='deprecated'" : null);
+        cellData("<b><a href='#" + prop.getType().name() + "'>" + prop.getType().toString().replaceAll(" ", "&nbsp;") + "</a></b>",
+            isDeprecated ? "class='deprecated'" : null);
+        cellData(isZooKeeperMutable(prop), isDeprecated ? "class='deprecated'" : null);
+        cellData("<pre>" + (prop.getRawDefaultValue().isEmpty() ? "&nbsp;" : sanitize(prop.getRawDefaultValue().replaceAll(" ", "&nbsp;"))) + "</pre>",
+            isDeprecated ? "class='deprecated'" : null);
+        cellData((isDeprecated ? "<b><i>Deprecated.</i></b> " : "") + sanitize(prop.getDescription()), isDeprecated ? "class='deprecated'" : null);
+        endRow();
+      }
+
+    }
+
+    @Override
+    void propertyTypeDescriptions() {
+      columnNames("Property Type", "Description");
+      for (PropertyType type : PropertyType.values()) {
+        if (type == PropertyType.PREFIX)
+          continue;
+        beginRow();
+        cellData("<h3 id='" + type.name() + "'>" + type + "</h3>", null);
+        cellData(type.getFormatDescription(), null);
+        endRow();
+      }
+    }
+
+    @Override
+    String sanitize(String str) {
+      return str.replace("&", "&amp;").replace("<", "&lt;").replace(">", "&gt;").replaceAll("(?:\r\n|\r|\n)", "<br />");
+    }
+
+    private String startTag(String tag, String options) {
+      return "<" + tag + (options != null ? " " + options : "") + ">";
+    }
+
+  }
+
+  private class LaTeX extends Format {
+    @Override
+    void beginSection(String section) {
+      doc.println("\\section{" + section + "}");
+    }
+
+    @Override
+    String getExt() {
+      return "tex";
+    }
+
+    @Override
+    void prefixSection(Property prefix) {
+      boolean depr = prefix.isDeprecated();
+      doc.println("\\subsection{" + prefix.getKey() + "*}" + (depr ? " (Deprecated)" : ""));
+      doc.println((depr ? "\\sout{\\textit{Deprecated.} " : "") + sanitize(prefix.getDescription()) + (depr ? "}" : ""));
+      doc.println();
+    }
+
+    @Override
+    void property(Property prefix, Property prop) {
+      boolean depr = prefix.isDeprecated() || prop.isDeprecated();
+      if (prop.getKey().startsWith(prefix.getKey())) {
+        doc.println("\\subsubsection{" + prop.getKey() + "}");
+        doc.println(strike((depr ? "\\textit{Deprecated.} " : "") + sanitize(prop.getDescription()), depr));
+        doc.println();
+        doc.println(strike("\\textit{Type:} " + prop.getType().name() + "\\\\", depr));
+        doc.println(strike("\\textit{ZooKeeper Mutable:} " + isZooKeeperMutable(prop) + "\\\\", depr));
+        doc.println(strike("\\textit{Default Value:} " + sanitize(prop.getRawDefaultValue()), depr));
+        doc.println();
+      }
+    }
+
+    private String strike(String s, boolean isDeprecated) {
+      return (isDeprecated ? "\\sout{" : "") + s + (isDeprecated ? "}" : "");
+    }
+
+    @Override
+    void propertyTypeDescriptions() {
+      for (PropertyType type : PropertyType.values()) {
+        if (type == PropertyType.PREFIX)
+          continue;
+        doc.println("\\subsection{" + sanitize(type.toString()) + "}");
+        doc.println(sanitize(type.getFormatDescription()));
+        doc.println();
+      }
+    }
+
+    @Override
+    String sanitize(String str) {
+      str = str.replace("\\", "\\textbackslash{}");
+      str = str.replace("~", "\\textasciitilde{}");
+      str = str.replace("^", "\\textasciicircum");
+
+      str = str.replace("&", "\\&");
+      str = str.replace("%", "\\%");
+      str = str.replace("$", "\\$");
+      str = str.replace("#", "\\#");
+      str = str.replace("_", "\\_");
+      str = str.replace("{", "\\{");
+      str = str.replace("}", "\\}");
+
+      str = str.replaceAll("(?:\r\n|\r|\n)", "\\\\\\\\\n");
+      return str;
+    }
+  }
+
+  private static Logger log = Logger.getLogger(DefaultConfiguration.class);
+
+  private PrintStream doc;
+
+  private final ArrayList<Property> prefixes;
+
+  private final TreeMap<String,Property> sortedProps;
+
+  ConfigurationDocGen(PrintStream doc) {
+    this.doc = doc;
+    this.prefixes = new ArrayList<Property>();
+    this.sortedProps = new TreeMap<String,Property>();
+
+    for (Property prop : Property.values()) {
+      if (prop.isExperimental())
+        continue;
+
+      if (prop.getType() == PropertyType.PREFIX)
+        this.prefixes.add(prop);
+      else
+        this.sortedProps.put(prop.getKey(), prop);
+    }
+  }
+
+  private void appendResource(String resourceName) {
+    InputStream data = DefaultConfiguration.class.getResourceAsStream(resourceName);
+    if (data != null) {
+      byte[] buffer = new byte[1024];
+      int n;
+      try {
+        while ((n = data.read(buffer)) > 0)
+          doc.print(new String(buffer, 0, n, Constants.UTF8));
+      } catch (IOException e) {
+        e.printStackTrace();
+        return;
+      } finally {
+        try {
+          data.close();
+        } catch (IOException ex) {
+          log.error(ex, ex);
+        }
+      }
+    }
+  }
+
+  private String isZooKeeperMutable(Property prop) {
+    if (!Property.isValidZooPropertyKey(prop.getKey()))
+      return "no";
+    if (Property.isFixedZooPropertyKey(prop))
+      return "yes but requires restart of the " + prop.getKey().split("[.]")[0];
+    return "yes";
+  }
+
+  void generateHtml() {
+    new HTML().generate();
+  }
+
+  void generateLaTeX() {
+    new LaTeX().generate();
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/40299f89/core/src/main/java/org/apache/accumulo/core/conf/DefaultConfiguration.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/conf/DefaultConfiguration.java b/core/src/main/java/org/apache/accumulo/core/conf/DefaultConfiguration.java
index cfd2f35..030e88a 100644
--- a/core/src/main/java/org/apache/accumulo/core/conf/DefaultConfiguration.java
+++ b/core/src/main/java/org/apache/accumulo/core/conf/DefaultConfiguration.java
@@ -17,22 +17,16 @@
 package org.apache.accumulo.core.conf;
 
 import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
 import java.io.PrintStream;
 import java.io.UnsupportedEncodingException;
-import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Map.Entry;
-import java.util.TreeMap;
 
 import org.apache.accumulo.core.Constants;
-import org.apache.log4j.Logger;
 
 public class DefaultConfiguration extends AccumuloConfiguration {
   private static DefaultConfiguration instance = null;
-  private static Logger log = Logger.getLogger(DefaultConfiguration.class);
   private Map<String,String> resolvedProps = null;
 
   synchronized public static DefaultConfiguration getInstance() {
@@ -66,123 +60,11 @@ public class DefaultConfiguration extends AccumuloConfiguration {
         props.put(entry.getKey(), entry.getValue());
   }
 
+  /*
+   * Used by the monitor to show configuration properties
+   */
   protected static void generateDocumentation(PrintStream doc) {
-    // read static content from resources and output
-    InputStream data = DefaultConfiguration.class.getResourceAsStream("config.html");
-    if (data != null) {
-      byte[] buffer = new byte[1024];
-      int n;
-      try {
-        while ((n = data.read(buffer)) > 0)
-          doc.print(new String(buffer, 0, n, Constants.UTF8));
-      } catch (IOException e) {
-        e.printStackTrace();
-        return;
-      } finally {
-        try {
-          data.close();
-        } catch (IOException ex) {
-          log.error(ex, ex);
-        }
-      }
-    }
-    doc.println();
-
-    ArrayList<Property> prefixes = new ArrayList<Property>();
-    TreeMap<String,Property> sortedProps = new TreeMap<String,Property>();
-    for (Property prop : Property.values()) {
-      if (prop.isExperimental())
-        continue;
-
-      if (prop.getType().equals(PropertyType.PREFIX))
-        prefixes.add(prop);
-      else
-        sortedProps.put(prop.getKey(), prop);
-    }
-
-    int indentDepth = 2;
-    doc.println(indent(indentDepth++) + "<p>Jump to: ");
-    String delimiter = "";
-    for (Property prefix : prefixes) {
-      if (prefix.isExperimental())
-        continue;
-
-      doc.print(delimiter + "<a href='#" + prefix.name() + "'>" + prefix.getKey() + "*</a>");
-      delimiter = "&nbsp;|&nbsp;";
-    }
-    doc.println(indent(--indentDepth) + "</p>");
-
-    doc.println(indent(indentDepth++) + "<table>");
-    for (Property prefix : prefixes) {
-
-      if (prefix.isExperimental())
-        continue;
-
-      boolean isDeprecated = prefix.isDeprecated();
-
-      doc.println(indent(indentDepth) + "<tr><td colspan='5'" + (isDeprecated ? " class='deprecated'" : "") + "><a id='" + prefix.name() + "' class='large'>"
-          + prefix.getKey() + "*</a></td></tr>");
-      doc.println(indent(indentDepth) + "<tr><td colspan='5'" + (isDeprecated ? " class='deprecated'" : "") + "><i>"
-          + (isDeprecated ? "<b><i>Deprecated.</i></b> " : "") + prefix.getDescription() + "</i></td></tr>");
-      if (!prefix.equals(Property.TABLE_CONSTRAINT_PREFIX) && !prefix.equals(Property.TABLE_ITERATOR_PREFIX)
-          && !prefix.equals(Property.TABLE_LOCALITY_GROUP_PREFIX))
-        doc.println(indent(indentDepth) + "<tr><th>Property</th><th>Type</th><th>Zookeeper Mutable</th><th>Default Value</th><th>Description</th></tr>");
-
-      boolean highlight = true;
-      for (Property prop : sortedProps.values()) {
-        if (prop.isExperimental())
-          continue;
-
-        isDeprecated = prefix.isDeprecated() || prop.isDeprecated();
-
-        if (prop.getKey().startsWith(prefix.getKey())) {
-          doc.println(indent(indentDepth++) + "<tr" + (highlight ? " class='highlight'" : "") + ">");
-          highlight = !highlight;
-          doc.println(indent(indentDepth) + "<td" + (isDeprecated ? " class='deprecated'" : "") + ">" + prop.getKey() + "</td>");
-          doc.println(indent(indentDepth) + "<td" + (isDeprecated ? " class='deprecated'" : "") + "><b><a href='#" + prop.getType().name() + "'>"
-              + prop.getType().toString().replaceAll(" ", "&nbsp;") + "</a></b></td>");
-          String zoo = "no";
-          if (Property.isValidZooPropertyKey(prop.getKey())) {
-            zoo = "yes";
-            if (Property.isFixedZooPropertyKey(prop)) {
-              zoo = "yes but requires restart of the " + prop.getKey().split("[.]")[0];
-            }
-          }
-          doc.println(indent(indentDepth) + "<td" + (isDeprecated ? " class='deprecated'" : "") + ">" + zoo + "</td>");
-          doc.println(indent(indentDepth) + "<td" + (isDeprecated ? " class='deprecated'" : "") + "><pre>"
-              + (prop.getRawDefaultValue().isEmpty() ? "&nbsp;" : prop.getRawDefaultValue().replaceAll(" ", "&nbsp;")) + "</pre></td>");
-          doc.println(indent(indentDepth) + "<td" + (isDeprecated ? " class='deprecated'" : "") + ">" + (isDeprecated ? "<b><i>Deprecated.</i></b> " : "")
-              + prop.getDescription() + "</td>");
-          doc.println(indent(--indentDepth) + "</tr>");
-        }
-      }
-    }
-    doc.println(indent(--indentDepth) + "</table>");
-
-    doc.println(indent(indentDepth) + "<h1>Property Type Descriptions</h1>");
-    doc.println(indent(indentDepth++) + "<table>");
-    doc.println(indent(indentDepth) + "<tr><th>Property Type</th><th>Description</th></tr>");
-    boolean highlight = true;
-    for (PropertyType type : PropertyType.values()) {
-      if (type.equals(PropertyType.PREFIX))
-        continue;
-      doc.println(indent(indentDepth++) + "<tr " + (highlight ? "class='highlight'" : "") + ">");
-      highlight = !highlight;
-      doc.println(indent(indentDepth) + "<td><h3><a id='" + type.name() + "'>" + type + "</a></h3></td>");
-      doc.println(indent(indentDepth) + "<td>" + type.getFormatDescription() + "</td>");
-      doc.println(indent(--indentDepth) + "</tr>");
-    }
-    doc.println(indent(--indentDepth) + "</table>");
-    doc.println(indent(--indentDepth) + "</body>");
-    doc.println(indent(--indentDepth) + "</html>");
-    doc.close();
-  }
-
-  private static String indent(int depth) {
-    StringBuilder sb = new StringBuilder();
-    for (int d = 0; d < depth; d++)
-      sb.append(" ");
-    return sb.toString();
+    new ConfigurationDocGen(doc).generateHtml();
   }
 
   /*
@@ -190,9 +72,11 @@ public class DefaultConfiguration extends AccumuloConfiguration {
    */
   public static void main(String[] args) throws FileNotFoundException, UnsupportedEncodingException {
     if (args.length == 2 && args[0].equals("--generate-doc")) {
-      generateDocumentation(new PrintStream(args[1], Constants.UTF8.name()));
+      new ConfigurationDocGen(new PrintStream(args[1], Constants.UTF8.name())).generateHtml();
+    } else if (args.length == 2 && args[0].equals("--generate-latex")) {
+      new ConfigurationDocGen(new PrintStream(args[1], Constants.UTF8.name())).generateLaTeX();
     } else {
-      throw new IllegalArgumentException("Usage: " + DefaultConfiguration.class.getName() + " --generate-doc <filename>");
+      throw new IllegalArgumentException("Usage: " + DefaultConfiguration.class.getName() + " --generate-doc <filename> | --generate-latex <filename>");
     }
   }
 

http://git-wip-us.apache.org/repos/asf/accumulo/blob/40299f89/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 795a250..9b803e2 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
@@ -73,30 +73,30 @@ public enum Property {
       "The path relative to the top level instance directory (instance.dfs.dir) where to store the key encryption key within HDFS."),
   @Experimental
   CRYPTO_DEFAULT_KEY_STRATEGY_CIPHER_SUITE("crypto.default.key.strategy.cipher.suite", "NullCipher", PropertyType.STRING,
-      "The cipher suite to use when encrypting session keys with a key encryption key.  This should be set to match the overall encryption algorithm  "
+      "The cipher suite to use when encrypting session keys with a key encryption keyThis should be set to match the overall encryption algorithm "
           + "but with ECB mode and no padding unless you really know what you're doing and are sure you won't break internal file formats"),
   @Experimental
   CRYPTO_OVERRIDE_KEY_STRATEGY_WITH_CONFIGURED_STRATEGY("crypto.override.key.strategy.with.configured.strategy", "false", PropertyType.BOOLEAN,
       "The default behavior is to record the key encryption strategy with the encrypted file, and continue to use that strategy for the life "
-          + "of that file.  Sometimes, you change your strategy and want to use the new strategy, not the old one.  (Most commonly, this will be "
+          + "of that file. Sometimes, you change your strategy and want to use the new strategy, not the old one. (Most commonly, this will be "
           + "because you have moved key material from one spot to another.)  If you want to override the recorded key strategy with the one in "
           + "the configuration file, set this property to true."),
   // SSL properties local to each node (see also instance.ssl.enabled which must be consistent across all nodes in an instance)
-  RPC_PREFIX("rpc.", null, PropertyType.PREFIX, "Properties in this category related to the configuration of SSL keys for RPC.  See also instance.ssl.enabled"),
+  RPC_PREFIX("rpc.", null, PropertyType.PREFIX, "Properties in this category related to the configuration of SSL keys for RPC. See also instance.ssl.enabled"),
   RPC_SSL_KEYSTORE_PATH("rpc.javax.net.ssl.keyStore", "$ACCUMULO_CONF_DIR/ssl/keystore.jks", PropertyType.PATH,
       "Path of the keystore file for the servers' private SSL key"),
   @Sensitive
   RPC_SSL_KEYSTORE_PASSWORD("rpc.javax.net.ssl.keyStorePassword", "", PropertyType.STRING,
-      "Password used to encrypt the SSL private keystore.  Leave blank to use the Accumulo instance secret"),
+      "Password used to encrypt the SSL private keystore. Leave blank to use the Accumulo instance secret"),
   RPC_SSL_KEYSTORE_TYPE("rpc.javax.net.ssl.keyStoreType", "jks", PropertyType.STRING, "Type of SSL keystore"),
   RPC_SSL_TRUSTSTORE_PATH("rpc.javax.net.ssl.trustStore", "$ACCUMULO_CONF_DIR/ssl/truststore.jks", PropertyType.PATH,
       "Path of the truststore file for the root cert"),
   @Sensitive
   RPC_SSL_TRUSTSTORE_PASSWORD("rpc.javax.net.ssl.trustStorePassword", "", PropertyType.STRING,
-      "Password used to encrypt the SSL truststore.  Leave blank to use no password"),
+      "Password used to encrypt the SSL truststore. Leave blank to use no password"),
   RPC_SSL_TRUSTSTORE_TYPE("rpc.javax.net.ssl.trustStoreType", "jks", PropertyType.STRING, "Type of SSL truststore"),
-  RPC_USE_JSSE("rpc.useJsse", "false", PropertyType.BOOLEAN,
-      "Use JSSE system properties to configure SSL rather than general.javax.net.ssl.* Accumulo properties"),
+  RPC_USE_JSSE("rpc.useJsse", "false", PropertyType.BOOLEAN, "Use JSSE system properties to configure SSL rather than the " + RPC_PREFIX.getKey()
+      + "javax.net.ssl.* Accumulo properties"),
   // instance properties (must be the same for every node in an instance)
   INSTANCE_PREFIX("instance.", null, PropertyType.PREFIX,
       "Properties in this category must be consistent throughout a cloud. This is enforced and servers won't be able to communicate if these differ."),
@@ -104,37 +104,32 @@ public enum Property {
   INSTANCE_ZK_TIMEOUT("instance.zookeeper.timeout", "30s", PropertyType.TIMEDURATION,
       "Zookeeper session timeout; max value when represented as milliseconds should be no larger than " + Integer.MAX_VALUE),
   @Deprecated
-  INSTANCE_DFS_URI(
-      "instance.dfs.uri",
-      "",
-      PropertyType.URI,
-      "A url accumulo should use to connect to DFS. If this is empty, accumulo will obtain this information from the hadoop configuration.  This property "
-          + "will only be used when creating new files if instance.volumes is empty.  After an upgrade to 1.6.0 Accumulo will start using absolute paths to "
-          + "reference files.  Files created before a 1.6.0 upgrade are referenced via relative paths.  Relative paths will always be resolved using this config "
-          + "(if empty using the hadoop config)."),
+  INSTANCE_DFS_URI("instance.dfs.uri", "", PropertyType.URI,
+      "A url accumulo should use to connect to DFS. If this is empty, accumulo will obtain this information from the hadoop configuration. This property "
+          + "will only be used when creating new files if instance.volumes is empty. After an upgrade to 1.6.0 Accumulo will start using absolute paths to "
+          + "reference files. Files created before a 1.6.0 upgrade are referenced via relative paths. Relative paths will always be resolved using this "
+          + "config (if empty using the hadoop config)."),
   @Deprecated
   INSTANCE_DFS_DIR("instance.dfs.dir", "/accumulo", PropertyType.ABSOLUTEPATH,
-      "HDFS directory in which accumulo instance will run.  Do not change after accumulo is initialized."),
+      "HDFS directory in which accumulo instance will run. Do not change after accumulo is initialized."),
   @Sensitive
   INSTANCE_SECRET("instance.secret", "DEFAULT", PropertyType.STRING,
       "A secret unique to a given instance that all servers must know in order to communicate with one another."
           + " Change it before initialization. To change it later use ./bin/accumulo accumulo.server.util.ChangeSecret [oldpasswd] [newpasswd], "
           + " and then update conf/accumulo-site.xml everywhere."),
   INSTANCE_VOLUMES("instance.volumes", "", PropertyType.STRING,
-      "A comma seperated list of dfs uris to use.  Files will be stored across these filesystems.  If this is empty, then instance.dfs.uri will be used.  "
-          + "After adding uris to this list, run 'accumulo init --add-volume' and then restart tservers.  If entries are removed from this list then tservers "
-          + "will need to be restarted.  After a uri is removed from the list Accumulo will not create new files in that location, however Accumulo can still "
-          + "reference files created at that location before the config change. To use a comma or other reserved characters in a URI use standard URI hex encoding."
-          + "For example replace commas with %2C."),
-  INSTANCE_VOLUMES_REPLACEMENTS(
-      "instance.volumes.replacements",
-      "",
-      PropertyType.STRING,
-      "Since accumulo stores absolute URIs changing the location of a namenode could prevent Accumulo from starting.  The property helps deal with that situation.  "
-          + "Provide a comma seperated list of uri replacement pairs here if a namenode location changes. Each pair shold be separated with a space.  For example if "
-          + "hdfs://nn1 was repalced with hdfs://nnA and hdfs://nn2 was replaced with hdfs://nnB, then set this property to "
-          + "'hdfs://nn1 hdfs://nnA,hdfs://nn2 hdfs://nnB'.   Replacements must be configured for use.  To see which volumes are currently in use, run 'accumulo admin volumes -l'."
-          + "To use a comma or other reserved characters in a URI use standard URI hex encoding. For example replace commas with %2C."),
+      "A comma seperated list of dfs uris to use. Files will be stored across these filesystems. If this is empty, then instance.dfs.uri will be used. "
+          + "After adding uris to this list, run 'accumulo init --add-volume' and then restart tservers. If entries are removed from this list then tservers "
+          + "will need to be restarted. After a uri is removed from the list Accumulo will not create new files in that location, however Accumulo can still "
+          + "reference files created at that location before the config change. To use a comma or other reserved characters in a URI use standard URI hex "
+          + "encoding. For example replace commas with %2C."),
+  INSTANCE_VOLUMES_REPLACEMENTS("instance.volumes.replacements", "", PropertyType.STRING,
+      "Since accumulo stores absolute URIs changing the location of a namenode could prevent Accumulo from starting. The property helps deal with that "
+          + "situation. Provide a comma seperated list of uri replacement pairs here if a namenode location changes. Each pair shold be separated with a "
+          + "space. For example, if hdfs://nn1 was repalced with hdfs://nnA and hdfs://nn2 was replaced with hdfs://nnB, then set this property to "
+          + "'hdfs://nn1 hdfs://nnA,hdfs://nn2 hdfs://nnB'Replacements must be configured for use. To see which volumes are currently in use, run "
+          + "'accumulo admin volumes -l'. To use a comma or other reserved characters in a URI use standard URI hex encoding. For example replace commas with "
+          + "%2C."),
   INSTANCE_SECURITY_AUTHENTICATOR("instance.security.authenticator", "org.apache.accumulo.server.security.handler.ZKAuthenticator", PropertyType.CLASSNAME,
       "The authenticator class that accumulo will use to determine if a user has privilege to perform an action"),
   INSTANCE_SECURITY_AUTHORIZOR("instance.security.authorizor", "org.apache.accumulo.server.security.handler.ZKAuthorizor", PropertyType.CLASSNAME,
@@ -181,7 +176,7 @@ public enum Property {
   MASTER_WALOG_CLOSER_IMPLEMETATION("master.walog.closer.implementation", "org.apache.accumulo.server.master.recovery.HadoopLogCloser", PropertyType.CLASSNAME,
       "A class that implements a mechansim to steal write access to a file"),
   MASTER_FATE_THREADPOOL_SIZE("master.fate.threadpool.size", "4", PropertyType.COUNT,
-      "The number of threads used to run FAult-Tolerant Executions.  These are primarily table operations like merge."),
+      "The number of threads used to run FAult-Tolerant Executions. These are primarily table operations like merge."),
 
   // properties that are specific to tablet server behavior
   TSERV_PREFIX("tserver.", null, PropertyType.PREFIX, "Properties in this category affect the behavior of the tablet servers"),
@@ -193,15 +188,15 @@ public enum Property {
   TSERV_CLIENTPORT("tserver.port.client", "9997", PropertyType.PORT, "The port used for handling client connections on the tablet servers"),
   TSERV_MUTATION_QUEUE_MAX("tserver.mutation.queue.max", "1M", PropertyType.MEMORY,
       "The amount of memory to use to store write-ahead-log mutations-per-session before flushing them. Since the buffer is per write session, consider the"
-          + " max number of concurrent writer when configuring.  When using Hadoop 2, Accumulo will call hsync() on the WAL .  For a small number of "
-          + "concurrent writers, increasing this buffer size decreases the frequncy of hsync calls.  For a large number of concurrent writers a small buffers "
+          + " max number of concurrent writer when configuring. When using Hadoop 2, Accumulo will call hsync() on the WAL . For a small number of "
+          + "concurrent writers, increasing this buffer size decreases the frequncy of hsync calls. For a large number of concurrent writers a small buffers "
           + "size is ok because of group commit."),
   TSERV_TABLET_SPLIT_FINDMIDPOINT_MAXOPEN("tserver.tablet.split.midpoint.files.max", "30", PropertyType.COUNT,
       "To find a tablets split points, all index files are opened. This setting determines how many index "
           + "files can be opened at once. When there are more index files than this setting multiple passes "
           + "must be made, which is slower. However opening too many files at once can cause problems."),
   TSERV_WALOG_MAX_SIZE("tserver.walog.max.size", "1G", PropertyType.MEMORY,
-      "The maximum size for each write-ahead log.  See comment for property tserver.memory.maps.max"),
+      "The maximum size for each write-ahead log. See comment for property tserver.memory.maps.max"),
   TSERV_MAJC_DELAY("tserver.compaction.major.delay", "30s", PropertyType.TIMEDURATION,
       "Time a tablet server will sleep between checking which tablets need compaction."),
   TSERV_MAJC_THREAD_MAXOPEN("tserver.compaction.major.thread.files.open.max", "10", PropertyType.COUNT,
@@ -220,7 +215,7 @@ public enum Property {
       "An implementation of MemoryManger that accumulo will use."),
   TSERV_SESSION_MAXIDLE("tserver.session.idle.max", "1m", PropertyType.TIMEDURATION, "maximum idle time for a session"),
   TSERV_READ_AHEAD_MAXCONCURRENT("tserver.readahead.concurrent.max", "16", PropertyType.COUNT,
-      "The maximum number of concurrent read ahead that will execute.  This effectively"
+      "The maximum number of concurrent read ahead that will execute. This effectively"
           + " limits the number of long running scans that can run concurrently per tserver."),
   TSERV_METADATA_READ_AHEAD_MAXCONCURRENT("tserver.metadata.readahead.concurrent.max", "8", PropertyType.COUNT,
       "The maximum number of concurrent metadata read ahead that will execute."),
@@ -236,18 +231,18 @@ public enum Property {
       "The number of concurrent threads that will load bloom filters in the background. "
           + "Setting this to zero will make bloom filters load in the foreground."),
   TSERV_MONITOR_FS("tserver.monitor.fs", "true", PropertyType.BOOLEAN,
-      "When enabled the tserver will monitor file systems and kill itself when one switches from rw to ro.  This is usually and indication that Linux has"
+      "When enabled the tserver will monitor file systems and kill itself when one switches from rw to ro. This is usually and indication that Linux has"
           + " detected a bad disk."),
   TSERV_MEMDUMP_DIR("tserver.dir.memdump", "/tmp", PropertyType.PATH,
-      "A long running scan could possibly hold memory that has been minor compacted.  To prevent this, the in memory map is dumped to a local file and the "
-          + "scan is switched to that local file.  We can not switch to the minor compacted file because it may have been modified by iterators.  The file "
+      "A long running scan could possibly hold memory that has been minor compacted. To prevent this, the in memory map is dumped to a local file and the "
+          + "scan is switched to that local file. We can not switch to the minor compacted file because it may have been modified by iterators. The file "
           + "dumped to the local dir is an exact copy of what was in memory."),
   TSERV_BULK_PROCESS_THREADS("tserver.bulk.process.threads", "1", PropertyType.COUNT,
-      "The master will task a tablet server with pre-processing a bulk file prior to assigning it to the appropriate tablet servers.  This configuration"
+      "The master will task a tablet server with pre-processing a bulk file prior to assigning it to the appropriate tablet servers. This configuration"
           + " value controls the number of threads used to process the files."),
   TSERV_BULK_ASSIGNMENT_THREADS("tserver.bulk.assign.threads", "1", PropertyType.COUNT,
       "The master delegates bulk file processing and assignment to tablet servers. After the bulk file has been processed, the tablet server will assign"
-          + " the file to the appropriate tablets on all servers.  This property controls the number of threads used to communicate to the other servers."),
+          + " the file to the appropriate tablets on all servers. This property controls the number of threads used to communicate to the other servers."),
   TSERV_BULK_RETRY("tserver.bulk.retry.max", "5", PropertyType.COUNT,
       "The number of times the tablet server will attempt to assign a file to a tablet as it migrates and splits."),
   TSERV_BULK_TIMEOUT("tserver.bulk.timeout", "5m", PropertyType.TIMEDURATION, "The time to wait for a tablet server to process a bulk import request."),
@@ -255,10 +250,10 @@ public enum Property {
   TSERV_THREADCHECK("tserver.server.threadcheck.time", "1s", PropertyType.TIMEDURATION, "The time between adjustments of the server thread pool."),
   TSERV_MAX_MESSAGE_SIZE("tserver.server.message.size.max", "1G", PropertyType.MEMORY, "The maximum size of a message that can be sent to a tablet server."),
   TSERV_HOLD_TIME_SUICIDE("tserver.hold.time.max", "5m", PropertyType.TIMEDURATION,
-      "The maximum time for a tablet server to be in the \"memory full\" state.  If the tablet server cannot write out memory"
-          + " in this much time, it will assume there is some failure local to its node, and quit.  A value of zero is equivalent to forever."),
+      "The maximum time for a tablet server to be in the \"memory full\" state. If the tablet server cannot write out memory"
+          + " in this much time, it will assume there is some failure local to its node, and quit. A value of zero is equivalent to forever."),
   TSERV_WAL_BLOCKSIZE("tserver.wal.blocksize", "0", PropertyType.MEMORY,
-      "The size of the HDFS blocks used to write to the Write-Ahead log.  If zero, it will be 110% of tserver.walog.max.size (that is, try to use just one"
+      "The size of the HDFS blocks used to write to the Write-Ahead log. If zero, it will be 110% of tserver.walog.max.size (that is, try to use just one"
           + " block)"),
   TSERV_WAL_REPLICATION("tserver.wal.replication", "0", PropertyType.COUNT,
       "The replication to use when writing the Write-Ahead log to HDFS. If zero, it will use the HDFS default replication setting."),
@@ -267,7 +262,7 @@ public enum Property {
   TSERV_SORT_BUFFER_SIZE("tserver.sort.buffer.size", "200M", PropertyType.MEMORY, "The amount of memory to use when sorting logs during recovery."),
   TSERV_ARCHIVE_WALOGS("tserver.archive.walogs", "false", PropertyType.BOOLEAN, "Keep copies of the WALOGs for debugging purposes"),
   TSERV_WORKQ_THREADS("tserver.workq.threads", "2", PropertyType.COUNT,
-      "The number of threads for the distributed workq.  These threads are used for copying failed bulk files."),
+      "The number of threads for the distributed work queue. These threads are used for copying failed bulk files."),
   TSERV_WAL_SYNC("tserver.wal.sync", "true", PropertyType.BOOLEAN,
       "Use the SYNC_BLOCK create flag to sync WAL writes to disk. Prevents problems recovering from sudden system resets."),
 
@@ -275,7 +270,7 @@ public enum Property {
   LOGGER_PREFIX("logger.", null, PropertyType.PREFIX, "Properties in this category affect the behavior of the write-ahead logger servers"),
   LOGGER_DIR("logger.dir.walog", "walogs", PropertyType.PATH,
       "The property only needs to be set if upgrading from 1.4 which used to store write-ahead logs on the local filesystem. In 1.5 write-ahead logs are "
-          + "stored in DFS.  When 1.5 is started for the first time it will copy any 1.4 write ahead logs into DFS.  It is possible to specify a "
+          + "stored in DFS. When 1.5 is started for the first time it will copy any 1.4 write ahead logs into DFS. It is possible to specify a "
           + "comma-separated list of directories."),
 
   // accumulo garbage collector properties
@@ -307,8 +302,9 @@ public enum Property {
   @Sensitive
   MONITOR_SSL_TRUSTSTOREPASS("monitor.ssl.trustStorePassword", "", PropertyType.STRING, "The truststore password for enabling monitor SSL."),
 
-  MONITOR_LOCK_CHECK_INTERVAL("monitor.lock.check.interval", "5s", PropertyType.TIMEDURATION, "The amount of time to sleep between checking for the Montior ZooKeeper lock"),
-  
+  MONITOR_LOCK_CHECK_INTERVAL("monitor.lock.check.interval", "5s", PropertyType.TIMEDURATION,
+      "The amount of time to sleep between checking for the Montior ZooKeeper lock"),
+
   TRACE_PREFIX("trace.", null, PropertyType.PREFIX, "Properties in this category affect the behavior of distributed tracing."),
   TRACE_PORT("trace.port.client", "12234", PropertyType.PORT, "The listening port for the trace server"),
   TRACE_TABLE("trace.table", "trace", PropertyType.STRING, "The name of the table to store distributed traces"),
@@ -316,8 +312,8 @@ public enum Property {
   @Sensitive
   TRACE_PASSWORD("trace.password", "secret", PropertyType.STRING, "The password for the user used to store distributed traces"),
   @Sensitive
-  TRACE_TOKEN_PROPERTY_PREFIX("trace.token.property", null, PropertyType.PREFIX,
-      "The prefix used to create a token for storing distributed traces.  For each propetry required by trace.token.type, place this prefix in front of it."),
+  TRACE_TOKEN_PROPERTY_PREFIX("trace.token.property.", null, PropertyType.PREFIX,
+      "The prefix used to create a token for storing distributed traces. For each propetry required by trace.token.type, place this prefix in front of it."),
   TRACE_TOKEN_TYPE("trace.token.type", PasswordToken.class.getName(), PropertyType.CLASSNAME, "An AuthenticationToken type supported by the authorizer"),
 
   // per table properties
@@ -329,19 +325,19 @@ public enum Property {
       + "will cause the global setting to take effect. However, you must use the API or the shell to change "
       + "properties in zookeeper that are set on a table."),
   TABLE_MAJC_RATIO("table.compaction.major.ratio", "3", PropertyType.FRACTION,
-      "minimum ratio of total input size to maximum input file size for running a major compaction.   When adjusting this property you may want to also "
-          + "adjust table.file.max.  Want to avoid the situation where only merging minor compactions occur."),
+      "minimum ratio of total input size to maximum input file size for running a major compactionWhen adjusting this property you may want to also "
+          + "adjust table.file.max. Want to avoid the situation where only merging minor compactions occur."),
   TABLE_MAJC_COMPACTALL_IDLETIME("table.compaction.major.everything.idle", "1h", PropertyType.TIMEDURATION,
       "After a tablet has been idle (no mutations) for this time period it may have all "
-          + "of its files compacted into one.  There is no guarantee an idle tablet will be compacted. "
+          + "of its files compacted into one. There is no guarantee an idle tablet will be compacted. "
           + "Compactions of idle tablets are only started when regular compactions are not running. Idle "
           + "compactions only take place for tablets that have one or more files."),
   TABLE_SPLIT_THRESHOLD("table.split.threshold", "1G", PropertyType.MEMORY, "When combined size of files exceeds this amount a tablet is split."),
   TABLE_MINC_LOGS_MAX("table.compaction.minor.logs.threshold", "3", PropertyType.COUNT,
-      "When there are more than this many write-ahead logs against a tablet, it will be minor compacted.  See comment for property tserver.memory.maps.max"),
+      "When there are more than this many write-ahead logs against a tablet, it will be minor compacted. See comment for property tserver.memory.maps.max"),
   TABLE_MINC_COMPACT_IDLETIME("table.compaction.minor.idle", "5m", PropertyType.TIMEDURATION,
       "After a tablet has been idle (no mutations) for this time period it may have its "
-          + "in-memory map flushed to disk in a minor compaction.  There is no guarantee an idle " + "tablet will be compacted."),
+          + "in-memory map flushed to disk in a minor compaction. There is no guarantee an idle " + "tablet will be compacted."),
   TABLE_SCAN_MAXMEM("table.scan.max.memory", "512K", PropertyType.MEMORY,
       "The maximum amount of memory that will be used to cache results of a client query/scan. "
           + "Once this limit is reached, the buffered data is sent to the client."),
@@ -361,8 +357,8 @@ public enum Property {
       + "When this value is LTE 0, HDFS defaults are used."),
   TABLE_FILE_MAX("table.file.max", "15", PropertyType.COUNT,
       "Determines the max # of files each tablet in a table can have. When adjusting this property you may want to consider adjusting"
-          + " table.compaction.major.ratio also.  Setting this property to 0 will make it default to tserver.scan.files.open.max-1, this will prevent a"
-          + " tablet from having more files than can be opened.  Setting this property low may throttle ingest and increase query performance."),
+          + " table.compaction.major.ratio also. Setting this property to 0 will make it default to tserver.scan.files.open.max-1, this will prevent a"
+          + " tablet from having more files than can be opened. Setting this property low may throttle ingest and increase query performance."),
   TABLE_WALOG_ENABLED("table.walog.enabled", "true", PropertyType.BOOLEAN, "Use the write-ahead log to prevent the loss of data."),
   TABLE_BLOOM_ENABLED("table.bloom.enabled", "false", PropertyType.BOOLEAN, "Use bloom filters on this table."),
   TABLE_BLOOM_LOAD_THRESHOLD("table.bloom.load.threshold", "1", PropertyType.COUNT,
@@ -371,7 +367,7 @@ public enum Property {
   TABLE_BLOOM_SIZE("table.bloom.size", "1048576", PropertyType.COUNT, "Bloom filter size, as number of keys."),
   TABLE_BLOOM_ERRORRATE("table.bloom.error.rate", "0.5%", PropertyType.FRACTION, "Bloom filter error rate."),
   TABLE_BLOOM_KEY_FUNCTOR("table.bloom.key.functor", "org.apache.accumulo.core.file.keyfunctor.RowFunctor", PropertyType.CLASSNAME,
-      "A function that can transform the key prior to insertion and check of bloom filter.  org.apache.accumulo.core.file.keyfunctor.RowFunctor,"
+      "A function that can transform the key prior to insertion and check of bloom filter. org.apache.accumulo.core.file.keyfunctor.RowFunctor,"
           + ",org.apache.accumulo.core.file.keyfunctor.ColumnFamilyFunctor, and org.apache.accumulo.core.file.keyfunctor.ColumnQualifierFunctor are"
           + " allowable values. One can extend any of the above mentioned classes to perform specialized parsing of the key. "),
   TABLE_BLOOM_HASHTYPE("table.bloom.hash.type", "murmur", PropertyType.STRING, "The bloom filter hash type"),
@@ -380,9 +376,9 @@ public enum Property {
           + "then set this to false. When this set to true missing data will be reported but queries "
           + "will still run possibly returning a subset of the data."),
   TABLE_DEFAULT_SCANTIME_VISIBILITY("table.security.scan.visibility.default", "", PropertyType.STRING,
-      "The security label that will be assumed at scan time if an entry does not have a visibility set.<br />"
+      "The security label that will be assumed at scan time if an entry does not have a visibility set.\n"
           + "Note: An empty security label is displayed as []. The scan results will show an empty visibility even if "
-          + "the visibility from this setting is applied to the entry.<br />"
+          + "the visibility from this setting is applied to the entry.\n"
           + "CAUTION: If a particular key has an empty security label AND its table's default visibility is also empty, "
           + "access will ALWAYS be granted for users with permission to that table. Additionally, if this field is changed, "
           + "all existing data with an empty visibility label will be interpreted with the new label on the next scan."),
@@ -390,9 +386,9 @@ public enum Property {
   TABLE_CONSTRAINT_PREFIX("table.constraint.", null, PropertyType.PREFIX,
       "Properties in this category are per-table properties that add constraints to a table. "
           + "These properties start with the category prefix, followed by a number, and their values "
-          + "correspond to a fully qualified Java class that implements the Constraint interface.<br />"
-          + "For example, table.constraint.1 = org.apache.accumulo.core.constraints.MyCustomConstraint "
-          + "and table.constraint.2 = my.package.constraints.MySecondConstraint"),
+          + "correspond to a fully qualified Java class that implements the Constraint interface.\n"
+          + "For example:\ntable.constraint.1 = org.apache.accumulo.core.constraints.MyCustomConstraint\n"
+          + "and:\ntable.constraint.2 = my.package.constraints.MySecondConstraint"),
   TABLE_INDEXCACHE_ENABLED("table.cache.index.enable", "true", PropertyType.BOOLEAN, "Determines whether index cache is enabled."),
   TABLE_BLOCKCACHE_ENABLED("table.cache.block.enable", "false", PropertyType.BOOLEAN, "Determines whether file block cache is enabled."),
   TABLE_ITERATOR_PREFIX("table.iterator.", null, PropertyType.PREFIX,
@@ -400,16 +396,16 @@ public enum Property {
           + "with a table. These properties start with the category prefix, followed by a scope (minc, majc, scan, etc.), "
           + "followed by a period, followed by a name, as in table.iterator.scan.vers, or table.iterator.scan.custom. "
           + "The values for these properties are a number indicating the ordering in which it is applied, and a class name "
-          + "such as table.iterator.scan.vers = 10,org.apache.accumulo.core.iterators.VersioningIterator<br /> "
+          + "such as:\n table.iterator.scan.vers = 10,org.apache.accumulo.core.iterators.VersioningIterator\n "
           + "These iterators can take options if additional properties are set that look like this property, "
-          + "but are suffixed with a period, followed by 'opt' followed by another period, and a property name.<br />"
+          + "but are suffixed with a period, followed by 'opt' followed by another period, and a property name.\n"
           + "For example, table.iterator.minc.vers.opt.maxVersions = 3"),
   TABLE_LOCALITY_GROUP_PREFIX("table.group.", null, PropertyType.PREFIX,
       "Properties in this category are per-table properties that define locality groups in a table. These properties start "
-          + "with the category prefix, followed by a name, followed by a period, and followed by a property for that group.<br />"
+          + "with the category prefix, followed by a name, followed by a period, and followed by a property for that group.\n"
           + "For example table.group.group1=x,y,z sets the column families for a group called group1. Once configured, "
-          + "group1 can be enabled by adding it to the list of groups in the " + TABLE_LOCALITY_GROUPS.getKey() + " property.<br />"
-          + "Additional group options may be specified for a named group by setting table.group.&lt;name&gt;.opt.&lt;key&gt;=&lt;value&gt;."),
+          + "group1 can be enabled by adding it to the list of groups in the " + TABLE_LOCALITY_GROUPS.getKey() + " property.\n"
+          + "Additional group options may be specified for a named group by setting table.group.<name>.opt.<key>=<value>."),
   TABLE_FORMATTER_CLASS("table.formatter", DefaultFormatter.class.getName(), PropertyType.STRING, "The Formatter class to apply on results in the shell"),
   TABLE_INTERPRETER_CLASS("table.interepreter", DefaultScanInterpreter.class.getName(), PropertyType.STRING,
       "The ScanInterpreter class to apply on scan arguments in the shell"),
@@ -421,13 +417,13 @@ public enum Property {
 
   // VFS ClassLoader properties
   VFS_CLASSLOADER_SYSTEM_CLASSPATH_PROPERTY(AccumuloVFSClassLoader.VFS_CLASSLOADER_SYSTEM_CLASSPATH_PROPERTY, "", PropertyType.STRING,
-      "Configuration for a system level vfs classloader.  Accumulo jar can be configured here and loaded out of HDFS."),
+      "Configuration for a system level vfs classloader. Accumulo jar can be configured here and loaded out of HDFS."),
   VFS_CONTEXT_CLASSPATH_PROPERTY(AccumuloVFSClassLoader.VFS_CONTEXT_CLASSPATH_PROPERTY, null, PropertyType.PREFIX,
-      "Properties in this category are define a classpath. These properties start  with the category prefix, followed by a context name.  "
+      "Properties in this category are define a classpath. These properties start  with the category prefix, followed by a context name. "
           + "The value is a comma seperated list of URIs. Supports full regex on filename alone. For example, "
-          + "general.vfs.context.classpath.cx1=hdfs://nn1:9902/mylibdir/*.jar.  "
-          + "You can enable post delegation for a context, which will load classes from the context first instead of the parent first.  "
-          + "Do this by setting general.vfs.context.classpath.&lt;name&gt;.delegation=post, where &lt;name&gt; is your context name.  "
+          + "general.vfs.context.classpath.cx1=hdfs://nn1:9902/mylibdir/*.jar. "
+          + "You can enable post delegation for a context, which will load classes from the context first instead of the parent first. "
+          + "Do this by setting general.vfs.context.classpath.<name>.delegation=post, where <name> is your context name"
           + "If delegation is not specified, it defaults to loading from parent classloader first."),
   @Interpolated
   VFS_CLASSLOADER_CACHE_DIR(AccumuloVFSClassLoader.VFS_CACHE_DIR, "${java.io.tmpdir}" + File.separator + "accumulo-vfs-cache-${user.name}",

http://git-wip-us.apache.org/repos/asf/accumulo/blob/40299f89/core/src/main/java/org/apache/accumulo/core/conf/PropertyType.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/conf/PropertyType.java b/core/src/main/java/org/apache/accumulo/core/conf/PropertyType.java
index 16f22e4..7b6a926 100644
--- a/core/src/main/java/org/apache/accumulo/core/conf/PropertyType.java
+++ b/core/src/main/java/org/apache/accumulo/core/conf/PropertyType.java
@@ -16,77 +16,75 @@
  */
 package org.apache.accumulo.core.conf;
 
-import java.util.regex.Pattern;
 import java.util.Arrays;
+import java.util.regex.Pattern;
 
 import org.apache.accumulo.core.Constants;
 import org.apache.hadoop.fs.Path;
 
 public enum PropertyType {
   PREFIX(null, null, null),
-  
+
   TIMEDURATION("duration", "\\d{1," + Long.toString(Long.MAX_VALUE).length() + "}(?:ms|s|m|h|d)?",
-      "A non-negative integer optionally followed by a unit of time (whitespace disallowed), as in 30s.<br />"
-          + "If no unit of time is specified, seconds are assumed. Valid units are 'ms', 's', 'm', 'h' for milliseconds, seconds, minutes, and hours.<br />"
-          + "Examples of valid durations are '600', '30s', '45m', '30000ms', '3d', and '1h'.<br />"
-          + "Examples of invalid durations are '1w', '1h30m', '1s 200ms', 'ms', '', and 'a'.<br />"
-          + "Unless otherwise stated, the max value for the duration represented in milliseconds is " + Long.MAX_VALUE),
-  DATETIME("date/time", "(?:19|20)\\d{12}[A-Z]{3}", "A date/time string in the format: YYYYMMDDhhmmssTTT where TTT is the 3 character time zone"),
-  MEMORY("memory", "\\d{1," + Long.toString(Long.MAX_VALUE).length() + "}(?:B|K|M|G)?",
-      "A positive integer optionally followed by a unit of memory (whitespace disallowed), as in 2G.<br />"
-          + "If no unit is specified, bytes are assumed. Valid units are 'B', 'K', 'M', 'G', for bytes, kilobytes, megabytes, and gigabytes.<br />"
-          + "Examples of valid memories are '1024', '20B', '100K', '1500M', '2G'.<br />"
-          + "Examples of invalid memories are '1M500K', '1M 2K', '1MB', '1.5G', '1,024K', '', and 'a'.<br />"
+      "A non-negative integer optionally followed by a unit of time (whitespace disallowed), as in 30s.\n"
+          + "If no unit of time is specified, seconds are assumed. Valid units are 'ms', 's', 'm', 'h' for milliseconds, seconds, minutes, and hours.\n"
+          + "Examples of valid durations are '600', '30s', '45m', '30000ms', '3d', and '1h'.\n"
+          + "Examples of invalid durations are '1w', '1h30m', '1s 200ms', 'ms', '', and 'a'.\n"
+          + "Unless otherwise stated, the max value for the duration represented in milliseconds is " + Long.MAX_VALUE), DATETIME("date/time",
+      "(?:19|20)\\d{12}[A-Z]{3}", "A date/time string in the format: YYYYMMDDhhmmssTTT where TTT is the 3 character time zone"), MEMORY("memory", "\\d{1,"
+      + Long.toString(Long.MAX_VALUE).length() + "}(?:B|K|M|G)?",
+      "A positive integer optionally followed by a unit of memory (whitespace disallowed), as in 2G.\n"
+          + "If no unit is specified, bytes are assumed. Valid units are 'B', 'K', 'M', 'G', for bytes, kilobytes, megabytes, and gigabytes.\n"
+          + "Examples of valid memories are '1024', '20B', '100K', '1500M', '2G'.\n"
+          + "Examples of invalid memories are '1M500K', '1M 2K', '1MB', '1.5G', '1,024K', '', and 'a'.\n"
           + "Unless otherwise stated, the max value for the memory represented in bytes is " + Long.MAX_VALUE),
-  
+
   HOSTLIST("host list", "[\\w-]+(?:\\.[\\w-]+)*(?:\\:\\d{1,5})?(?:,[\\w-]+(?:\\.[\\w-]+)*(?:\\:\\d{1,5})?)*",
-      "A comma-separated list of hostnames or ip addresses, with optional port numbers.<br />"
-          + "Examples of valid host lists are 'localhost:2000,www.example.com,10.10.1.1:500' and 'localhost'.<br />"
+      "A comma-separated list of hostnames or ip addresses, with optional port numbers.\n"
+          + "Examples of valid host lists are 'localhost:2000,www.example.com,10.10.1.1:500' and 'localhost'.\n"
           + "Examples of invalid host lists are '', ':1000', and 'localhost:80000'"),
-  
-  PORT("port", "\\d{1,5}", "An positive integer in the range 1024-65535, not already in use or specified elsewhere in the configuration"),
-  COUNT("count", "\\d{1,10}", "A non-negative integer in the range of 0-" + Integer.MAX_VALUE),
-  FRACTION("fraction/percentage", "\\d*(?:\\.\\d+)?%?",
-      "A floating point number that represents either a fraction or, if suffixed with the '%' character, a percentage.<br />"
-          + "Examples of valid fractions/percentages are '10', '1000%', '0.05', '5%', '0.2%', '0.0005'.<br />"
+
+  PORT("port", "\\d{1,5}", "An positive integer in the range 1024-65535, not already in use or specified elsewhere in the configuration"), COUNT("count",
+      "\\d{1,10}", "A non-negative integer in the range of 0-" + Integer.MAX_VALUE), FRACTION("fraction/percentage", "\\d*(?:\\.\\d+)?%?",
+      "A floating point number that represents either a fraction or, if suffixed with the '%' character, a percentage.\n"
+          + "Examples of valid fractions/percentages are '10', '1000%', '0.05', '5%', '0.2%', '0.0005'.\n"
           + "Examples of invalid fractions/percentages are '', '10 percent', 'Hulk Hogan'"),
 
   PATH("path", ".*",
-      "A string that represents a filesystem path, which can be either relative or absolute to some directory. The filesystem depends on the property.  The following environment variables will be substituted: " + Arrays.asList(Constants.PATH_PROPERTY_ENV_VARS)),
-  ABSOLUTEPATH("absolute path", null,
+      "A string that represents a filesystem path, which can be either relative or absolute to some directory. The filesystem depends on the property. The "
+          + "following environment variables will be substituted: " + Arrays.asList(Constants.PATH_PROPERTY_ENV_VARS)), ABSOLUTEPATH("absolute path", null,
       "An absolute filesystem path. The filesystem depends on the property. This is the same as path, but enforces that its root is explicitly specified.") {
     @Override
     public boolean isValidFormat(String value) {
       return new Path(value).isAbsolute();
     }
   },
-  
-  CLASSNAME("java class", "[\\w$.]*", "A fully qualified java class name representing a class on the classpath.<br />"
+
+  CLASSNAME("java class", "[\\w$.]*", "A fully qualified java class name representing a class on the classpath.\n"
       + "An example is 'java.lang.String', rather than 'String'"),
-  
+
   STRING("string", ".*",
-      "An arbitrary string of characters whose format is unspecified and interpreted based on the context of the property to which it applies."),
-  BOOLEAN("boolean", "(?:true|false)", "Has a value of either 'true' or 'false'"),
-  URI("uri", ".*", "A valid URI");
-  
+      "An arbitrary string of characters whose format is unspecified and interpreted based on the context of the property to which it applies."), BOOLEAN(
+      "boolean", "(?:true|false)", "Has a value of either 'true' or 'false'"), URI("uri", ".*", "A valid URI");
+
   private String shortname, format;
   private Pattern regex;
-  
+
   private PropertyType(String shortname, String regex, String formatDescription) {
     this.shortname = shortname;
     this.format = formatDescription;
     this.regex = regex == null ? null : Pattern.compile(regex, Pattern.DOTALL);
   }
-  
+
   @Override
   public String toString() {
     return shortname;
   }
-  
+
   String getFormatDescription() {
     return format;
   }
-  
+
   public boolean isValidFormat(String value) {
     return (regex == null && value == null) ? true : regex.matcher(value).matches();
   }

http://git-wip-us.apache.org/repos/asf/accumulo/blob/40299f89/core/src/main/resources/org/apache/accumulo/core/conf/config-header.html
----------------------------------------------------------------------
diff --git a/core/src/main/resources/org/apache/accumulo/core/conf/config-header.html b/core/src/main/resources/org/apache/accumulo/core/conf/config-header.html
new file mode 100644
index 0000000..8270ad2
--- /dev/null
+++ b/core/src/main/resources/org/apache/accumulo/core/conf/config-header.html
@@ -0,0 +1,90 @@
+<!DOCTYPE html>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+  <title>Accumulo Configuration</title>
+  <link rel='stylesheet' type='text/css' href='documentation.css' media='screen'/>
+ </head>
+ <body>
+  <h1>Configuration Management</h1>
+  <p>All accumulo properties have a default value in the source code.  Properties can also be set
+  in accumulo-site.xml and in zookeeper on per-table or system-wide basis.  If properties are set in more than one location,
+  accumulo will choose the property with the highest precedence.  This order of precedence is described
+  below (from highest to lowest):</p>
+  <table>
+   <tr><th>Location</th><th>Description</th></tr>
+   <tr class='highlight'><td><b>Zookeeper<br/>table properties</b></td>
+       <td>Table properties are applied to the entire cluster when set in zookeeper using the accumulo API or shell.  While table properties take precedent over system properties, both will override properties set in accumulo-site.xml<br/><br/>
+           Table properties consist of all properties with the table.* prefix.  Table properties are configured on a per-table basis using the following shell commmand:
+        <pre>config -t TABLE -s PROPERTY=VALUE</pre></td>
+   </tr>
+   <tr><td><b>Zookeeper<br/>system properties</b></td>
+      <td>System properties are applied to the entire cluster when set in zookeeper using the accumulo API or shell.  System properties consist of all properties with a 'yes' in the 'Zookeeper Mutable' column in the table below.  They are set with the following shell command:
+        <pre>config -s PROPERTY=VALUE</pre>
+      If a table.* property is set using this method, the value will apply to all tables except those configured on per-table basis (which have higher precedence).<br/><br/>
+      While most system properties take effect immediately, some require a restart of the process which is indicated in 'Zookeeper Mutable'.</td>
+   </tr>
+   <tr class='highlight'><td><b>accumulo-site.xml</b></td>
+       <td>Accumulo processes (master, tserver, etc) read their local accumulo-site.xml on start up.  Therefore, changes made to accumulo-site.xml must rsynced across the cluster and processes must be restarted to apply changes.<br/><br/>
+           Certain properties (indicated by a 'no' in 'Zookeeper Mutable') cannot be set in zookeeper and only set in this file.  The accumulo-site.xml also allows you to configure tablet servers with different settings.</td>
+   </tr>
+   <tr><td><b>Default</b></td>
+        <td>All properties have a default value in the source code.  This value has the lowest precedence and is overriden if set in accumulo-site.xml or zookeeper.<br/><br/>While the default value is usually optimal, there are cases where a change can increase query and ingest performance.</td>
+   </tr>
+  </table>
+
+  <p>The 'config' command in the shell allows you to view the current system configuration.  You can also use the '-t' option to view a table's configuration as below:
+
+  <pre>
+    $ ./bin/accumulo shell -u root
+    Enter current password for 'root'@'ac14': ******
+
+    Shell - Apache Accumulo Interactive Shell
+    -
+    - version: 1.5.0
+    - instance name: ac14
+    - instance id: 4f48fa03-f692-43ce-ae03-94c9ea8b7181
+    -
+    - type 'help' for a list of available commands
+    -
+    root@ac13> config -t foo
+    ---------+---------------------------------------------+------------------------------------------------------
+    SCOPE    | NAME                                        | VALUE
+    ---------+---------------------------------------------+------------------------------------------------------
+    default  | table.balancer ............................ | org.apache.accumulo.server.master.balancer.DefaultLoadBalancer
+    default  | table.bloom.enabled ....................... | false
+    default  | table.bloom.error.rate .................... | 0.5%
+    default  | table.bloom.hash.type ..................... | murmur
+    default  | table.bloom.key.functor ................... | org.apache.accumulo.core.file.keyfunctor.RowFunctor
+    default  | table.bloom.load.threshold ................ | 1
+    default  | table.bloom.size .......................... | 1048576
+    default  | table.cache.block.enable .................. | false
+    default  | table.cache.index.enable .................. | false
+    default  | table.compaction.major.everything.at ...... | 19700101000000GMT
+    default  | table.compaction.major.everything.idle .... | 1h
+    default  | table.compaction.major.ratio .............. | 1.3
+    site     |    @override .............................. | 1.4
+    system   |    @override .............................. | 1.5
+    table    |    @override .............................. | 1.6
+    default  | table.compaction.minor.idle ............... | 5m
+    default  | table.compaction.minor.logs.threshold ..... | 3
+    default  | table.failures.ignore ..................... | false
+  </pre>
+
+  <h1>Configuration Properties</h1>
+

http://git-wip-us.apache.org/repos/asf/accumulo/blob/40299f89/core/src/main/resources/org/apache/accumulo/core/conf/config-header.tex
----------------------------------------------------------------------
diff --git a/core/src/main/resources/org/apache/accumulo/core/conf/config-header.tex b/core/src/main/resources/org/apache/accumulo/core/conf/config-header.tex
new file mode 100644
index 0000000..a1e1dc0
--- /dev/null
+++ b/core/src/main/resources/org/apache/accumulo/core/conf/config-header.tex
@@ -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.
+
+\chapter{Configuration Management}
+\label{app:config}
+
+\section{Configuration Overview}
+
+All accumulo properties have a default value in the source code.  Properties can also be set
+in accumulo-site.xml and in zookeeper on per-table or system-wide basis.  If properties are set in more than one location,
+accumulo will choose the property with the highest precedence.  This order of precedence is described
+below (from highest to lowest):
+
+\subsection{Zookeeper table properties}
+Table properties are applied to the entire cluster when set in zookeeper using the accumulo API or shell.  While table properties take precedent over system properties, both will override properties set in accumulo-site.xml
+
+Table properties consist of all properties with the table.* prefix.  Table properties are configured on a per-table basis using the following shell commmand:
+\begingroup\fontsize{8pt}{8pt}\selectfont\begin{verbatim}
+  config -t TABLE -s PROPERTY=VALUE
+\end{verbatim}\endgroup
+
+\subsection{Zookeeper system properties}
+
+System properties are applied to the entire cluster when set in zookeeper using the accumulo API or shell.  System properties consist of all properties with a `yes' in the `Zookeeper Mutable' column in the table below.  They are set with the following shell command:
+\begingroup\fontsize{8pt}{8pt}\selectfont\begin{verbatim}
+  config -s PROPERTY=VALUE
+\end{verbatim}\endgroup
+
+If a table.* property is set using this method, the value will apply to all tables except those configured on per-table basis (which have higher precedence).
+
+While most system properties take effect immediately, some require a restart of the process which is indicated in `Zookeeper Mutable'.
+
+\subsection{accumulo-site.xml}
+
+Accumulo processes (master, tserver, etc) read their local accumulo-site.xml on start up.  Therefore, changes made to accumulo-site.xml must rsynced across the cluster and processes must be restarted to apply changes.
+
+Certain properties (indicated by a `no' in `Zookeeper Mutable') cannot be set in zookeeper and only set in this file.  The accumulo-site.xml also allows you to configure tablet servers with different settings.
+
+\subsection{Default Values}
+
+All properties have a default value in the source code.  This value has the lowest precedence and is overriden if set in accumulo-site.xml or zookeeper.
+
+While the default value is usually optimal, there are cases where a change can increase query and ingest performance.
+
+\section{Configuration in the Shell}
+
+The `config' command in the shell allows you to view the current system configuration.  You can also use the `-t' option to view a table's configuration as below:
+
+\begingroup\fontsize{8pt}{8pt}\selectfont\begin{verbatim}
+
+    $ ./bin/accumulo shell -u root
+    Enter current password for 'root'@'ac14': ******
+
+    Shell - Apache Accumulo Interactive Shell
+    -
+    - version: 1.5.0
+    - instance name: ac14
+    - instance id: 4f48fa03-f692-43ce-ae03-94c9ea8b7181
+    -
+    - type 'help' for a list of available commands
+    -
+    root@ac13> config -t foo
+    ---------+---------------------------------------------+------------------------------------------------------
+    SCOPE    | NAME                                        | VALUE
+    ---------+---------------------------------------------+------------------------------------------------------
+    default  | table.balancer ............................ | org.apache.accumulo.server.master.balancer.DefaultLoadBalancer
+    default  | table.bloom.enabled ....................... | false
+    default  | table.bloom.error.rate .................... | 0.5%
+    default  | table.bloom.hash.type ..................... | murmur
+    default  | table.bloom.key.functor ................... | org.apache.accumulo.core.file.keyfunctor.RowFunctor
+    default  | table.bloom.load.threshold ................ | 1
+    default  | table.bloom.size .......................... | 1048576
+    default  | table.cache.block.enable .................. | false
+    default  | table.cache.index.enable .................. | false
+    default  | table.compaction.major.everything.at ...... | 19700101000000GMT
+    default  | table.compaction.major.everything.idle .... | 1h
+    default  | table.compaction.major.ratio .............. | 1.3
+    site     |    @override .............................. | 1.4
+    system   |    @override .............................. | 1.5
+    table    |    @override .............................. | 1.6
+    default  | table.compaction.minor.idle ............... | 5m
+    default  | table.compaction.minor.logs.threshold ..... | 3
+    default  | table.failures.ignore ..................... | false
+
+\end{verbatim}\endgroup
+

http://git-wip-us.apache.org/repos/asf/accumulo/blob/40299f89/core/src/main/resources/org/apache/accumulo/core/conf/config.html
----------------------------------------------------------------------
diff --git a/core/src/main/resources/org/apache/accumulo/core/conf/config.html b/core/src/main/resources/org/apache/accumulo/core/conf/config.html
deleted file mode 100644
index 266e0be..0000000
--- a/core/src/main/resources/org/apache/accumulo/core/conf/config.html
+++ /dev/null
@@ -1,90 +0,0 @@
-<!DOCTYPE html>
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one or more
-  contributor license agreements.  See the NOTICE file distributed with
-  this work for additional information regarding copyright ownership.
-  The ASF licenses this file to You under the Apache License, Version 2.0
-  (the "License"); you may not use this file except in compliance with
-  the License.  You may obtain a copy of the License at
-
-      http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing, software
-  distributed under the License is distributed on an "AS IS" BASIS,
-  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  See the License for the specific language governing permissions and
-  limitations under the License.
--->
-<html xmlns="http://www.w3.org/1999/xhtml">
- <head>
-  <title>Accumulo Configuration</title>
-  <link rel='stylesheet' type='text/css' href='documentation.css' media='screen'/>
- </head>
- <body>
-  <h1>Apache Accumulo Configuration Management</h1>
-  <p>All accumulo properties have a default value in the source code.  Properties can also be set
-  in accumulo-site.xml and in zookeeper on per-table or system-wide basis.  If properties are set in more than one location,
-  accumulo will choose the property with the highest precedence.  This order of precedence is described
-  below (from highest to lowest):</p>
-  <table>
-   <tr><th>Location</th><th>Description</th></tr>
-   <tr class='highlight'><td><b>Zookeeper<br/>table properties</b></td>
-       <td>Table properties are applied to the entire cluster when set in zookeeper using the accumulo API or shell.  While table properties take precedent over system properties, both will override properties set in accumulo-site.xml<br/><br/>
-           Table properties consist of all properties with the table.* prefix.  Table properties are configured on a per-table basis using the following shell commmand:
-		    <pre>config -t TABLE -s PROPERTY=VALUE</pre></td>
-   </tr>
-   <tr><td><b>Zookeeper<br/>system properties</b></td>
-	    <td>System properties are applied to the entire cluster when set in zookeeper using the accumulo API or shell.  System properties consist of all properties with a 'yes' in the 'Zookeeper Mutable' column in the table below.  They are set with the following shell command:
-		    <pre>config -s PROPERTY=VALUE</pre>
-			If a table.* property is set using this method, the value will apply to all tables except those configured on per-table basis (which have higher precedence).<br/><br/>
-			While most system properties take effect immediately, some require a restart of the process which is indicated in 'Zookeeper Mutable'.</td>
-   </tr>
-   <tr class='highlight'><td><b>accumulo-site.xml</b></td>
-       <td>Accumulo processes (master, tserver, etc) read their local accumulo-site.xml on start up.  Therefore, changes made to accumulo-site.xml must rsynced across the cluster and processes must be restarted to apply changes.<br/><br/>
-           Certain properties (indicated by a 'no' in 'Zookeeper Mutable') cannot be set in zookeeper and only set in this file.  The accumulo-site.xml also allows you to configure tablet servers with different settings.</td>
-   </tr>
-   <tr><td><b>Default</b></td>
-   	   <td>All properties have a default value in the source code.  This value has the lowest precedence and is overriden if set in accumulo-site.xml or zookeeper.<br/><br/>While the default value is usually optimal, there are cases where a change can increase query and ingest performance.</td>
-   </tr>
-  </table>
-  
-  <p>The 'config' command in the shell allows you to view the current system configuration.  You can also use the '-t' option to view a table's configuration as below:
-  
-  <pre>
-    $ ./bin/accumulo shell -u root
-    Enter current password for 'root'@'ac14': ******
-
-    Shell - Apache Accumulo Interactive Shell
-    - 
-    - version: 1.5.0
-    - instance name: ac14
-    - instance id: 4f48fa03-f692-43ce-ae03-94c9ea8b7181
-    - 
-    - type 'help' for a list of available commands
-    - 
-    root@ac13> config -t foo
-    ---------+---------------------------------------------+------------------------------------------------------
-    SCOPE    | NAME                                        | VALUE
-    ---------+---------------------------------------------+------------------------------------------------------
-    default  | table.balancer ............................ | org.apache.accumulo.server.master.balancer.DefaultLoadBalancer
-    default  | table.bloom.enabled ....................... | false
-    default  | table.bloom.error.rate .................... | 0.5%
-    default  | table.bloom.hash.type ..................... | murmur
-    default  | table.bloom.key.functor ................... | org.apache.accumulo.core.file.keyfunctor.RowFunctor
-    default  | table.bloom.load.threshold ................ | 1
-    default  | table.bloom.size .......................... | 1048576
-    default  | table.cache.block.enable .................. | false
-    default  | table.cache.index.enable .................. | false
-    default  | table.compaction.major.everything.at ...... | 19700101000000GMT
-    default  | table.compaction.major.everything.idle .... | 1h
-    default  | table.compaction.major.ratio .............. | 1.3
-    site     |    @override .............................. | 1.4
-    system   |    @override .............................. | 1.5
-    table    |    @override .............................. | 1.6
-    default  | table.compaction.minor.idle ............... | 5m
-    default  | table.compaction.minor.logs.threshold ..... | 3
-    default  | table.failures.ignore ..................... | false
-  </pre>
-  
-  <h1>Configuration Properties</h1>
-  

http://git-wip-us.apache.org/repos/asf/accumulo/blob/40299f89/core/src/test/java/org/apache/accumulo/core/conf/PropertyTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/accumulo/core/conf/PropertyTest.java b/core/src/test/java/org/apache/accumulo/core/conf/PropertyTest.java
index 600caab..d9a747b 100644
--- a/core/src/test/java/org/apache/accumulo/core/conf/PropertyTest.java
+++ b/core/src/test/java/org/apache/accumulo/core/conf/PropertyTest.java
@@ -18,6 +18,7 @@ package org.apache.accumulo.core.conf;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 
 import java.io.File;
@@ -39,16 +40,16 @@ public class PropertyTest {
     for (Property prop : Property.values())
       if (prop.getType().equals(PropertyType.PREFIX))
         validPrefixes.add(prop.getKey());
-    
+
     HashSet<String> propertyNames = new HashSet<String>();
     for (Property prop : Property.values()) {
       // make sure properties default values match their type
       assertTrue("Property " + prop + " has invalid default value " + prop.getDefaultValue() + " for type " + prop.getType(),
           prop.getType().isValidFormat(prop.getDefaultValue()));
-      
+
       // make sure property has a description
       assertFalse("Description not set for " + prop, prop.getDescription() == null || prop.getDescription().isEmpty());
-      
+
       // make sure property starts with valid prefix
       boolean containsValidPrefix = false;
       for (String pre : validPrefixes)
@@ -57,14 +58,14 @@ public class PropertyTest {
           break;
         }
       assertTrue("Invalid prefix on prop " + prop, containsValidPrefix);
-      
+
       // make sure properties aren't duplicate
       assertFalse("Duplicate property name " + prop.getKey(), propertyNames.contains(prop.getKey()));
       propertyNames.add(prop.getKey());
-      
+
     }
   }
-  
+
   @Test
   public void testPorts() {
     HashSet<Integer> usedPorts = new HashSet<Integer>();
@@ -76,29 +77,29 @@ public class PropertyTest {
         assertTrue("Port out of range of valid ports: " + port, port > 1023 && port < 65536);
       }
   }
-  
+
   private void typeCheckValidFormat(PropertyType type, String... args) {
     for (String s : args)
       assertTrue(s + " should be valid", type.isValidFormat(s));
   }
-  
+
   private void typeCheckInvalidFormat(PropertyType type, String... args) {
     for (String s : args)
       assertFalse(s + " should be invalid", type.isValidFormat(s));
   }
-  
+
   @Test
   public void testTypes() {
     typeCheckValidFormat(PropertyType.TIMEDURATION, "600", "30s", "45m", "30000ms", "3d", "1h");
     typeCheckInvalidFormat(PropertyType.TIMEDURATION, "1w", "1h30m", "1s 200ms", "ms", "", "a");
-    
+
     typeCheckValidFormat(PropertyType.MEMORY, "1024", "20B", "100K", "1500M", "2G");
     typeCheckInvalidFormat(PropertyType.MEMORY, "1M500K", "1M 2K", "1MB", "1.5G", "1,024K", "", "a");
-    
+
     typeCheckValidFormat(PropertyType.HOSTLIST, "localhost", "server1,server2,server3", "server1:1111,server2:3333", "localhost:1111", "server2:1111",
         "www.server", "www.server:1111", "www.server.com", "www.server.com:111");
     typeCheckInvalidFormat(PropertyType.HOSTLIST, ":111", "local host");
-    
+
     typeCheckValidFormat(PropertyType.ABSOLUTEPATH, "/foo", "/foo/c", "/");
     // in hadoop 2.0 Path only normalizes Windows paths properly when run on a Windows system
     // this makes the following checks fail
@@ -106,7 +107,7 @@ public class PropertyTest {
       typeCheckValidFormat(PropertyType.ABSOLUTEPATH, "d:\\foo12", "c:\\foo\\g", "c:\\foo\\c", "c:\\");
     typeCheckInvalidFormat(PropertyType.ABSOLUTEPATH, "foo12", "foo/g", "foo\\c");
   }
-  
+
   @Test
   public void testRawDefaultValues() {
     AccumuloConfiguration conf = AccumuloConfiguration.getDefaultConfiguration();
@@ -114,30 +115,30 @@ public class PropertyTest {
     assertEquals(new File(System.getProperty("java.io.tmpdir"), "accumulo-vfs-cache-" + System.getProperty("user.name")).getAbsolutePath(),
         conf.get(Property.VFS_CLASSLOADER_CACHE_DIR));
   }
-  
+
   @Test
   public void testSensitiveKeys() {
     final TreeMap<String,String> extras = new TreeMap<String,String>();
     extras.put("trace.token.property.blah", "something");
-    
+
     AccumuloConfiguration conf = new DefaultConfiguration() {
       @Override
       public Iterator<Entry<String,String>> iterator() {
         final Iterator<Entry<String,String>> parent = super.iterator();
         final Iterator<Entry<String,String>> mine = extras.entrySet().iterator();
-        
+
         return new Iterator<Entry<String,String>>() {
-          
+
           @Override
           public boolean hasNext() {
             return parent.hasNext() || mine.hasNext();
           }
-          
+
           @Override
           public Entry<String,String> next() {
             return parent.hasNext() ? parent.next() : mine.next();
           }
-          
+
           @Override
           public void remove() {
             throw new UnsupportedOperationException();
@@ -160,4 +161,14 @@ public class PropertyTest {
     }
     assertEquals(expected, actual);
   }
+
+  @Test
+  public void validatePropertyKeys() {
+    for (Property prop : Property.values()) {
+      if (prop.getType().equals(PropertyType.PREFIX)) {
+        assertTrue(prop.getKey().endsWith("."));
+        assertNull(prop.getDefaultValue());
+      }
+    }
+  }
 }

http://git-wip-us.apache.org/repos/asf/accumulo/blob/40299f89/docs/pom.xml
----------------------------------------------------------------------
diff --git a/docs/pom.xml b/docs/pom.xml
index 0b7a602..32ba317 100644
--- a/docs/pom.xml
+++ b/docs/pom.xml
@@ -29,10 +29,51 @@
   <profiles>
     <profile>
       <id>docs</id>
+      <dependencies>
+        <dependency>
+          <groupId>org.apache.accumulo</groupId>
+          <artifactId>accumulo-core</artifactId>
+        </dependency>
+      </dependencies>
       <build>
         <plugins>
           <plugin>
             <groupId>org.codehaus.mojo</groupId>
+            <artifactId>exec-maven-plugin</artifactId>
+            <executions>
+              <execution>
+                <id>prep-output-dir</id>
+                <goals>
+                  <goal>exec</goal>
+                </goals>
+                <phase>compile</phase>
+                <configuration>
+                  <executable>mkdir</executable>
+                  <arguments>
+                    <argument>-p</argument>
+                    <argument>${project.build.directory}/latex/accumulo_user_manual/appendices</argument>
+                  </arguments>
+                </configuration>
+              </execution>
+              <execution>
+                <id>config-appendix</id>
+                <goals>
+                  <goal>java</goal>
+                </goals>
+                <phase>compile</phase>
+                <configuration>
+                  <mainClass>org.apache.accumulo.core.conf.DefaultConfiguration</mainClass>
+                  <classpathScope>compile</classpathScope>
+                  <arguments>
+                    <argument>--generate-latex</argument>
+                    <argument>${project.build.directory}/latex/accumulo_user_manual/appendices/config.tex</argument>
+                  </arguments>
+                </configuration>
+              </execution>
+            </executions>
+          </plugin>
+          <plugin>
+            <groupId>org.codehaus.mojo</groupId>
             <artifactId>latex-maven-plugin</artifactId>
             <executions>
               <execution>